Andy 3 jaren geleden
bovenliggende
commit
65a587eee1

+ 194 - 98
src/components/keyboard/index.vue

@@ -1,120 +1,216 @@
 <template>
-    <div class="keyboard">
-        <div class="key-title">
-            请输入公式  <span>(请在软键盘内完成操作)</span>
+  <div class="keyboard">
+    <div class="key-title">请输入公式 <span>(请在软键盘内完成操作)</span></div>
+    <div class="key-setup">
+      <div class="show">{{ result.join("") }}</div>
+      <div class="key-box">
+        <div class="left-key" @click="clickItem">
+          <div
+            :data-key="item"
+            :class="[
+              'left-key-items',
+              index == 0 || index == key_list_left.length - 2
+                ? 'left-key-long'
+                : '',
+            ]"
+            v-for="(item, index) of key_list_left"
+            :key="index"
+          >
+            {{ item }}
+          </div>
         </div>
-        <div class="key-setup">
-            <div class="show">{{result.join('')}}</div>
-            <div class="key-box" >
-                <div class="left-key" @click="clickItem">
-                    <div :data-key='item' :class="['left-key-items',index == 0 || index == (key_list_left.length-2) ? 'left-key-long' : '']" v-for="(item,index) of key_list_left" :key="index">{{item}}</div>
-                </div>
-                <div class="right-key" @click="clickItem">
-                    <div class="right-key-row" v-for="(item,index) of key_list_right" :key='index'>
-                        
-                        <div :data-key='_item.e_title' class="right-item" v-for="(_item,_index) of item" :key="_index">{{_item.e_title+'('+_item.title+')'}}</div>
-                    </div>
-                </div>
+        <div class="right-key" @click="clickItem">
+          <div
+            class="right-key-row"
+            v-for="(item, index) of key_list_right"
+            :key="index"
+          >
+            <div
+              :data-key="_item.e_title"
+              class="right-item"
+              v-for="(_item, _index) of item"
+              :key="_index"
+            >
+              {{ _item.e_title + "(" + _item.title + ")" }}
             </div>
+          </div>
         </div>
+      </div>
+    </div>
 
-        <div class="key-footer">
-            <Button @click="cancel" style="margin-right:20px;">取消</Button>
-            <Button @click="success" type='primary'>确认</Button>
-        </div>
-
-        
+    <div class="key-footer">
+      <Button @click="cancel" style="margin-right:20px;">取消</Button>
+      <Button @click="success" type="primary">确认</Button>
     </div>
+  </div>
 </template>
 
 <script>
 export default {
-    props:{
-        rightData:Array,
-        default:null
+  props: {
+    rightData: {
+      type: Array,
+      default: null,
     },
-    data(){
-        return {
-            key_list_left:[
-                'C','7','8','9','(',')','4','5','6','+','*','1','2','3','-','/','0','.'
-            ],
-            key_list_right:[
-                // 'L','L1','L2',
-            ],
-            result:[],
-            revoke_str:'',
-        }
+    showValue: {
+      type: String,
+      default: () => "",
     },
-    watch:{
-        rightData(e){
-            let result = []
-            e.map(v=>result.push(v))
-            this.key_list_right = result;
-            this.key_list_right =  this.spliceGroup(this.key_list_right,4)
-            this.$forceUpdate()
-        }
+  },
+  data() {
+    return {
+      key_list_left: [
+        "C",
+        "7",
+        "8",
+        "9",
+        "(",
+        ")",
+        "4",
+        "5",
+        "6",
+        "+",
+        "*",
+        "1",
+        "2",
+        "3",
+        "-",
+        "/",
+        "0",
+        ".",
+      ],
+      key_list_right: [
+        // 'L','L1','L2',
+      ],
+      result: this.showValue.split(""),
+      revoke_str: "",
+    };
+  },
+  watch: {
+    rightData(e) {
+      let result = [];
+      e.map((v) => result.push(v));
+      this.key_list_right = result;
+      this.key_list_right = this.spliceGroup(this.key_list_right, 4);
+      this.$forceUpdate();
     },
-    computed:{
+    showValue() {
+      this.result = this.showValue.split("");
     },
-    created(){},
-    mounted(){
-        this.key_list_right =  this.spliceGroup(this.key_list_right,4)
+  },
+  computed: {},
+  created() {},
+  mounted() {
+    this.key_list_right = this.spliceGroup(this.key_list_right, 4);
+  },
+  methods: {
+    spliceGroup(arr, n) {
+      let index = 0;
+      let new_arr = [];
+      while (index < arr.length) {
+        new_arr.push(arr.splice(index, n));
+      }
+      return new_arr;
     },
-    methods:{
-        spliceGroup(arr,n){
-            let index = 0
-            let new_arr = []
-            while (index<arr.length){
-                new_arr.push(arr.splice(index,n))
-            }
-            return new_arr
-        },
-        clickItem(e){
-            let key_code = e.target.dataset.key//此处用到了事件委托,当点击到中间的缝隙时直接跳出函数
-            if(key_code == 'C'){
-                this.result.pop()
-            }else{
-                this.result.push(key_code)
-            }
-            
-            this.$emit('click',this.result)
-        },
-        success(){
-            this.$emit('success',this.result.join(''))
-            this.result = [];
-        },
-        cancel(){
-            this.$emit('cancel','')
-            this.result = [];
-        }
-    }
-}
+    clickItem(e) {
+      let key_code = e.target.dataset.key; //此处用到了事件委托,当点击到中间的缝隙时直接跳出函数
+      if (key_code == "C") {
+        this.result.pop();
+      } else {
+        this.result.push(key_code);
+      }
+
+      this.$emit("click", this.result);
+    },
+    success() {
+      this.$emit("success", this.result.join(""));
+      this.result = [];
+    },
+    cancel() {
+      this.$emit("cancel", "");
+      this.result = [];
+    },
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-.keyboard{
-    .key-title{font-size: 22px;color:#333333;span{font-size:16px;color:#666666;}padding:20px 0;}
-    .key-setup{padding:32px 76px;background:#D3D5DD;}
-    .key-box{display: flex;
-        .left-key{display: flex;width:670px;flex-wrap:wrap;
-             .left-key-items{width:124px;height:80px;display: flex;justify-content: center;align-items: center;background:#fff;margin-right:10px;margin-top:10px;
-                font-size:26px;color:#333;border-radius:5px;cursor: pointer;
-             }
-             .left-key-long{width:258px;}
+.keyboard {
+  .key-title {
+    font-size: 22px;
+    color: #333333;
+    span {
+      font-size: 16px;
+      color: #666666;
+    }
+    padding: 20px 0;
+  }
+  .key-setup {
+    padding: 32px 76px;
+    background: #d3d5dd;
+  }
+  .key-box {
+    display: flex;
+    .left-key {
+      display: flex;
+      width: 670px;
+      flex-wrap: wrap;
+      .left-key-items {
+        width: 124px;
+        height: 80px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        background: #fff;
+        margin-right: 10px;
+        margin-top: 10px;
+        font-size: 26px;
+        color: #333;
+        border-radius: 5px;
+        cursor: pointer;
+      }
+      .left-key-long {
+        width: 258px;
+      }
+    }
+    .right-key {
+      display: flex;
+      .right-key-row {
+        .right-item {
+          width: 124px;
+          height: 80px;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          margin-right: 10px;
+          margin-top: 10px;
+          background: #f48b01;
+          color: #fff;
+          border-radius: 5px;
+          cursor: pointer;
         }
-        .right-key{display: flex;
-            .right-key-row{
-                .right-item{width:124px;height:80px;display: flex;justify-content: center;align-items: center;
-                    margin-right:10px;margin-top:10px;background: #F48B01;color:#fff;border-radius: 5px;
-                    cursor: pointer;
-                }
-                &:last-child{
-                    .right-item{margin-right:0;}
-                }
-            }
+        &:last-child {
+          .right-item {
+            margin-right: 0;
+          }
         }
+      }
     }
-    .show{height:84px;background: #fff;border-radius: 5px;display: flex;justify-content: center;align-items: center;font-size:32px;color:#333333;}
+  }
+  .show {
+    height: 84px;
+    background: #fff;
+    border-radius: 5px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 32px;
+    color: #333333;
+  }
+}
+.key-footer {
+  display: flex;
+  justify-content: flex-end;
+  padding-top: 20px;
 }
-.key-footer{display: flex;justify-content:flex-end;padding-top:20px;}
-</style>
+</style>

+ 41 - 0
src/components/product/add/index.js

@@ -0,0 +1,41 @@
+import Vue from 'vue'
+import AddProduct from './index.vue'
+import store from '../../../store/index';
+const ReferenceCollner = Vue.extend(AddProduct)
+
+const Content = ({ custom_id, route_id_at_copy, then, cancel }) => {
+    const instance = new ReferenceCollner({
+        data: {
+            custom_id,
+            route_id_at_copy,
+        }
+    })
+    instance.vm = instance.$mount()
+    instance.vm.showAddProduct = true
+    instance.dom = instance.vm.$el
+    instance.$store = store
+    document.body.appendChild(instance.vm.$el) // 将dom插入body
+    instance.vm.$on('then', () => {
+        if (typeof then === 'function') {
+            then(instance.addProductArray || {})
+        }
+        instance.showAddProduct = false
+        instance.dom.remove();
+        instance.vm.$destroy()
+
+    })
+    instance.vm.$on('cancel', () => {
+        if (typeof cancel === 'function') {
+            cancel(instance)
+        }
+        instance.showAddProduct = false
+        instance.dom.remove();
+        instance.vm.$destroy()
+    })
+    return instance.vm
+}
+export default {
+    install: Vue => {
+        Vue.prototype.$addProduct = Content // 组件暴露出去,并挂载在Vue的prototype上
+    }
+}

+ 1524 - 0
src/components/product/add/index.vue

@@ -0,0 +1,1524 @@
+<template>
+  <div>
+    <Modal
+      :width="1400"
+      class-name="vertical-center-modal"
+      title="新增产品"
+      :mask-closable="false"
+      v-model="showAddProduct"
+    >
+      <div style="max-height: 800px; overflow: hidden; overflow-y: auto">
+        <Tabs v-model="currentTabIndex" ref="tabsRef">
+          <Button
+            @click="handleAddProductCopy"
+            size="small"
+            type="primary"
+            style="margin-right: 5px"
+            slot="extra"
+            >复制产品</Button
+          >
+          <Button
+            @click="handleAddProductAdd"
+            size="small"
+            type="warning"
+            style="margin-right: 5px"
+            slot="extra"
+            >添加</Button
+          >
+          <Button
+            @click="handleAddProductDele"
+            size="small"
+            type="primary"
+            slot="extra"
+            >删除</Button
+          >
+          <TabPane
+            :label="
+              (item.position ? item.position : '位置') + '-' + item.type_name
+            "
+            v-for="(item, index) in addProductArray"
+            :key="item.id"
+            :name="item.index + ''"
+          >
+            <div class="modal_product_info">
+              <div class="modal_product_info_title">产品信息</div>
+              <div class="modal_product_info_content modal_product">
+                <Form :model="item" :label-width="100">
+                  <FormItem label="选择产品:">
+                    <Tooltip style="width: 120px" transfer>
+                      <span slot="content">
+                        <span
+                          v-for="_item in productList"
+                          :key="_item.id"
+                          v-show="_item.id == item.product_id"
+                          >{{ _item.title }}</span
+                        >
+                      </span>
+                      <Select
+                        filterable
+                        clearable
+                        filter-by-label
+                        transfer
+                        label-in-value
+                        size="small"
+                        v-model="item.product_id"
+                        @on-change="handleAddProductSelect($event, index)"
+                        style="width: 120px"
+                      >
+                        <Option
+                          v-for="item of productList"
+                          :tag="item.img_url"
+                          :key="item.id"
+                          :label="item.title"
+                          :value="item.id"
+                        ></Option>
+                      </Select>
+                    </Tooltip>
+                  </FormItem>
+                  <FormItem label="位置:">
+                    <Tooltip style="width: 120px" transfer>
+                      <span slot="content">
+                        {{ item.position }}
+                      </span>
+                      <Input
+                        size="small"
+                        v-model="item.position"
+                        style="width: 120px"
+                        placeholder="请输入位置"
+                      />
+                    </Tooltip>
+                  </FormItem>
+                  <FormItem label="计量单位:">
+                    <Input
+                      size="small"
+                      disabled
+                      style="width: 120px"
+                      v-model="item.unit"
+                      placeholder="自动带出"
+                    />
+                  </FormItem>
+                  <!-- 工艺属性 -->
+                  <FormItem
+                    v-for="(ele, idx) in item.process"
+                    :key="ele.key + '' + item.id"
+                    :label="ele.title + ':'"
+                  >
+                    <Tooltip style="width: 120px" transfer>
+                      <span slot="content">
+                        <span
+                          v-for="_item in ele.processList"
+                          :key="_item.id"
+                          v-show="_item.id == ele.value"
+                          >{{ _item.title }}</span
+                        >
+                      </span>
+                      <Select
+                        style="width: 120px"
+                        filterable
+                        clearable
+                        filter-by-label
+                        transfer
+                        label-in-value
+                        @on-open-change="
+                          (e) => handleGetProductMeasure(e, idx, item, ele)
+                        "
+                        @on-change="
+                          (e) => handleProductProcessChange(e, idx, item, ele)
+                        "
+                        v-model="ele.value"
+                        size="small"
+                      >
+                        <Option
+                          v-for="option of ele.processList"
+                          :key="option.id"
+                          :disabled="option.isDisabled"
+                          :label="option.title"
+                          :value="option.id"
+                        ></Option>
+                      </Select>
+                    </Tooltip>
+                  </FormItem>
+                  <!-- 测量字段 -->
+                  <FormItem
+                    v-for="ele in item.measure"
+                    :key="ele.id"
+                    :label="ele.title + ':'"
+                  >
+                    <Input
+                      size="small"
+                      type="text"
+                      clearable
+                      :placeholder="ele.e_title"
+                      v-model="ele.value"
+                      @on-change="
+                        (e) => handleProductMeasureChange(e, item, ele)
+                      "
+                      @on-blur="(e) => handleProductMeasureBlur(e, item, ele)"
+                      style="width: 120px"
+                    />
+                  </FormItem>
+                  <FormItem label="数量:">
+                    <Input
+                      size="small"
+                      @on-change="(e) => handleProductNumChange(e, item)"
+                      v-model="item.total_num"
+                      style="width: 120px"
+                      placeholder="请输入产品数量"
+                    />
+                  </FormItem>
+                  <FormItem label="核算数量:">
+                    <Input
+                      size="small"
+                      v-model="item.num"
+                      disabled
+                      style="width: 120px"
+                      placeholder="自动带出"
+                    />
+                  </FormItem>
+                  <FormItem label="单价:">
+                    <Input
+                      size="small"
+                      v-model="item.unit_price"
+                      @on-change="(e) => handleProductUnit_priceChange(e, item)"
+                      style="width: 120px"
+                      placeholder="自动带出"
+                    />
+                  </FormItem>
+                  <FormItem label="附加金额:">
+                    <Input
+                      size="small"
+                      v-model="item.ext_price"
+                      @on-change="(e) => handleProductExt_priceChange(e, item)"
+                      style="width: 120px"
+                      placeholder="自动带出"
+                    />
+                  </FormItem>
+                  <FormItem label="超标金额:">
+                    <Input
+                      size="small"
+                      @on-change="(e) => handleProductOver_priceChange(e, item)"
+                      v-model="item.over_price"
+                      style="width: 120px"
+                      placeholder="自动带出"
+                    />
+                  </FormItem>
+                  <FormItem label="金额:">
+                    <Input
+                      size="small"
+                      v-model="item.price"
+                      style="width: 120px"
+                      placeholder="自动带出"
+                    />
+                  </FormItem>
+                  <FormItem label="图号:">
+                    <Input
+                      size="small"
+                      v-model="item.url_number"
+                      style="width: 120px"
+                      placeholder="自动带出"
+                    />
+                  </FormItem>
+                  <FormItem
+                    v-for="(_customize, customize_key) in item.customize"
+                    :label="_customize.style + ':'"
+                    :key="customize_key + 99"
+                  >
+                    <Input
+                      v-show="_customize.type == 1"
+                      size="small"
+                      type="text"
+                      v-model="_customize.value"
+                      style="width: 120px"
+                      placeholder="请输入"
+                    />
+
+                    <Select
+                      v-show="_customize.type == 2"
+                      style="width: 120px"
+                      filterable
+                      clearable
+                      v-model="_customize.value"
+                      size="small"
+                    >
+                      <Option
+                        v-for="option of _customize.explain"
+                        :key="option.value"
+                        :label="option.value"
+                        :value="option.value"
+                      ></Option>
+                    </Select>
+                  </FormItem>
+                  <FormItem
+                    v-for="(outh, outh_key) in item.outh"
+                    :label="outh.title"
+                    :key="outh_key + 21"
+                  >
+                    <img
+                      v-if="outh.key == 'img' || outh.key == 'url'"
+                      @click="showPreview(item, outh.key)"
+                      style="
+                        max-width: 30px;
+                        max-height: 30px;
+                        top: 5px;
+                        position: relative;
+                        cursor: pointer;
+                      "
+                      :src="$store.state.ip + outh.value"
+                    />
+                    <Input
+                      v-if="
+                        outh.key != 'img' &&
+                          outh.key != 'url' &&
+                          outh.key != 'lock'
+                      "
+                      disabled
+                      placeholder="自动生成"
+                      style="width: 120px"
+                      size="small"
+                      v-model="outh.value"
+                    />
+                    <Select
+                      label-in-value
+                      @on-change="changeLock($event, item, index)"
+                      size="small"
+                      clearable
+                      style="width: 120px"
+                      v-if="outh.key == 'lock'"
+                      v-model="item[outh.key]"
+                    >
+                      <Option
+                        v-for="luck of lock_list"
+                        :key="luck.id"
+                        :tag="luck.price"
+                        :value="luck.id"
+                        :label="luck.title"
+                      ></Option>
+                      <Option :value="0" label="无"></Option>
+                    </Select>
+                  </FormItem>
+                  <FormItem label="备注:">
+                    <Select
+                      size="small"
+                      clearable
+                      filterable
+                      allow-create
+                      @on-create="handleRemarkCreate"
+                      style="width: 120px"
+                      v-model="item.remark"
+                    >
+                      <Option
+                        v-for="_remark of support_remark"
+                        :key="_remark"
+                        :value="_remark"
+                        :label="_remark"
+                      ></Option>
+                    </Select>
+                    <!-- <Input
+                      size="small"
+                      type="textarea"
+                      v-model="item.remark"
+                      style="width: 120px"
+                      placeholder="请输入备注"
+                    /> -->
+                  </FormItem>
+                  <FormItem label="产品图:">
+                    <!-- v-show="modalData.url && modalData.url.length > 0" -->
+                    <div class="product-img">
+                      <div class="product-add">
+                        <div
+                          class="items"
+                          v-for="(item, index) of item.url"
+                          :key="index"
+                        >
+                          <img
+                            @click="looks(item)"
+                            :src="$store.state.ip + item"
+                            alt=""
+                          />
+                        </div>
+                      </div>
+                    </div>
+                  </FormItem>
+                </Form>
+              </div>
+            </div>
+            <div class="modal_product_info">
+              <div class="modal_product_info_title">部件信息</div>
+              <div class="modal_product_info_content modal_parts">
+                <Form
+                  :model="element"
+                  v-for="(element, idx) in item.part"
+                  :key="element.id + '111' + idx"
+                  :label-width="50"
+                >
+                  <FormItem
+                    :label-width="element.isBP ? 1 : 50"
+                    v-show="!element.is_metal"
+                  >
+                    <Radio
+                      v-show="element.isBP"
+                      @click.native.prevent="handleRadioClick(element)"
+                      v-model="element.isChoosed"
+                    ></Radio>
+                    <!-- <span v-show="element.isBP">{{ element.part_title }} </span> -->
+                  </FormItem>
+                  <FormItem label="部件:" v-show="!element.is_metal">
+                    <Select
+                      filterable
+                      clearable
+                      transfer
+                      label-in-value
+                      size="small"
+                      @on-change="
+                        handlePartChange(
+                          $event,
+                          element,
+                          item.measure,
+                          item.total_num
+                        )
+                      "
+                      v-model="element.change_id"
+                      style="width: 180px"
+                    >
+                      <Option
+                        v-for="item of element.change"
+                        :key="item.id"
+                        :label="item.part_title"
+                        :value="item.id"
+                      ></Option>
+                    </Select>
+                  </FormItem>
+                  <FormItem
+                    label="高:"
+                    v-show="
+                      !element.is_metal &&
+                        element.hide_measure &&
+                        !element.hide_measure.filter((v) => v == 'H').length > 0
+                    "
+                  >
+                    <Input
+                      size="small"
+                      clearable
+                      v-model="element.long"
+                      style="width: 50px"
+                      placeholder="请输入厚"
+                    />
+                  </FormItem>
+                  <FormItem
+                    label="宽:"
+                    v-show="
+                      !element.is_metal &&
+                        element.hide_measure &&
+                        !element.hide_measure.filter((v) => v == 'W').length > 0
+                    "
+                  >
+                    <Input
+                      size="small"
+                      clearable
+                      v-model="element.wide"
+                      style="width: 50px"
+                      placeholder="请输入宽"
+                    />
+                  </FormItem>
+                  <FormItem
+                    label="厚:"
+                    v-show="
+                      !element.is_metal &&
+                        element.hide_measure &&
+                        !element.hide_measure.filter((v) => v == 'T').length > 0
+                    "
+                  >
+                    <Input
+                      size="small"
+                      clearable
+                      v-model="element.high"
+                      style="width: 50px"
+                      placeholder="请输入高"
+                    />
+                  </FormItem>
+                  <FormItem
+                    v-for="(process_detail, idx) in element.process"
+                    :key="process_detail.name + '222' + element.part_id"
+                    :label="process_detail.name + ':'"
+                    v-show="
+                      !element.is_metal &&
+                        element.hide_process &&
+                        !element.hide_process.filter(
+                          (v) => v == process_detail.process_id
+                        ).length > 0
+                    "
+                  >
+                    <Tooltip style="width: 120px" transfer>
+                      <span slot="content">
+                        <span
+                          v-for="_item in process_detail.cld"
+                          :key="_item.id"
+                          v-show="_item.id == process_detail.procedure_property"
+                          >{{ _item.title }}</span
+                        >
+                      </span>
+                      <Select
+                        style="width: 120px"
+                        filterable
+                        clearable
+                        transfer
+                        label-in-value
+                        @on-change="
+                          (e) => handlePartProcessChange(e, idx, element)
+                        "
+                        v-model="process_detail.procedure_property"
+                        size="small"
+                      >
+                        <Option
+                          v-for="option of process_detail.cld"
+                          :key="option.id"
+                          :label="option.title"
+                          :value="option.id"
+                        ></Option>
+                      </Select>
+                    </Tooltip>
+                  </FormItem>
+                  <FormItem v-show="!element.is_metal">
+                    <Button
+                      @click="handlePartsApart(element, idx, item.part)"
+                      type="primary"
+                      v-if="element.isBP"
+                      style="margin-right: 5px"
+                      size="small"
+                      >拆分</Button
+                    >
+                    <Button
+                      @click="handlePartsDele(element, idx, item.part)"
+                      type="primary"
+                      v-else
+                      style="margin-right: 5px"
+                      size="small"
+                      >删除</Button
+                    >
+                    <Button
+                      @click="handlePartDetailEdit(element, idx)"
+                      type="primary"
+                      style="margin-right: 5px"
+                      size="small"
+                      >{{
+                        element.isShowPartDetail ? "收起" : "修改原材料"
+                      }}</Button
+                    >
+                  </FormItem>
+                  <div
+                    :class="[
+                      'part_detail_form',
+                      element.isShowPartDetail ? '' : 'hide_part_detail',
+                    ]"
+                    :data-index="idx"
+                  >
+                    <FormItem>
+                      <div v-for="ele in element.part_detail" :key="ele.id">
+                        <Form :model="ele">
+                          <FormItem>
+                            <div style="width: 200px">
+                              {{ ele.title || ele.part_detail_title }}
+                            </div>
+                          </FormItem>
+                          <!-- 原材料 -->
+                          <Form>
+                            <FormItem>
+                              <div style="width: 200px">
+                                {{ ele.material_detail_title || "请选择" }}
+                              </div>
+                            </FormItem>
+                            <FormItem label="高" :label-width="40">
+                              <Select
+                                style="width: 80px"
+                                filterable
+                                clearable
+                                transfer
+                                v-model="ele.material_detail_id"
+                                @on-change="(e) => handleMaterialChange(e, ele)"
+                                placeholder="请选择高"
+                                size="small"
+                              >
+                                <Option
+                                  v-for="option of ele.material_detail_list"
+                                  :key="option.material_detail_id"
+                                  :label="option.long"
+                                  :value="option.material_detail_id"
+                                ></Option>
+                              </Select>
+                            </FormItem>
+                            <FormItem label="宽" :label-width="40">
+                              <Select
+                                style="width: 80px"
+                                filterable
+                                clearable
+                                transfer
+                                v-model="ele.material_detail_id"
+                                placeholder="请选择宽"
+                                size="small"
+                              >
+                                <Option
+                                  v-for="option of ele.material_detail_list"
+                                  :key="option.material_detail_id"
+                                  :label="option.wide"
+                                  :value="option.material_detail_id"
+                                ></Option>
+                              </Select>
+                            </FormItem>
+                            <FormItem label="厚" :label-width="40">
+                              <Select
+                                style="width: 80px"
+                                filterable
+                                clearable
+                                transfer
+                                v-model="ele.material_detail_id"
+                                placeholder="请选择厚"
+                                size="small"
+                              >
+                                <Option
+                                  v-for="option of ele.material_detail_list"
+                                  :key="option.material_detail_id"
+                                  :label="option.high"
+                                  :value="option.material_detail_id"
+                                ></Option>
+                              </Select>
+                            </FormItem>
+                            <FormItem label="数量" :label-width="40">
+                              <Input
+                                size="small"
+                                v-model="ele.material_detail_num"
+                                style="width: 80px"
+                                placeholder="请输入数量"
+                              />
+                            </FormItem>
+                          </Form>
+                        </Form>
+                      </div>
+                    </FormItem>
+                  </div>
+                </Form>
+              </div>
+            </div>
+            <div class="modal_product_info">
+              <div class="modal_product_info_title">
+                附加信息
+                <Button
+                  @click="handleExtraAdd(item.metalArray, 1)"
+                  type="primary"
+                  style="margin-right: 5px"
+                  size="small"
+                  >新增五金</Button
+                >
+                <Button
+                  @click="handleExtraAdd(item.extArray, 2)"
+                  type="primary"
+                  size="small"
+                  >新增附加项目</Button
+                >
+              </div>
+              <div class="modal_product_info_content modal_extra">
+                <Form
+                  :model="element"
+                  v-for="(element, idx) in item.metalArray"
+                  :key="element.id"
+                  :label-width="80"
+                >
+                  <FormItem label="五金:">
+                    <Select
+                      filterable
+                      clearable
+                      transfer
+                      label-in-value
+                      size="small"
+                      @on-change="
+                        (e) =>
+                          handleMetalChange(e, element, idx, item.metalArray)
+                      "
+                      v-model="element.material_id"
+                      style="width: 100px"
+                    >
+                      <Option
+                        v-for="item of metalList"
+                        :key="item.id"
+                        :label="item.title"
+                        :value="item.id"
+                      ></Option>
+                    </Select>
+                  </FormItem>
+                  <FormItem label="数量:">
+                    <Input
+                      size="small"
+                      v-model="element.num"
+                      @on-change="handleTotalPriceCalc(element, item)"
+                      style="width: 100px"
+                      placeholder="请输入数量"
+                    />
+                  </FormItem>
+                  <FormItem label="单价:">
+                    <Input
+                      size="small"
+                      v-model="element.price"
+                      @on-change="handleTotalPriceCalc(element, item)"
+                      style="width: 100px"
+                      placeholder="请输入单价"
+                    />
+                  </FormItem>
+                  <FormItem label="金额:">
+                    <Input
+                      size="small"
+                      @on-change="handleTotalPriceChange(element, item)"
+                      v-model="element.total_price"
+                      style="width: 100px"
+                      placeholder="请输入金额"
+                    />
+                  </FormItem>
+                  <FormItem label="备注:">
+                    <Input
+                      size="small"
+                      v-model="element.remark"
+                      style="width: 100px"
+                      placeholder="请输入备注"
+                    />
+                  </FormItem>
+                  <FormItem>
+                    <a
+                      style="color: red"
+                      @click="
+                        handleExtraDele(item.metalArray, element, idx, item)
+                      "
+                      >删除</a
+                    >
+                  </FormItem>
+                </Form>
+                <Form
+                  :model="element"
+                  v-for="(element, idx) in item.extArray"
+                  :key="element.id"
+                  :label-width="80"
+                >
+                  <FormItem label="附加项目:">
+                    <Select
+                      filterable
+                      clearable
+                      transfer
+                      label-in-value
+                      size="small"
+                      v-model="element.id"
+                      @on-change="(e) => handleExtChange(element, e, item)"
+                      style="width: 100px"
+                    >
+                      <Option
+                        v-for="item of extList"
+                        :key="item.id"
+                        :label="item.title"
+                        :value="item.id"
+                      ></Option>
+                    </Select>
+                  </FormItem>
+                  <FormItem label="数量:">
+                    <Input
+                      size="small"
+                      v-model="element.num"
+                      @on-change="handleTotalPriceCalc(element, item)"
+                      style="width: 100px"
+                      placeholder="请输入数量"
+                    />
+                  </FormItem>
+                  <FormItem label="单价:">
+                    <Input
+                      size="small"
+                      v-model="element.price"
+                      @on-change="handleTotalPriceCalc(element, item)"
+                      style="width: 100px"
+                      placeholder="请输入单价"
+                    />
+                  </FormItem>
+                  <FormItem label="金额:">
+                    <Input
+                      size="small"
+                      @on-change="handleTotalPriceChange(element, item)"
+                      v-model="element.total_price"
+                      style="width: 100px"
+                      placeholder="请输入金额"
+                    />
+                  </FormItem>
+                  <FormItem label="备注:">
+                    <Input
+                      size="small"
+                      v-model="element.remark"
+                      style="width: 100px"
+                      placeholder="请输入备注"
+                    />
+                  </FormItem>
+                  <FormItem>
+                    <a
+                      style="color: red"
+                      @click="
+                        handleExtraDele(item.extArray, element, idx, item)
+                      "
+                      >删除</a
+                    >
+                  </FormItem>
+                </Form>
+              </div>
+            </div>
+          </TabPane>
+        </Tabs>
+      </div>
+      <div slot="footer">
+        <Button @click="cancel">取消</Button>
+        <Button @click="then" type="primary">确定</Button>
+      </div>
+    </Modal>
+  </div>
+</template>
+
+<script>
+// 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+// 例如:import 《组件名称》 from '《组件路径》';
+export default {
+  name: "",
+  components: {},
+  props: {},
+  // import引入的组件需要注入到对象中才能使用
+  data() {
+    // 这里存放数据
+    return {
+      showAddProduct: false,
+      addProductArray: [
+        {
+          type_name: "产品1",
+          num: 1,
+          position: "位置",
+          index: "0",
+          metalArray: [],
+          extArray: [],
+        },
+      ], //新增产品列表
+      pre_bp_id: "", //产品分类ID,添加多个产品时判断是否与前一个产品分类一致
+      process_match_list: [], //当前产品所有工艺组合
+      process_all_list: [], //当前产品所有工艺
+      support_remark: [], //备注列表
+      bpp_list: [], //工艺属性列表
+      //   route_id_at_copy: "", //复制产品的工艺路线ID
+      pre_process_obj: {}, //产品工艺属性,添加多个产品时判断是否与前一个工艺属性一致
+      currentTabIndex: "0", //当前分页面
+      productList: [], //产品列表
+      metalList: [], //五金列表
+      extList: [], //五金列表
+    };
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    //   获取工艺属性
+    this.axios({
+      method: "get",
+      url: "/api/bpp_list",
+    }).then((res) => {
+      if (res.code == 200) {
+        this.bpp_list = res.data;
+      }
+    });
+    // 获取产品列表
+    this.axios("/api/product").then(
+      (res) => (this.productList = res.data.data)
+    );
+    // 获取五金列表
+    this.axios
+      .get("/api/material", { params: { sub_type_id: 5 } })
+      .then((res) => {
+        if (res.code == 200) {
+          this.metalList = res.data.data;
+        }
+      });
+    // 获取附加列表
+    this.axios.get("/api/project_ext_list").then((res) => {
+      if (res.code == 200) {
+        this.extList = res.data.data;
+      }
+    });
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  methods: {
+    handleAddProductCopy() {
+      let idx = this.$refs.tabsRef.activeKey;
+      let obj = this.deepClone(this.addProductArray[idx]);
+      obj.index = this.addProductArray.length;
+      this.pre_bp_id = this.addProductArray[idx].bp_id;
+      this.addProductArray.push(obj);
+    },
+    handleAddProductDele() {
+      let idx = this.$refs.tabsRef.activeKey;
+      this.addProductArray.splice(idx, 1);
+    },
+    handleAddProductAdd() {
+      let index = this.addProductArray.length;
+      this.addProductArray.push({
+        type_name: "产品" + (this.addProductArray.length + 1),
+        position: "",
+        index,
+        extArray: [{ type: 2 }],
+        metalArray: [{ type: 1 }],
+      });
+    },
+    handleAddProductSelect(row, n) {
+      if (row) {
+        let product_id = row.value;
+        this.addProductArray[n].type_name = row.label;
+        this.addProductArray[n].title = row.label;
+        this.axios("/api/order_get_product_detail_new", {
+          params: { product_id, custom_id: this.custom_id },
+        }).then((res) => {
+          if (res.code == 200) {
+            if (this.addProductArray.length == 1) {
+              let _temp_obj = {};
+              if (res.data.process.list.length > 1) {
+                for (const key in res.data.process.list[0].detail) {
+                  res.data.process.list.reduce((pre, cur) => {
+                    if (_temp_obj[key] == "") {
+                      return pre;
+                    } else {
+                      if (pre.detail[key] == cur.detail[key]) {
+                        _temp_obj[key] = pre.detail[key];
+                        return pre;
+                      } else {
+                        _temp_obj[key] = "";
+                        return pre;
+                      }
+                    }
+                  });
+                }
+              } else {
+                _temp_obj = res.data.process.list[0].detail;
+              }
+              this.pre_process_obj = this.deepClone(_temp_obj);
+            }
+            // this.process_match_list = res.data.process.list;
+            this.process_all_list = res.data.process.title;
+            this.support_remark = res.data.support_remark;
+            let modalData = this.addProductArray[n];
+            modalData.url = res.data.url;
+            modalData.total_num = res.data.total_num || 1;
+            modalData.ext_price = res.data.ext_price || 0;
+            modalData.unit_price = res.data.price || 0;
+            modalData.num = res.data.num || 1;
+            modalData.num_temp_save = modalData.num;
+            modalData.over_price = res.data.over_price || 0;
+            modalData.position = res.data.position || "";
+            modalData.unit = res.data.unit || "";
+            modalData.remark = res.data.remark || "";
+            modalData.url_number = res.data.url_number || "";
+            modalData.overdraft = res.data.overdraft;
+            modalData.num_formula = res.data.num_formula;
+            modalData.bp_id = res.data.bp_id;
+            // 金额=(产品单价)*核算数量 +附加金额 + 超标金额
+            modalData.price =
+              (modalData.unit_price * 1 || 0) * (modalData.num * 1 || 1) +
+              (modalData.over_price * 1 || 0) +
+              (modalData.ext_price * 1 || 0);
+            modalData.price = modalData.price.toFixed(2);
+            modalData.selected_ids = [];
+            modalData.part = res.data.part;
+            modalData.part.forEach((element) => {
+              // 选择不是附加项目的,
+              if (!element.is_metal) {
+                // 选择不是线条、或者基础档案中要默认为空的部件
+                element.isBP = true;
+                element.isChoosed = true;
+                if (element.is_null == 1) {
+                  element.change_id = "";
+                } else {
+                  element.part_detail = element.sub_part;
+                  //展示非拆分部件
+                  // 默认替换部件
+                  element.change_id = element.change[0].id;
+                  //存计算公式
+                  element.long ? "" : (element.long = 0);
+                  element.wide ? "" : (element.wide = 0);
+                  element.high ? "" : (element.high = 0);
+                  element.longCalc = element.long;
+                  element.wideCalc = element.wide;
+                  element.highCalc = element.high;
+                  element.part_detail.forEach((elem) => {
+                    elem.org_num = elem.num;
+                    elem.material_detail_id = 0;
+                    elem.material_detail_title =
+                      elem.material_detail_list[0].title;
+                    elem.material_detail_id =
+                      elem.material_detail_list[0].material_detail_id;
+                    elem.material_detail_num = elem.num || 0;
+                    elem.material_detail_org_num = elem.num || 0;
+                    elem.long ? "" : (elem.long = 0);
+                    elem.wide ? "" : (elem.wide = 0);
+                    elem.high ? "" : (elem.high = 0);
+                    elem.longCalc = elem.long || "";
+                    elem.wideCalc = elem.wide || "";
+                    elem.highCalc = elem.high || "";
+                    elem.material_detail_list.forEach((el) => {
+                      el.long = el.long || "0";
+                      el.wide = el.wide || "0";
+                      el.high = el.high || "0";
+                    });
+                  });
+                }
+              }
+            });
+            //测量字段
+            modalData.measure = res.data.measure;
+            modalData.measure.forEach((element) => {
+              element.value = "";
+              element.measureCalc = element.e_title;
+            });
+            //工艺属性
+            this.bpp_list.map((element) => {
+              for (const key in res.data.process.title) {
+                const ele = res.data.process.title[key];
+                if (element.name == ele) {
+                  if (this.route_id_at_copy) {
+                    const compare_copy = res.data.process.list.filter(
+                      (item) => item.id == this.route_id_at_copy
+                    );
+                    if (compare_copy && compare_copy.length > 0) {
+                      if (!modalData.procedure_properties) {
+                        modalData.procedure_properties = [];
+                      }
+                      modalData.procedure_properties[
+                        modalData.process.lenngth
+                      ] = compare_copy[0].detail[key] * 1;
+                      modalData.process.push({
+                        key: key,
+                        title: ele,
+                        value: compare_copy[0].detail[key] * 1,
+                        processList: element.cld,
+                      });
+                    } else {
+                      modalData.process.push({
+                        key: key,
+                        title: ele,
+                        value: "",
+                        processList: element.cld,
+                      });
+                    }
+                  } else {
+                    const compare = res.data.process.list.filter(
+                      (item) => item.detail[key] == this.pre_process_obj[key]
+                    );
+                    if (compare.length > 0) {
+                      modalData.procedure_properties = [];
+                      modalData.procedure_properties.push(
+                        this.pre_process_obj[key] * 1
+                      );
+                      modalData.process.push({
+                        key: key,
+                        title: ele,
+                        value: this.pre_process_obj[key] * 1,
+                        processList: element.cld,
+                      });
+                    } else {
+                      modalData.procedure_properties = [];
+                      modalData.procedure_properties.push("");
+                      modalData.process.push({
+                        key: key,
+                        title: ele,
+                        value: "",
+                        processList: element.cld,
+                      });
+                    }
+                  }
+                }
+              }
+            });
+            modalData.part.forEach((element) => {
+              if (!element.is_metal) {
+                //赋值默认工艺属性
+                element.process = this.deepClone(this.bpp_list);
+                element.process.forEach((elem, index) => {
+                  for (const key in res.data.process.title) {
+                    const ele = res.data.process.title[key];
+                    if (elem.name == ele) {
+                      elem.procedure_property = this.pre_process_obj[key] * 1;
+                      elem.process_id = key;
+                      if (!element.procedure_properties) {
+                        element.procedure_properties = [];
+                      }
+                      element.procedure_properties[index] =
+                        this.pre_process_obj[key] * 1;
+                    }
+                  }
+                });
+              }
+            });
+          }
+        });
+      }
+    },
+    handleExtraAdd(array, type) {
+      array.push({
+        num: 0,
+        price: 0,
+        total_price: 0,
+        type,
+        remark: "",
+        title: "",
+        is_metal: true,
+      });
+      this.$forceUpdate();
+    },
+    handleRemarkCreate(val) {
+      this.support_remark.push(val);
+    },
+    handleProductMeasureChange(e, product, measure_detail) {
+      if (e.target.value) {
+        let cur_measure = measure_detail.measureCalc;
+        let cur_value = measure_detail.value;
+        product.over_price = 0;
+        //当前测量字段 L W H  修改部件测量字段
+        product.part.forEach((element) => {
+          if (!element.is_metal) {
+            if (!element.is_null == 1) {
+              //处理公式
+              if (element.highCalc.indexOf(cur_measure) != -1) {
+                element.high = element.highCalc.replace(
+                  new RegExp(cur_measure, "g"),
+                  cur_value || ""
+                );
+              }
+              if (element.longCalc.indexOf(cur_measure) != -1) {
+                element.long = element.longCalc.replace(
+                  new RegExp(cur_measure, "g"),
+                  cur_value || ""
+                );
+              }
+              if (element.wideCalc.indexOf(cur_measure) != -1) {
+                element.wide = element.wideCalc.replace(
+                  new RegExp(cur_measure, "g"),
+                  cur_value || ""
+                );
+              }
+              //判断测量字段公式中是否还含有字母
+              let flag_high = false;
+              let flag_long = false;
+              let flag_wide = false;
+              for (let index = 0; index < product.measure.length; index++) {
+                const item = product.measure[index];
+                if (element.high.indexOf(item.measureCalc) != -1) {
+                  flag_high = true;
+                }
+                if (element.long.indexOf(item.measureCalc) != -1) {
+                  flag_long = true;
+                }
+                if (element.wide.indexOf(item.measureCalc) != -1) {
+                  flag_wide = true;
+                }
+              }
+              if (flag_high) {
+              } else {
+                element.high = eval(element.high);
+                element.high += "";
+              }
+              if (flag_long) {
+              } else {
+                element.long = eval(element.long);
+                element.long += "";
+              }
+              if (flag_wide) {
+              } else {
+                element.wide = eval(element.wide);
+                element.wide += "";
+              }
+              element.part_detail.forEach((elem) => {
+                if (!elem.high) {
+                } else if (elem.highCalc.indexOf(cur_measure) != -1) {
+                  elem.high = elem.highCalc.replace(
+                    new RegExp(cur_measure, "g"),
+                    cur_value || ""
+                  );
+                }
+                if (!elem.long) {
+                } else if (elem.longCalc.indexOf(cur_measure) != -1) {
+                  elem.long = elem.longCalc.replace(
+                    new RegExp(cur_measure, "g"),
+                    cur_value || ""
+                  );
+                }
+                if (!elem.wide) {
+                } else if (elem.wideCalc.indexOf(cur_measure) != -1) {
+                  elem.wide = elem.wideCalc.replace(
+                    new RegExp(cur_measure, "g"),
+                    cur_value || ""
+                  );
+                }
+                //判断测量字段公式中是否还含有字母
+                let _flag_high = false;
+                let _flag_long = false;
+                let _flag_wide = false;
+                // Number类型无法使用indexOf
+                elem.high += "";
+                elem.long += "";
+                elem.wide += "";
+                for (let index = 0; index < product.measure.length; index++) {
+                  const item = product.measure[index];
+                  if (!elem.high) {
+                  } else if (elem.high.indexOf(item.measureCalc) != -1) {
+                    _flag_high = true;
+                  }
+                  if (!elem.long) {
+                  } else if (elem.long.indexOf(item.measureCalc) != -1) {
+                    _flag_long = true;
+                  }
+                  if (!elem.wide) {
+                  } else if (elem.wide.indexOf(item.measureCalc) != -1) {
+                    _flag_wide = true;
+                  }
+                }
+                if (_flag_high) {
+                } else {
+                  elem.high = eval(elem.high);
+                  elem.high += "";
+                  elem.high == "null" && (elem.high = 0);
+                }
+                if (_flag_long) {
+                } else {
+                  elem.long = eval(elem.long);
+                  elem.long += "";
+                  elem.long == "null" && (elem.long = 0);
+                }
+                if (_flag_wide) {
+                } else {
+                  elem.wide = eval(elem.wide);
+                  elem.wide += "";
+                  elem.wide == "null" && (elem.wide = 0);
+                }
+              });
+            }
+          }
+        });
+        product.part.map((item) => {
+          const cur_part = product.overdraft.filter(
+            (v) => v.part_id == item.part_id
+          );
+          cur_part.length > 0 &&
+            cur_part.map((element) => {
+              // 1 高 2 宽 3 厚
+              if (
+                element.type == 1 &&
+                item.long > element.min &&
+                item.long < element.max
+              ) {
+                item.formula_temp = element.formula;
+                item.formula_temp = item.formula_temp.replace(/H/g, item.long);
+                item.formula_temp = item.formula_temp.replace(/W/g, item.wide);
+                item.formula_temp = item.formula_temp.replace(/T/g, item.high);
+                item.formula_value = eval(item.formula_temp);
+                product.over_price += item.formula_value * 1 || 0;
+                product.over_price = product.over_price.toFixed(2);
+              }
+              if (
+                element.type == 2 &&
+                item.wide > element.min &&
+                item.wide < element.max
+              ) {
+                item.formula_temp = element.formula;
+                item.formula_temp = item.formula_temp.replace(/H/g, item.long);
+                item.formula_temp = item.formula_temp.replace(/W/g, item.wide);
+                item.formula_temp = item.formula_temp.replace(/T/g, item.high);
+                item.formula_value = eval(item.formula_temp);
+                product.over_price += item.formula_value * 1 || 0;
+                product.over_price = product.over_price.toFixed(2);
+              }
+              if (
+                element.type == 3 &&
+                item.high > element.min &&
+                item.high < element.max
+              ) {
+                item.formula_temp = element.formula;
+                item.formula_temp = item.formula_temp.replace(/H/g, item.long);
+                item.formula_temp = item.formula_temp.replace(/W/g, item.wide);
+                item.formula_temp = item.formula_temp.replace(/T/g, item.high);
+                item.formula_value = eval(item.formula_temp);
+                product.over_price += item.formula_value * 1 || 0;
+                product.over_price = product.over_price.toFixed(2);
+              }
+            });
+        });
+        //修改核算数量
+        // 如果没有核算数量公式,核算数量取产品数量
+        if (product.num_formula == "") {
+          product.total_num = product.num;
+        } else {
+          product.num_formula_temp = product.num_formula;
+          product.measure.forEach((element) => {
+            if (product.num_formula.indexOf(element.e_title) != -1) {
+              product.num_formula_temp = product.num_formula_temp.replace(
+                new RegExp(element.e_title, "g"),
+                element.value || 0
+              );
+            }
+          });
+          product.num = eval(product.num_formula_temp);
+          product.num = product.num.toFixed(2);
+          product.over_price = product.over_price.toFixed(2);
+          product.num_temp_save = product.num;
+          product.price =
+            (product.unit_price * 1 || 0) * (product.num * 1 || 1) +
+            (product.over_price * 1 || 0) +
+            (product.ext_price * 1 || 0);
+          product.price = product.price.toFixed(2);
+        }
+        this.$forceUpdate();
+      }
+    },
+    handleProductMeasureBlur(e, product, measure_detail) {
+      try {
+        measure_detail.value = eval(e.target.value);
+      } catch (error) {
+        console.log("error :>> ", error);
+      }
+      product.part.map((part) => {
+        part.part_detail &&
+          part.part_detail.length > 0 &&
+          part.part_detail.map((part_detail) => {
+            part_detail._longCalc = this.handleCalcPartDetailLong(
+              part_detail,
+              product
+            );
+            if (part_detail.material_detail_list.length > 1) {
+              try {
+                part_detail.longCalcFinal = eval(part_detail._longCalc);
+                part_detail.material_detail_id = this.handleFindNearest(
+                  part_detail.material_detail_list,
+                  part_detail.longCalcFinal
+                );
+              } catch (error) {
+                console.log("error :>> ", error);
+              }
+            }
+          });
+      });
+      this.$forceUpdate();
+    },
+    handleMaterialChange(val, row) {
+      if (val) {
+        let tempRow = row.material_detail_list.filter(
+          (item) => item.material_detail_id == val
+        );
+        row.material_detail_title = tempRow[0].title;
+        this.$forceUpdate();
+      }
+    },
+    handleProductExt_priceChange(e, product) {
+      product.ext_price = e.target.value * 1;
+      product.price =
+        (product.unit_price * 1 || 0) * (product.num * 1 || 1) +
+        (product.over_price * 1 || 0) +
+        (product.ext_price * 1 || 0);
+      product.price = product.price.toFixed(2);
+      this.$forceUpdate();
+    },
+    handleProductOver_priceChange(e, product) {
+      product.over_price = e.target.value;
+      product.price =
+        (product.unit_price * 1 || 0) * (product.num * 1 || 1) +
+        (product.over_price * 1 || 0) +
+        (product.ext_price * 1 || 0);
+      product.price = product.price.toFixed(2);
+      this.$forceUpdate();
+    },
+    handleProductUnit_priceChange(e, product) {
+      product.unit_price = e.target.value * 1;
+      product.price =
+        (product.unit_price * 1 || 0) * (product.num * 1 || 1) +
+        (product.over_price * 1 || 0) +
+        (product.ext_price * 1 || 0);
+      product.price = product.price.toFixed(2);
+      this.$forceUpdate();
+    },
+    handleProductNumChange(e, product) {
+      product.part.map((element) => {
+        element.part_detail.map((elem) => {
+          elem.material_detail_num =
+            e.target.value * elem.material_detail_org_num;
+        });
+      });
+      product.total_num = e.target.value;
+      product.num = (product.total_num * product.num_temp_save).toFixed(2);
+      product.price =
+        (product.unit_price * 1 || 0) * (product.num * 1 || 1) +
+        (product.over_price * 1 || 0) +
+        (product.ext_price * 1 || 0);
+      product.price = product.price.toFixed(2);
+      this.$forceUpdate();
+    },
+    handleCalcPartDetailLong(part_detail, product) {
+      for (const key in product.measure) {
+        const element = product.measure[key];
+        if (element.value) {
+          part_detail._longCalc = part_detail.longCalc.replace(
+            new RegExp(element.e_title, "g"),
+            element.value || ""
+          );
+        }
+      }
+      try {
+        eval(part_detail._longCalc);
+      } catch (error) {
+        for (const key in product.measure) {
+          const element = product.measure[key];
+          part_detail._longCalc = part_detail._longCalc.replace(
+            new RegExp(element.e_title, "g"),
+            element.value || ""
+          );
+        }
+      }
+      return part_detail._longCalc;
+    },
+    handleFindNearest(array, value) {
+      const temp = this.deepClone(array);
+      temp.sort((a, b) => {
+        return Math.abs(a.long - value) - Math.abs(b.long - value);
+      });
+      return temp[0].material_detail_id;
+    },
+    handleMetalChange(e, row, n, arr) {
+      arr[n].ext_id = e.value;
+      arr[n].title = e.label;
+    },
+    looks(img) {
+      const array = [{ img_url: img }];
+      this.$previewImg({
+        list: array,
+        baseUrl: this.$store.state.ip,
+        baseImgField: "img_url",
+        baseTitleField: "",
+      });
+    },
+    handleExtChange(row, { value, label }, item) {
+      row.ext_id = value;
+      row.title = label;
+      const element = this.extList.filter((item) => item.id == value);
+      row.num = element[0].num;
+      row.price = element[0].price;
+      row.total_price = (row.num * row.price).toFixed(2);
+      this.handleTotalPriceCalc(row, item);
+    },
+    handleTotalPriceCalc(row, item) {
+      row.total_price = ((row.price || 0) * (row.num || 0)).toFixed(2);
+      let sum1 = 0;
+      item.metalArray &&
+        item.metalArray.length > 0 &&
+        item.metalArray.forEach((element) => {
+          sum1 += element.total_price * 1 || 0;
+        });
+      let sum2 = 0;
+      item.extArray &&
+        item.extArray.length > 0 &&
+        item.extArray.forEach((element) => {
+          sum2 += element.total_price * 1 || 0;
+        });
+      item.ext_price = sum1 * 1 + sum2 * 1;
+      item.price =
+        (item.unit_price * 1 || 0) * (item.num * 1 || 1) +
+        (item.over_price * 1 || 0) +
+        (item.ext_price * 1 || 0);
+      item.price = item.price.toFixed(2);
+      this.$forceUpdate();
+    },
+    then() {
+      this.$emit("then");
+    },
+    cancel() {
+      this.$emit("cancel");
+    },
+    deepClone(obj) {
+      //定义对象来判断当前的参数是数组还是对象
+      let objClone = Array.isArray(obj) ? [] : {};
+      //如果obj存在并且为对象
+      if (obj && typeof obj == "object") {
+        for (let key in obj) {
+          if (Object.hasOwnProperty.call(obj, key)) {
+            //如果obj的子元素为对象,那么递归(层级遍历)
+            if (obj[key] && typeof obj[key] == "object") {
+              objClone[key] = this.deepClone(obj[key]);
+            } else {
+              //如果不是,直接赋值
+              objClone[key] = obj[key];
+            }
+          }
+        }
+      }
+      return objClone;
+    },
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  beforeCreate() {}, // 生命周期 - 创建之前
+  beforeMount() {}, // 生命周期 - 挂载之前
+  beforeUpdate() {}, // 生命周期 - 更新之前
+  updated() {}, // 生命周期 - 更新之后
+  beforeDestroy() {}, // 生命周期 - 销毁之前
+  destroyed() {}, // 生命周期 - 销毁完成
+  activated() {}, // 如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+
+<style lang="scss" scoped>
+.modal_product_info {
+  background-color: #f5f5f5;
+  border-radius: 10px;
+  padding: 10px;
+  margin-bottom: 10px;
+  .modal_product_info_title {
+    font-size: 20px;
+    font-weight: 700;
+    margin-bottom: 10px;
+  }
+  .modal_product_info_content {
+    .part_detail_form {
+      /deep/.ivu-form {
+        display: flex;
+        justify-content: flex-start;
+        flex-wrap: wrap;
+      }
+      /deep/ .ivu-form-item {
+        display: inline-block;
+        min-width: 150px;
+      }
+    }
+  }
+  .modal_product {
+    /deep/.ivu-form {
+      display: flex;
+      justify-content: flex-start;
+      flex-wrap: wrap;
+    }
+    /deep/ .ivu-form-item {
+      display: inline-block;
+      min-width: 200px;
+    }
+  }
+  .modal_parts {
+    /deep/.ivu-form {
+      display: flex;
+      justify-content: flex-start;
+      flex-wrap: wrap;
+    }
+    /deep/ .ivu-form-item {
+      display: inline-block;
+      min-width: 30px;
+    }
+  }
+  .modal_extra {
+    /deep/.ivu-form {
+      display: flex;
+      justify-content: flex-start;
+      flex-wrap: wrap;
+    }
+    /deep/ .ivu-form-item {
+      display: inline-block;
+      min-width: 100px;
+    }
+  }
+}
+</style>

+ 9 - 9
src/main.js

@@ -11,7 +11,7 @@ import "./untils/filter";
 import IconFont from './assets/iconfont/iconfont.js'
 import echarts from 'echarts'
 import Viewer from 'v-viewer'
-import components  from '@/untils/components'
+import components from '@/untils/components'
 import 'viewerjs/dist/viewer.css'
 import 'xe-utils'
 import VXETable from 'vxe-table'
@@ -25,7 +25,7 @@ Vue.use(VXETable)
 import 'lib-flexible'
 Vue.use(Viewer);
 Viewer.setDefaults({
-  Options: { "inline": true, "button": true, "navbar": true, "title": true, "toolbar": true, "tooltip": true, "movable": true, "zoomable": true, "rotatable": true, "scalable": true, "transition": true, "fullscreen": true, "keyboard": true, "url": "data-source" }
+    Options: { "inline": true, "button": true, "navbar": true, "title": true, "toolbar": true, "tooltip": true, "movable": true, "zoomable": true, "rotatable": true, "scalable": true, "transition": true, "fullscreen": true, "keyboard": true, "url": "data-source" }
 });
 
 Vue.use(ViewUI)
@@ -36,16 +36,16 @@ Vue.use(components)
 
 Vue.prototype.axios = axios
 
-Vue.prototype.func = untilFn//全局引入自定义函数库
+Vue.prototype.func = untilFn //全局引入自定义函数库
 
 Vue.config.productionTip = false
 Vue.prototype.$echarts = echarts
-Vue.prototype.$Message.config({//全局提示演示关闭时间
-  duration: 3
+Vue.prototype.$Message.config({ //全局提示演示关闭时间
+    duration: 3
 });
 
 new Vue({
-  router,
-  store,
-  render: h => h(App),
-}).$mount('#app')
+    router,
+    store,
+    render: h => h(App),
+}).$mount('#app')

+ 21 - 19
src/untils/components.js

@@ -20,25 +20,27 @@ import DispatchOrder from '../components/DispatchOrder/index.js'
 import PreviewImg from '../components/previewImg/index'
 import SetTableheader from '../components/tableHeader/index'
 import ConfirmForm from '../components/confirm/form/index'
+import AddProduct from '../components/product/add/index'
 
 
-export default (Vue)=>{
-  Vue.component("Topsearch", Topsearch)
-  Vue.component('Toptitle', Toptitle)  
-  Vue.component('Footer', Footer)
-  Vue.component('FullPage', FullPage)
-  Vue.component('Generaladd', Generaladd)
-  Vue.component('Tables', Tables)
-  Vue.component('ProductTables', ProductTables)
-  Vue.component('ColumnDropTree',ColumnDropTree)
-  Vue.use(Loading)
-  Vue.use(PreviewImg)
-  Vue.use(SetTableheader)
-  Vue.use(ConfirmForm)
-  Vue.use(ConfirmDelete)//删除--确认
-  Vue.use(SelectProcessRouter)//工艺路线
-  Vue.use(DownMeasurement)//下测量
-  Vue.use(DownProduction)//下生产---下生产计划
-  Vue.use(DispatchOrder)//派工单
-  Vue.use(Reference)
+export default (Vue) => {
+    Vue.component("Topsearch", Topsearch)
+    Vue.component('Toptitle', Toptitle)
+    Vue.component('Footer', Footer)
+    Vue.component('FullPage', FullPage)
+    Vue.component('Generaladd', Generaladd)
+    Vue.component('Tables', Tables)
+    Vue.component('ProductTables', ProductTables)
+    Vue.component('ColumnDropTree', ColumnDropTree)
+    Vue.use(Loading)
+    Vue.use(PreviewImg)
+    Vue.use(SetTableheader)
+    Vue.use(ConfirmForm)
+    Vue.use(AddProduct)
+    Vue.use(ConfirmDelete) //删除--确认
+    Vue.use(SelectProcessRouter) //工艺路线
+    Vue.use(DownMeasurement) //下测量
+    Vue.use(DownProduction) //下生产---下生产计划
+    Vue.use(DispatchOrder) //派工单
+    Vue.use(Reference)
 }

+ 23 - 6
src/views/BidSystem/ContractList/list.vue

@@ -104,12 +104,7 @@
         </div>
       </template>
     </FullPage>
-    <Modal
-      v-model="processModal"
-      title="下深化"
-      @on-ok="handleProcess"
-      @on-cancel="processModal = false"
-    >
+    <Modal v-model="processModal" title="下深化">
       <div>
         <div class="process_modal">
           <span>深化人员:</span>
@@ -139,6 +134,22 @@
           ></DatePicker>
         </div>
       </div>
+      <div slot="footer">
+        <Button
+          @click="processModal = false"
+          type="primary"
+          ghost
+          style="margin-right: 10px"
+          >取消</Button
+        >
+        <Button
+          @click="handleProcess"
+          type="primary"
+          style="margin-right: 10px"
+          :disabled="process_control"
+          >确定</Button
+        >
+      </div>
     </Modal>
     <Modal
       v-model="showModal"
@@ -185,6 +196,7 @@ export default {
   data() {
     // 这里存放数据
     return {
+      process_control: false,
       tableColums: [
         {
           type: "selection",
@@ -537,6 +549,7 @@ export default {
   },
   methods: {
     handleProcess() {
+      this.process_control = true;
       this.axios({
         method: "get",
         url: "/api/order_area_pull",
@@ -554,7 +567,11 @@ export default {
         if (res.code == 200) {
           this.$Message.success(res.msg);
           this.getData(this.proxyObj);
+          this.processModal = false;
         }
+        setTimeout(() => {
+          this.process_control = false;
+        }, 500);
       });
     },
     //1深化  2编辑  3详情  4删除  0新增

+ 11 - 14
src/views/BidSystem/DeepeningOrder/list.vue

@@ -140,7 +140,8 @@
           >取消</Button
         >
         <Button
-          @click="debounce(handleProcess(), 1000)"
+          @click="handleProcess"
+          :disabled="throttle_control"
           type="primary"
           style="margin-right: 10px"
           >确定</Button
@@ -159,6 +160,7 @@ export default {
   data() {
     // 这里存放数据
     return {
+      throttle_control: false,
       tableColums: [
         {
           type: "selection",
@@ -285,6 +287,7 @@ export default {
   mounted() {},
   methods: {
     handleProcess() {
+      this.throttle_control = true;
       if (
         this.process_man &&
         this.process_end_time &&
@@ -307,8 +310,10 @@ export default {
           this.$Message.success(res.msg);
           this.processModal = false;
           this.getData(this.proxyObj);
+          this.throttle_control = false;
         });
       } else {
+        this.throttle_control = false;
         this.$Message.warning("信息请填写完整");
       }
     },
@@ -394,19 +399,11 @@ export default {
         this.tableheaders = res.data.tableSet || [];
       });
     },
-    debounce(fn, delay) {
-      let timer = null;
-      return function() {
-        const context = this;
-        const args = arguments;
-        if (timer) {
-          clearTimeout(timer);
-          timer = null;
-        }
-        timer = setTimeout(() => {
-          fn.apply(context, args);
-        }, delay);
-      };
+    throttle(delay) {
+      this.throttle_control = true;
+      setTimeout(() => {
+        this.handleProcess();
+      }, delay);
     },
     changePage(e) {
       this.page_index = e;

+ 190 - 86
src/views/BidSystem/ProductDeOrder/deorderdetail.vue

@@ -341,7 +341,7 @@
           <div style="padding: 10px 0">
             <span>工艺路线:</span>
             <Button
-              :disabled="!partsItem.isAddProcessRoute || type == 2"
+              :disabled="type == 2"
               @click="editRouter(partsItem, partsIndex)"
               >选择工艺路线</Button
             >
@@ -432,19 +432,44 @@
                 v-model="partsItem.partsWoodTableData[index].number"
               />
             </template>
+
+            <template slot-scope="{ index }" slot="partWoolLongSet">
+              <Input
+                @on-search="openKey(partsIndex, index, 'wool_long', partsItem)"
+                :disabled="type == 2"
+                placeholder="毛料高"
+                search
+                enter-button="公式"
+                v-model="partsItem.partsWoodTableData[index].wool_long"
+              />
+            </template>
+            <template slot-scope="{ index }" slot="partWoolWideSet">
+              <Input
+                @on-search="openKey(partsIndex, index, 'wool_wide', partsItem)"
+                :disabled="type == 2"
+                placeholder="毛料宽"
+                search
+                enter-button="公式"
+                v-model="partsItem.partsWoodTableData[index].wool_wide"
+              />
+            </template>
             <template slot-scope="{ index }" slot="partLongSet">
               <Input
-                @on-focus="openKey(partsIndex, index, 'long', partsItem)"
-                :disabled="!partsItem.isAddPart || type == 2"
-                placeholder="高"
+                @on-search="openKey(partsIndex, index, 'long', partsItem)"
+                :disabled="type == 2"
+                placeholder="精裁高"
+                search
+                enter-button="公式"
                 v-model="partsItem.partsWoodTableData[index].long"
               />
             </template>
             <template slot-scope="{ index }" slot="partWideSet">
               <Input
-                @on-focus="openKey(partsIndex, index, 'wide', partsItem)"
-                :disabled="!partsItem.isAddPart || type == 2"
-                placeholder="宽"
+                @on-search="openKey(partsIndex, index, 'wide', partsItem)"
+                :disabled="type == 2"
+                placeholder="精裁宽"
+                search
+                enter-button="公式"
                 v-model="partsItem.partsWoodTableData[index].wide"
               />
             </template>
@@ -970,6 +995,7 @@
       <div>
         <KeyBoard
           :rightData="measureList"
+          :showValue="KeyBoardValue"
           @cancel="cancelKey"
           @success="successKey"
           class="key-co"
@@ -1050,7 +1076,9 @@ export default {
                 number: "",
                 company: "",
                 long: "",
+                wool_long: "",
                 wide: "",
+                wool_wide: "",
                 thick: "",
                 technological_requirement_id: "",
                 sub_num: "",
@@ -1117,17 +1145,31 @@ export default {
         },
         { title: "单位", key: "company", align: "center", minWidth: 80 },
         {
-          title: "高",
+          title: "毛料高",
+          key: "wool_long",
+          align: "center",
+          minWidth: 180,
+          slot: "partWoolLongSet",
+        },
+        {
+          title: "毛料宽",
+          key: "wool_wide",
+          align: "center",
+          minWidth: 180,
+          slot: "partWoolWideSet",
+        },
+        {
+          title: "精裁高",
           key: "long",
           align: "center",
-          minWidth: 120,
+          minWidth: 180,
           slot: "partLongSet",
         },
         {
-          title: "宽",
+          title: "精裁宽",
           key: "wide",
           align: "center",
-          minWidth: 120,
+          minWidth: 180,
           slot: "partWideSet",
         },
         { title: "厚", key: "thick", align: "center", minWidth: 120 },
@@ -1333,6 +1375,7 @@ export default {
         // { e_title: 'W', title: '宽', id: 1, sort: 0 },
         // { e_title: 'D', title: '深', id: 1, sort: 0 },
       ],
+      KeyBoardValue: "",
       attrIndex: "",
       attrName: "",
       materialWoodList: [], // 木板列表
@@ -1469,7 +1512,9 @@ export default {
                   number: "",
                   company: "",
                   long: "",
+                  wool_long: "",
                   wide: "",
+                  wool_wide: "",
                   thick: "",
                   technological_requirement_id: "",
                   sub_num: "",
@@ -1642,12 +1687,22 @@ export default {
         }).then((res) => {
           if (res.code == 200) {
             res.data.part.forEach((element) => {
-              this.formData.parts.forEach((ele) => {
+              this.formData.parts.forEach((ele, idx) => {
                 if (element.part_id == ele.part_id) {
                   element.process_ids = ele.process_ids;
                   element.route_id = ele.route_id;
                   element.produce_list = ele.produce_list;
                   element.process_list = ele.process_list;
+                  element.part_title = element.title
+                  if (isEditItem) {
+                    const temp_arr = isEditItem.parts.filter(
+                      (v) => v.part_id == element.part_id
+                    );
+                    element.long = temp_arr[temp_arr.length - 1].long;
+                    element.wide = temp_arr[temp_arr.length - 1].wide;
+                    element.thick = temp_arr[temp_arr.length - 1].thick;
+                    element.detail = temp_arr[temp_arr.length - 1].detail;
+                  }
                 }
               });
             });
@@ -1667,50 +1722,52 @@ export default {
             this.formData.parts.map((element) => {
               element.partsProcessLineTableData = [];
               element.proportion = element.ratio;
-              element.wide = element.formula_w;
-              element.thick = element.formula_h;
-              element.long = element.formula_l;
               element.isShowProcessLine = true;
               element.ProcessAttrList = JSON.parse(
                 JSON.stringify(this.tempProcessAttrList)
               ); //工艺属性列表
-
-              this.axios("/api/parts_detail", {
-                params: { id: element.part_id },
-              }).then((re) => {
-                // element.company = re.data.company
-                element.isAddPart = true;
-                element.isAddProcessRoute = true;
-                element.parts_type = re.data.p_id;
-                // element.part_id = re.data.title
-                this.axios({
-                  method: "get",
-                  url: "/api/parts_index",
-                  params: {
-                    bp_id: element.parts_type,
-                  },
-                }).then((r) => {
-                  element.partsNameList = r.data.data;
-                  if (isEditItem) {
-                    let item = isEditItem;
-                    // let item = JSON.parse(JSON.stringify(isEditItem));
-                    item.parts.forEach((element) => {
-                      element.processCombination = element.route_id;
-                      let obj = { value: element.route_id, label: "" };
-                      this.handleProcessRouteSelect(element, obj);
-                    });
-                    isEditItem = item;
-                  }
-                  this.$forceUpdate();
+              element.part_id &&
+                this.axios("/api/parts_detail", {
+                  params: { id: element.part_id },
+                }).then((re) => {
+                  // element.company = re.data.company
+                  element.isAddPart = true;
+                  element.isAddProcessRoute = true;
+                  element.parts_type = re.data.p_id;
+                  this.axios({
+                    method: "get",
+                    url: "/api/parts_index",
+                    params: {
+                      bp_id: element.parts_type,
+                    },
+                  }).then((r) => {
+                    element.partsNameList = r.data.data;
+                    element.part_id = re.data.id;
+                    console.log("element :>> ", element);
+                    if (isEditItem) {
+                      let item = isEditItem;
+                      // let item = JSON.parse(JSON.stringify(isEditItem));
+                      item.parts.forEach((it) => {
+                        it.processCombination = it.route_id;
+                        let obj = { value: it.route_id, label: "" };
+                        this.handleProcessRouteSelect(it, obj);
+                      });
+                      isEditItem = item;
+                    } else {
+                      element.thick = element.formula_h;
+                      element.wide = element.formula_w;
+                      element.long = element.formula_l;
+                    }
+                    this.$forceUpdate();
+                  });
+                  element.company = re.data.company;
+                  // element.partsNameList = [{ id: re.data.id, title: re.data.title }]
+                  element.pay_state = re.data.label;
+                  // element.partsWoodTableData = re.data.detail;
+                  this.showSimilarProductModal = false;
                 });
-                element.company = re.data.company;
-                // element.partsNameList = [{ id: re.data.id, title: re.data.title }]
-                element.pay_state = re.data.label;
-                // element.partsWoodTableData = re.data.detail;
-                this.showSimilarProductModal = false;
-              });
-              let obj = { value: element.part_id };
-              this.handlePartsNameSelect(element, obj);
+              let obj = { value: element.part_id, title: element.title };
+              this.handlePartsNameSelect_test(element, obj);
             });
           }
         });
@@ -1774,7 +1831,8 @@ export default {
     },
     // 部件名称
     handlePartsNameSelect(item, val) {
-      if (val) {
+      if (val && val.value) {
+        item.part_title = val.label
         if (val.label != val.value) {
           item.isAddPart = false;
           this.axios({
@@ -1818,6 +1876,61 @@ export default {
           // item.process_name = "";
         }
       }
+      console.log('item :>> ', item);
+    },
+    handlePartsNameSelect_test(item, val) {
+      if (val && val.value) {
+        if (val.label != val.value) {
+          item.isAddPart = false;
+          this.axios({
+            method: "get",
+            url: "/api/parts_detail",
+            params: {
+              id: val.value,
+            },
+          }).then((res) => {
+            item.pay_state = res.data.label;
+            item.company = res.data.company;
+            item.ProcessAttrList = this.tempProcessAttrList;
+            item.partsWoodTableData ? "" : (item.partsWoodTableData = []);
+            item.partsMetalseData ? "" : (item.partsMetalseData = []);
+            item.partsWoodTableData = res.data.detail.filter(
+              (v) => v.type_id == 1 || v.type_id == 2
+            );
+            console.log("item :>> ", item);
+            item.partsWoodTableData.map((v, k) => {
+              const temp_arr = item.detail.filter((w) => w.id == v.id);
+              if (temp_arr.length > 0) {
+                v.long = temp_arr[temp_arr.length - 1].long;
+                v.wool_long = temp_arr[temp_arr.length - 1].wool_long;
+                v.wide = temp_arr[temp_arr.length - 1].wide;
+                v.wool_wide = temp_arr[temp_arr.length - 1].wool_wide;
+              }
+            });
+            item.partsMetalseData = res.data.detail.filter(
+              (v) => v.type_id == 5
+            );
+            this.axios({
+              method: "get",
+              url: "/api/process_route_index",
+              params: {
+                part_id: val.value,
+              },
+            }).then((re) => {
+              this.$nextTick(() => {
+                item.partsProcessRouteList = re.data.detail;
+                this.$forceUpdate();
+              });
+            });
+          });
+        } else {
+          item.isAddPart = true;
+          // item.ProcessAttrList = this.tempProcessAttrList;
+          // item.partsWoodTableData = [];
+          // item.partsMetalseData = [];
+          // item.process_name = "";
+        }
+      }
     },
     // 选择工艺组合名称
     handleProcessRouteSelect(item, val) {
@@ -1893,9 +2006,7 @@ export default {
         // }
       }
     },
-    handleProcessSelect(){
-      
-    },
+    handleProcessSelect() {},
     handleProcessLineShow(item, index) {
       item.isShowProcessLine
         ? (document.getElementsByClassName("parts_content_lineTable")[
@@ -2098,7 +2209,9 @@ export default {
             number: "",
             company: "",
             long: "",
+            wool_long: "",
             wide: "",
+            wool_wide: "",
             thick: "",
             technological_requirement_id: "",
             sub_num: "",
@@ -2140,7 +2253,9 @@ export default {
         number: "",
         company: "",
         long: "",
+        wool_long: "",
         wide: "",
+        wool_wide: "",
         thick: "",
         technological_requirement_id: "",
         sub_num: "",
@@ -2205,13 +2320,13 @@ export default {
       this.formData.parts.forEach((element) => {
         sum += element.proportion * 1;
       });
-      const BJ_name = this.formData.parts.map((item) => {
-        return item.part_id;
-      });
-      const atfer_BJ_name = Array.from(new Set(BJ_name));
-      if (atfer_BJ_name.length != BJ_name.length) {
-        return this.$Message.error("部件名称存在重复");
-      }
+      // const BJ_name = this.formData.parts.map((item) => {
+      //   return item.part_id;
+      // });
+      // const atfer_BJ_name = Array.from(new Set(BJ_name));
+      // if (atfer_BJ_name.length != BJ_name.length) {
+      //   return this.$Message.error("部件名称存在重复");
+      // }
       if (sum != 100) {
         this.$Message.error("产值比之和须为100");
       } else {
@@ -2219,12 +2334,12 @@ export default {
         let save_sucess = true;
         for (let i in this.formData.parts) {
           let element = this.formData.parts[i];
-          let flag = false;
-          element.partsNameList.forEach((ele) => {
-            if (element.part_id == ele.id && ele.id == ele.title) {
-              flag = true;
-            }
-          });
+          let flag = true;
+          // element.partsNameList.forEach((ele) => {
+          //   if (element.part_id == ele.id && ele.id == ele.title) {
+          //     flag = true;
+          //   }
+          // });
           if (flag) {
             let result = await this.axios({
               method: "post",
@@ -2235,7 +2350,7 @@ export default {
                   bp_id: this.nowSelectObj.id, //相似产品
                   company: element.company,
                   label: element.pay_state,
-                  title: element.part_id,
+                  title: element.part_title,
                 },
                 op: "add",
                 detail: [
@@ -2257,8 +2372,7 @@ export default {
               //   }
               // });
               let properties = element.ProcessAttrList.map((v) => {
-                console.log('v :>> ', v);
-                return { name: v.name, value: v.selected_value||'' };
+                return { name: v.name, value: v.selected_value || "" };
               });
               // element.partsProcessLineTableData.forEach(async (el, idx) => {
               //   if (idx == element.length - 1) {
@@ -2297,7 +2411,7 @@ export default {
             //   }
             // });
             let properties = element.ProcessAttrList.map((v) => {
-              return { name: v.name, value: v.selected_value||'' };
+              return { name: v.name, value: v.selected_value || "" };
             });
             if (bool) {
               let res = await this.axios({
@@ -2368,27 +2482,17 @@ export default {
     cancelKey() {
       this.showKey = false;
     },
+    handleMeasureSearch() {},
     openKey(partsIndex, index, attr, partsItem) {
-      // this.axios({
-      //   method: "get",
-      //   url: "/api/basics_product_list",
-      //   params: {
-      //     id: partsItem.part_id,
-      //   },
-      // })
-      //   .then((res) => {
-      // res.data.forEach((element) => {
-      //   if (element.id == partsItem.part_id) {
-      //     this.measureList = element.measure;
-      //   }
-      // });
       this.showKey = true;
-      this.attrParentindex = partsIndex;
+      this.KeyBoardValue = this.attrParentindex = partsIndex;
       if (index != -1) {
         this.attrIndex = index;
         this.keyUseType = 1;
+        this.KeyBoardValue = partsItem.partsWoodTableData[index][attr];
       } else {
         this.keyUseType = 2;
+        this.KeyBoardValue = partsItem[attr];
       }
       this.attrName = attr;
       // })

+ 37 - 19
src/views/BidSystem/ProductDeOrder/list.vue

@@ -101,12 +101,7 @@
         </div>
       </template>
     </FullPage>
-    <Modal
-      v-model="processModal"
-      title="下生产"
-      @on-ok="handleProcess"
-      @on-cancel="processModal = false"
-    >
+    <Modal v-model="processModal" title="下生产">
       <div>
         <div class="process_modal">
           <span>生产人员:</span>
@@ -136,6 +131,22 @@
           ></DatePicker>
         </div>
       </div>
+      <div slot="footer">
+        <Button
+          @click="processModal = false"
+          type="primary"
+          ghost
+          style="margin-right: 10px"
+          >取消</Button
+        >
+        <Button
+          @click="handleProcess"
+          type="primary"
+          style="margin-right: 10px"
+          :disabled="process_control"
+          >确定</Button
+        >
+      </div>
     </Modal>
   </div>
 </template>
@@ -149,6 +160,7 @@ export default {
   data() {
     // 这里存放数据
     return {
+      process_control: false,
       tableColums: [
         {
           type: "selection",
@@ -276,6 +288,7 @@ export default {
   mounted() {},
   methods: {
     handleProcess() {
+      this.process_control = true;
       this.axios({
         method: "get",
         url: "/api/order_area_pull",
@@ -292,7 +305,11 @@ export default {
         if (res.code == 200) {
           this.$Message.success(res.msg);
           this.getData(this.proxyObj);
+          this.processModal = false;
         }
+        setTimeout(() => {
+          this.process_control = false;
+        }, 500);
       });
     },
     // 1下生产  2拆单  3详情 4删除 5成本预算
@@ -357,11 +374,10 @@ export default {
                   order_no: row.order_no,
                   sub_status: 2,
                 },
-              })
-                .then((res) => {
-                  this.$Message.success(res.msg);
-                  this.getData(this.proxyObj);
-                })
+              }).then((res) => {
+                this.$Message.success(res.msg);
+                this.getData(this.proxyObj);
+              });
             },
             onCancel: () => {},
           });
@@ -381,8 +397,8 @@ export default {
       this.page_index = 1;
       // 2拆单  换接口 弃用
       // row.sub_status = 2;
-      if (!row.explode_status&&row.explode_status!=0) {
-        row.explode_status = 99
+      if (!row.explode_status && row.explode_status != 0) {
+        row.explode_status = 99;
       }
       row.page_index = this.page_index;
       row.page_size = this.page_size;
@@ -391,12 +407,14 @@ export default {
     },
     getData(row) {
       this.loading = true;
-      this.axios("/api/order_area_explode_list", { params: row }).then((res) => {
-        this.loading = false;
-        this.tableData = res.data.data;
-        this.total = res.data.total;
-        this.tableheaders = res.data.tableSet || [];
-      });
+      this.axios("/api/order_area_explode_list", { params: row }).then(
+        (res) => {
+          this.loading = false;
+          this.tableData = res.data.data;
+          this.total = res.data.total;
+          this.tableheaders = res.data.tableSet || [];
+        }
+      );
     },
     changePage(e) {
       this.page_index = e;

+ 162 - 30
src/views/OrderMannage/BusinessOrderlist/edit.vue

@@ -3,15 +3,15 @@
     <Toptitle
       :title="type == 1 ? '新增订单' : type == 2 ? '编辑订单' : '订单详情'"
     >
-      <Button 
-      @click="print" 
-      type="primary" 
-      ghost 
-      v-show="type == 3"
-      style="margin-right: 10px"
+      <Button
+        @click="print"
+        type="primary"
+        ghost
+        v-show="type == 3"
+        style="margin-right: 10px"
         >打印</Button
       >
-       <Button @click="back" type="primary" ghost style="margin-right: 10px"
+      <Button @click="back" type="primary" ghost style="margin-right: 10px"
         >返回</Button
       >
       <Button
@@ -2704,6 +2704,7 @@ export default {
       cus_list: [],
       pre_bp_id: "",
       support_remark: [],
+      bpp_list: [],
     };
   },
   computed: {
@@ -2714,6 +2715,15 @@ export default {
   },
   watch: {},
   created() {
+    //   获取工艺属性
+    this.axios({
+      method: "get",
+      url: "/api/bpp_list",
+    }).then((res) => {
+      if (res.code == 200) {
+        this.bpp_list = res.data;
+      }
+    });
     // 获取负责人列表
     this.axios.get("/api/support_service_name").then((res) => {
       this.clientDetailList_respon = [];
@@ -2812,11 +2822,14 @@ export default {
           }
         });
     },
-    print(){
-      this.$router.push({path:"/cms/ordermannage/businessorderlist/printlist",query:{
-       order_no:this.$route.query.order_no,
-       box_id:this.info.box_id
-      }})
+    print() {
+      this.$router.push({
+        path: "/cms/ordermannage/businessorderlist/printlist",
+        query: {
+          order_no: this.$route.query.order_no,
+          box_id: this.info.box_id,
+        },
+      });
     },
     back() {
       // this.$router.go(-1);
@@ -2933,7 +2946,7 @@ export default {
       this.modalArray.splice(idx, 1);
     },
     handleTabsAdd() {
-      let index = JSON.parse(JSON.stringify(this.modalArray.length));
+      let index = this.modalArray.length;
       this.modalArray.push({
         type_name: "产品" + (this.modalArray.length + 1),
         position: "",
@@ -3487,7 +3500,7 @@ export default {
       let total_line = 0;
       this.wood_title_count.map((v) => {
         v.measure_str.map((w) => {
-          total_line += w.num*1;
+          total_line += w.num * 1;
         });
       });
       // 线条合计放进统计
@@ -3915,11 +3928,134 @@ export default {
         }
       });
     },
+    // handleShowAddProductModal(this.info.custom_id,)
+    handleShowAddProductModal(custom_id, route_id_at_copy) {
+      this.$addProduct({
+        custom_id,
+        route_id_at_copy,
+        then: (addProductArray) => {
+          console.log("addProductArray :>> ", addProductArray);
+          this.modalArray = addProductArray
+          this.modalArray.forEach((element) => {
+            // 工艺属性
+            if (!element.procedure_properties_str) {
+              element.procedure_properties_str = [];
+            }
+            if (!element.procedure_properties) {
+              element.procedure_properties = [];
+            }
+            element.process.forEach((elem, index) => {
+              const _temp = elem.processList.filter(
+                (item) => item.id == elem.value
+              );
+              element.procedure_properties_str[index] =
+                _temp.length > 0 ? _temp[0].title : "";
+              element.procedure_properties[index] =
+                _temp.length > 0 ? _temp[0].id : "";
+            });
+            element.process_str = element.procedure_properties_str.join("/");
+            // 尺寸
+            if (!element.measurement) {
+              element.measurement = "";
+            }
+            if (!element.measurement_no_letter) {
+              element.measurement_no_letter = "";
+            }
+            let tempStr = "";
+            let tempStr_no_letter = "";
+            element.measure.forEach((elem) => {
+              tempStr += elem.measureCalc + elem.value + "*";
+              tempStr_no_letter += +elem.value + "*";
+            });
+            element.measurement = tempStr.substring(0, tempStr.length - 1);
+            element.measurement_no_letter = tempStr_no_letter.substring(
+              0,
+              tempStr_no_letter.length - 1
+            );
+            // 五金、  附加项目
+            element.ext = [...element.metalArray, ...element.extArray];
+            //其他项
+            element.other = element.customize;
+            // 部件字段
+            element.part.forEach((elem) => {
+              if (!elem.is_metal) {
+                elem.title ? "" : (elem.title = elem.part_title);
+                // if (elem.procedure_properties_str && elem.procedure_properties_str != 0) {
+                //   elem.process_str = elem.procedure_properties_str.join('/')
+                // } else {
+                elem.procedure_properties_str = [];
+                elem.process.forEach((item, index) => {
+                  const _temp = item.cld.filter(
+                    (_cld) => _cld.id == item.procedure_property
+                  );
+                  elem.procedure_properties_str[index] =
+                    _temp.length > 0 ? _temp[0].title : "";
+                });
+                elem.process_str = elem.procedure_properties_str.join("/");
+                // }
+              }
+            });
+            element.ext &&
+              element.ext.length > 0 &&
+              (element.ext.map((elem) => {
+                if (elem.type == 1) {
+                  elem.total_num = elem.num;
+                  elem.unit_price = elem.price;
+                  elem.ext_price = elem.num * elem.price;
+                  elem.is_metal = true;
+                  element.part.push(elem);
+                  if (!element.extra) {
+                    element.extra = "";
+                  }
+                } else {
+                  if (!element.extra) {
+                    element.extra = "";
+                  }
+                  element.extra += `${elem.title}/`;
+                }
+              }),
+              (element.extra = element.extra.substring(
+                0,
+                element.extra.length - 1
+              )));
+            // element.part.push({
+            //   title: "五金",
+            //   total_num: "",
+            //   unit_price: "",
+            // });
+          });
+          this.modalArray.forEach((element) => {
+            element.part.forEach((elem) => {
+              if (!elem.is_metal) {
+                elem.measurement = `${elem.long}*${elem.wide}*${elem.high}`;
+                elem.title = elem.part_title;
+                elem.procedure_properties = [];
+                elem.process.map((item) => {
+                  elem.procedure_properties.push(item.procedure_property);
+                });
+              }
+            });
+          });
+          this.tableData = [...this.tableData, ...this.modalArray];
+          this.currencyIndex = null;
+          this.route_id_at_copy = "";
+          // 合计 、 线条 统计价格
+          this.handleCalcCount();
+          this.showAddProduct = false;
+          this.$forceUpdate();
+        },
+      });
+    },
+    handleShowEditProductModal(custom_id, route_id_at_copyrow) {},
     handleSet(row, index, type) {
       let obj;
       // 1 新增 2 编辑 3 删除 4复制  5详情
       switch (type) {
         case 1:
+          // this.handleShowAddProductModal(
+          //   this.info.custom_id,
+          //   this.route_id_at_copy
+          // );
           this.title_state = 1;
           if (this.info.custom_id) {
             this.modalArray = [
@@ -4209,26 +4345,24 @@ export default {
                   element.long ? "" : (element.long = 0);
                   element.wide ? "" : (element.wide = 0);
                   element.high ? "" : (element.high = 0);
-                  element.longCalc = JSON.parse(JSON.stringify(element.long));
-                  element.wideCalc = JSON.parse(JSON.stringify(element.wide));
-                  element.highCalc = JSON.parse(JSON.stringify(element.high));
+                  element.longCalc = element.long;
+                  element.wideCalc = element.wide;
+                  element.highCalc = element.high;
                   element.part_detail.forEach((elem) => {
-                    elem.org_num = JSON.parse(JSON.stringify(elem.num));
+                    elem.org_num = elem.num;
                     elem.material_detail_id = 0;
                     elem.material_detail_title =
                       elem.material_detail_list[0].title;
                     elem.material_detail_id =
                       elem.material_detail_list[0].material_detail_id;
                     elem.material_detail_num = elem.num || 0;
-                    elem.material_detail_org_num = JSON.parse(
-                      JSON.stringify(elem.num || 0)
-                    );
+                    elem.material_detail_org_num = elem.num || 0;
                     elem.long ? "" : (elem.long = 0);
                     elem.wide ? "" : (elem.wide = 0);
                     elem.high ? "" : (elem.high = 0);
-                    elem.longCalc = JSON.parse(JSON.stringify(elem.long || ""));
-                    elem.wideCalc = JSON.parse(JSON.stringify(elem.wide || ""));
-                    elem.highCalc = JSON.parse(JSON.stringify(elem.high || ""));
+                    elem.longCalc = elem.long || "";
+                    elem.wideCalc = elem.wide || "";
+                    elem.highCalc = elem.high || "";
                     elem.material_detail_list.forEach((el) => {
                       el.long = el.long || "0";
                       el.wide = el.wide || "0";
@@ -4242,7 +4376,7 @@ export default {
             modalData.measure = res.data.measure;
             modalData.measure.forEach((element) => {
               element.value = "";
-              element.measureCalc = JSON.parse(JSON.stringify(element.e_title));
+              element.measureCalc = element.e_title;
             });
             //工艺属性
             modalData.process = [];
@@ -4349,7 +4483,7 @@ export default {
       this.info.fax_price = (this.info.predict_price - e.target.value).toFixed(
         2
       );
-      this.$forceUpdate()
+      this.$forceUpdate();
     },
     handleClearExtInfo(modalData, pre_id, cur_id) {
       if (cur_id != pre_id) {
@@ -5140,9 +5274,7 @@ export default {
         if (product.num_formula == "") {
           product.total_num = product.num;
         } else {
-          product.num_formula_temp = JSON.parse(
-            JSON.stringify(product.num_formula)
-          );
+          product.num_formula_temp = product.num_formula;
           product.measure.forEach((element) => {
             if (product.num_formula.indexOf(element.e_title) != -1) {
               product.num_formula_temp = product.num_formula_temp.replace(
@@ -5154,7 +5286,7 @@ export default {
           product.num = eval(product.num_formula_temp);
           product.num = product.num.toFixed(2);
           product.over_price = product.over_price.toFixed(2);
-          product.num_temp_save = JSON.parse(JSON.stringify(product.num));
+          product.num_temp_save = product.num;
           product.price =
             (product.unit_price * 1 || 0) * (product.num * 1 || 1) +
             (product.over_price * 1 || 0) +

+ 35 - 0
src/views/ProductionOrderList/InboundForm/index.vue

@@ -185,6 +185,41 @@ export default {
           serverName: "residential_name",
         },
         {
+          title: "区域",
+          name: "Input",
+          placeholder: "请输入区域",
+          value: "",
+          serverName: "residential_name",
+        },
+        {
+          title: "楼层",
+          name: "Input",
+          placeholder: "请输入楼层",
+          value: "",
+          serverName: "residential_name",
+        },
+        {
+          title: "房间",
+          name: "Input",
+          placeholder: "请输入房间",
+          value: "",
+          serverName: "residential_name",
+        },
+        {
+          title: "图号",
+          name: "Input",
+          placeholder: "请输入图号",
+          value: "",
+          serverName: "residential_name",
+        },
+        {
+          title: "部件分类",
+          name: "Input",
+          placeholder: "请输入部件分类",
+          value: "",
+          serverName: "residential_name",
+        },
+        {
           title: "包装状态",
           name: "Select",
           placeholder: "请选择",

+ 2 - 2
vue.config.js

@@ -2,10 +2,10 @@ const axios_default_ip =
     process.env.NODE_ENV == 'dev' ?
     'http://121.41.102.225:82' :
     process.env.NODE_ENV == 'test-prd' ?
-    'http://124.71.176.88:882' //测试服
+    'http://121.41.102.225:82' //测试服
     :
     process.env.NODE_ENV == 'prd_other' ?
-    'http://121.37.173.82:82' //森兰九鼎
+    'http://121.37.173.82:82' //贝斯特
     :
     'http://124.71.176.88:82';
 //  http://124.71.176.88:882  //江山