Parcourir la source

'报价管理'

zhujun il y a 2 ans
Parent
commit
3eec4a1a16

+ 32 - 27
src/api/saleManage/quotation.js

@@ -1,5 +1,5 @@
 import request from '@/utils/request';
-
+import { download } from '@/utils/file';
 /**
  * 获取信息列表
  */
@@ -48,7 +48,7 @@ export async function addInformation(data) {
  * 删除
  */
 export async function deleteInformation(data) {
-  const res = await request.delete('/eom/quote/delete', {data});
+  const res = await request.delete('/eom/quote/delete', { data });
   if (res.data.code == 0) {
     return res.data.data;
   }
@@ -59,34 +59,39 @@ export async function deleteInformation(data) {
  * 导出报价单
  */
 export async function getExport(id) {
-    const res = await request.get(`/eom/quote/export/${id}`, {});
-    if (res.data.code == 0) {
-      return res.data.data;
-    }
-    return Promise.reject(new Error(res.data.message));
-  }
+  const res = await request.get(
+    `/eom/quote/export/${id}`,
+    {
+      responseType: 'blob'
+    },
+
+  );
+
+  download(res.data, '报价单.xlsx');
+}
 
+/**
+ * 产品分类
+ */
 
-  /**
-   * 产品分类
-   */
-  
-  export async function getProduceTreeByPid() {
-    const res = await request.get(`/main/categoryLevel/getProduceTreeByPid?type=1`, {});
-    if (res.data.code == 0) {
-      return res.data.data;
-    }
-    return Promise.reject(new Error(res.data.message));
+export async function getProduceTreeByPid() {
+  const res = await request.get(
+    `/main/categoryLevel/getProduceTreeByPid?type=1`,
+    {}
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
   }
+  return Promise.reject(new Error(res.data.message));
+}
 
 /**
-   * 产品列表
-   */
-  export async function getProductList(params) {
-    const res = await request.get(`/main/category/getList`, { params });
-    if (res.data.code == 0) {
-      return res.data.data;
-    }
-    return Promise.reject(new Error(res.data.message));
+ * 产品列表
+ */
+export async function getProductList(params) {
+  const res = await request.get(`/main/category/getList`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
   }
-  
+  return Promise.reject(new Error(res.data.message));
+}

+ 1 - 0
src/components/Dict/DictSelection.vue

@@ -67,6 +67,7 @@
           this.$emit('itemChange', this.getDict(this.dictName, val));
         },
         get() {
+          console.log(this.dictList,'3333333333333')
           return this.value;
         }
       }

+ 166 - 0
src/components/productTree/index.vue

@@ -0,0 +1,166 @@
+<template>
+    <div class="tree-wrapper">
+      <el-tree
+        :data="treeList"
+        :props="defaultProps"
+        v-loading="treeLoading"
+        :node-key="nodeKey"
+        ref="tree"
+        :highlight-current="true"
+        :expand-on-click-node="false"
+        @node-click="handleNodeClick"
+        v-bind="$attrs"
+        :default-expand-all="defaultExpandAll"
+      >
+      </el-tree>
+    </div>
+  </template>
+  
+  <script>
+    import { getProduceTreeByPid } from '@/api/saleManage/quotation';
+    // let originId = '';
+    // let originType = '';
+    export default {
+      props: {
+        // treeList私有化处理
+        treeFormate: {
+          type: Function,
+          default: null
+        },
+        defaultProps: {
+          type: Object,
+          default: function () {
+            return {
+              children: 'children',
+              value: 'id',
+              label: 'name'
+            };
+          }
+        },
+        defaultExpandAll: {
+          type: Boolean,
+          default: function () {
+            return false;
+          }
+        },
+        // 初始请求treeList
+        init: {
+          type: Boolean,
+          default: true
+        },
+       
+        isFirstRefreshTable:{
+          type: Boolean,
+          default: true
+        },
+        id: {
+          type: String,
+          default: '0'
+        },
+        nodeKey: {
+          type: String,
+          default: 'id'
+        }
+        // appendRoot: {
+        //   type: Boolean,
+        //   default: false
+        // },
+      },
+      data() {
+        return {
+          treeList: [],
+          treeLoading: false,
+          parentName: '',
+          parentId: '',
+          currentKey: ''
+        };
+      },
+      mounted() {
+        if (this.init) {
+          this.getTreeData();
+        }
+      },
+      methods: {
+        getInstance() {
+          return this.$refs.tree;
+        },
+        // 获取树结构数据
+        async getTreeData(params = {}) {
+          try {
+            this.treeLoading = true;
+  
+            const data = await getProduceTreeByPid(params);
+            this.treeLoading = false;
+            this.$emit('setRootId', data[0].id);
+              this.treeList = this.$util.toTreeData({
+              data: data || [],
+              idField: 'id',
+              parentIdField: 'parentId'
+            });
+            this.$nextTick(() => {
+                // 默认高亮第一级树节点
+                if (this.treeList[0]&&this.isFirstRefreshTable) {
+                  this.setCurrentKey(this.treeList[0].id);
+                  this.handleNodeClick(
+                    this.treeList[0],
+                    this.$refs.tree.getCurrentNode()
+                  );
+                }
+              });
+              return this.treeList;
+          } catch (error) {
+            console.error(error);
+          }
+          this.treeLoading = false;
+        },
+        // 递归 - 往树children里面添加parentName
+        // _setParentName (tree) {
+        //   let data = tree;
+        //   for (let i = 0; i < data.length; i++) {
+        //     if (data[i].parentId === '0') {
+        //       this.parentName = data[i].name;
+        //       originId = data[i].id;
+        //       originType = data[i].type;
+        //     }
+  
+        //     data[i]['originId'] = originId;
+        //     data[i]['originType'] = originType;
+        //     data[i]['parentId'] = data[i]['parentId'];
+        //     if (data[i].children && data[i].children.length > 0) {
+        //       this._setParentName(data[i].children);
+        //     }
+        //   }
+        //   return data;
+        // },
+  
+        handleNodeClick(data, node) {
+          this.$emit('handleNodeClick', data, node);
+        },
+        // 设置默认高亮行
+        setCurrentKey(id) {
+          this.currentKey = id;
+          this.$refs.tree.setCurrentKey(this.currentKey);
+        },
+  
+        // 获取树的选中状态
+        getSelectList() {
+          const selectList = this.$refs.tree.getCurrentNode();
+          return selectList;
+        }
+      }
+    };
+  </script>
+  
+  <style lang="scss" scoped>
+    .tree-wrapper {
+      width: 100%;
+      height: 100%;
+      overflow: auto;
+  
+      :deep(.el-tree) {
+        display: inline-block;
+        min-width: 100%;
+      }
+    }
+  </style>
+  

+ 1 - 0
src/enum/dict.js

@@ -24,6 +24,7 @@ export default {
   商机来源:'business_opport_code',
   影响力:'influence_level_code',
   态度:'attittude_code',
+  质保期单位:'date_unit',
   商机阶段:'business_stage_code',
   客户联系人状态: 'contact_link_status'
 };

+ 2 - 0
src/utils/request.js

@@ -13,6 +13,7 @@ const service = axios.create({
   baseURL: API_BASE_URL,
   transformResponse: [
     function (data) {
+ 
       if (data instanceof Blob) {
         return data;
       }
@@ -57,6 +58,7 @@ service.interceptors.response.use(
     return res;
   },
   (error) => {
+    console.log(error,'77777777777')
     // 登录过期处理
     if (error?.response?.status === 401) {
       const currentPath = router.currentRoute.path;

+ 6 - 18
src/views/saleManage/businessOpportunity/components/addOpportunityDialog.vue

@@ -9,11 +9,8 @@
     width="80%"
     @close="cancel"
   >
-  <el-card
-        shadow="never"
-        header="基本信息"
-        body-style="padding: 22px 20px 0 0;"
-      >
+ 
+      <headerTitle title="基本信息"></headerTitle>
   <el-form
           label-width="120px"
           ref="form"
@@ -93,30 +90,21 @@
             </el-col>
           </el-row>
         </el-form>
-      </el-card>
-      <el-card
-        shadow="never"
-        header="竞品"
-        body-style="padding: 22px 20px 0 20px;"
-      >
+     
+      <headerTitle title="竞品"></headerTitle>
         <businessAddTable
           ref="businessAddTable"
           @timeAll="getDetailTable"
           :delDetailIds="delDetailIds"
         ></businessAddTable>
-      </el-card>
-      <el-card
-        shadow="never"
-        header="关键人信息"
-        body-style="padding: 22px 20px 0 20px;"
-      >
+      
+      <headerTitle title="关键人信息"></headerTitle>
         <personnelAddTable
           ref="personnelAddTable"
           :contactId="form.contactId"
           @timeAll="getPersonnelAddTable"
           :delDetailIds="PersonnelDetailIds"
         ></personnelAddTable>
-      </el-card>
     <div slot="footer" class="footer">
       <el-button type="primary" @click="save">保存</el-button>
       <el-button @click="cancel">返回</el-button>

+ 5 - 4
src/views/saleManage/businessOpportunity/components/headList.vue

@@ -45,6 +45,7 @@ export default {
  
     data() {
         return {
+            currentIndex:0,
             visible: false,
             statusOptions: [
           { value: 1, label: '全职' },
@@ -127,11 +128,11 @@ export default {
 
     },
     methods: {
-        open(item) {
+        open(item,index=0) {
             if (item) {
-
                 this.radio = item.id
             }
+            this.currentIndex=index
             this.visible = true
         },
 
@@ -170,9 +171,9 @@ export default {
 
         selected() {
             if (!this.current) {
-                return this.$message.warning('请选择上级客户')
+                return this.$message.warning('请至少选择一项')
             }
-            this.$emit('changeParent', this.current)
+            this.$emit('changeParent', this.current,this.currentIndex)
             this.handleClose()
         },
 

+ 2 - 2
src/views/saleManage/contact/components/parentList.vue

@@ -1,5 +1,5 @@
 <template>
-    <el-dialog title="选择客户" :visible.sync="visible" :before-close="handleClose" :close-on-click-modal="false" top="5vh"
+    <el-dialog title="选择客户"  custom-class="ele-dialog-form long-dialog-form" :visible.sync="visible" :before-close="handleClose" :close-on-click-modal="false" top="5vh"
         :close-on-press-escape="false" append-to-body width="80%">
         <el-card shadow="never">
 
@@ -29,7 +29,7 @@
 
         </el-card>
 
-        <div class="btns">
+        <div class="btns" slot="footer">
             <el-button type="primary" size="small" @click="selected">选择</el-button>
             <el-button size="small" @click="handleClose">关闭</el-button>
         </div>

+ 298 - 143
src/views/saleManage/quotation/components/addDialog.vue

@@ -9,15 +9,12 @@
     width="80%"
     @close="cancel"
   >
-
+  
   <el-form ref="form" :model="form" :rules="rules" label-width="120px">
-      <el-card
-        shadow="never"
-        header="基本信息"
-        body-style="padding: 22px 20px 0 0;"
-      >
+     
+      <headerTitle title="基本信息"></headerTitle>
         <el-row>
-          <el-col :span="6">
+          <el-col :span="12">
             <el-form-item
               label="询价方名称"
               prop="contactName"
@@ -26,42 +23,24 @@
               <el-input
                 clearable
                 v-model="form.contactName"
+                @click.native="handParent"
                 placeholder="请输入"
               />
             </el-form-item>
-            <el-form-item prop="businessLicenseFiles" label="询价单附件">
-                <fileUpload
-                  v-model="form.businessLicenseFiles"
-                  module="main"
-                  :showLib="false"
-                  :limit="1"
-                />
-              </el-form-item>
-              <el-form-item prop="deliveryDate" label="交货日期">
-                <el-date-picker
-                v-model="form.deliveryDate"
-                  value-format="yyyy-MM-dd"
-                  placeholder="交货日期"
-                  type="date"
-                  class="filter-item"
-                ></el-date-picker>
-              </el-form-item>
-              <el-form-item prop="quoteFax" label="报价方传真">
-                <el-input
-                clearable
-                v-model="form.quoteFax"
-                placeholder="请输入"
-              />
-              </el-form-item>
-              <el-form-item prop="quoteTel" label="报价方联系电话">
-                <el-input
-                clearable
-                v-model="form.quoteTel"
-                placeholder="请输入"
-              />
-              </el-form-item>
-          </el-col>
-          <el-col :span="6">
+            <el-form-item
+              label="询价方联系人"
+              prop="contactLinkName"
+              style="margin-bottom: 22px"
+            >
+            <el-select v-model="form.contactLinkName" placeholder="请选择"  @change="onchangeLink" @focus="selectFocus" >
+                 <el-option
+                   v-for="item in linkNameOptions"
+                   :key="item.id"
+                   :label="item.linkName"
+                   :value="item.id">
+                 </el-option>
+               </el-select>
+            </el-form-item>
             <el-form-item
               label="询价方电话"
               prop="contactTel"
@@ -75,74 +54,65 @@
               />
             </el-form-item>
             <el-form-item
-              label="询价方地址"
-              prop="contactAddress"
+              label="询价方传真"
+              prop="contactFax"
               style="margin-bottom: 22px"
             >
               <el-input
                 clearable
-                v-model="form.contactAddress"
+                v-model="form.contactFax"
                 placeholder="请输入"
               />
             </el-form-item>
             <el-form-item
-              label="付款方式"
-              prop="payWay"
-              style="margin-bottom: 22px"
-            >
-            <DictSelection dictName="付款方式" clearable v-model="form.payWay">
-                </DictSelection>
-            </el-form-item>
-            <el-form-item prop="taxRate" label="税率">
-                <el-input
-                clearable
-                v-model="form.taxRate"
-                placeholder="请输入"
-              />
-              </el-form-item>
-              <el-form-item prop="totalPrice" label="总金额">
-                <el-input
-                clearable
-                v-model="form.totalPrice"
-                placeholder="请输入"
-              />
-              </el-form-item>
-          </el-col>
-          <el-col :span="6">
-            <el-form-item
-              label="询价方联系人"
-              prop="contactLinkName"
+              label="	询价方Email"
+              prop="contactEmail"
               style="margin-bottom: 22px"
             >
               <el-input
                 clearable
-                :maxlength="20"
-                v-model="form.contactLinkName"
+                v-model="form.contactEmail"
                 placeholder="请输入"
               />
             </el-form-item>
             <el-form-item
-              label="	询价方email"
-              prop="contactEmail"
+              label="询价方地址"
+              prop="contactAddress"
               style="margin-bottom: 22px"
             >
               <el-input
                 clearable
-                v-model="form.contactEmail"
+                v-model="form.contactAddress"
                 placeholder="请输入"
               />
             </el-form-item>
+          <el-form-item prop="askFile" label="询价单附件">
+                <fileUpload
+                  v-model="form.askFile"
+                  module="main"
+                  :showLib="false"
+                  :limit="1"
+                />
+              </el-form-item>
+          
+          </el-col>
+
+
+
+
+          <el-col :span="12">
             <el-form-item
-              label="报价方地址"
-              prop="quoteAddress"
+              label="报价方名称"
+              prop="quoteName"
               style="margin-bottom: 22px"
             >
               <el-input
                 clearable
-                v-model="form.quoteAddress"
+                v-model="form.quoteName"
                 placeholder="请输入"
               />
             </el-form-item>
+
             <el-form-item
               label="报价方联系人"
               prop="quoteLinkName"
@@ -151,36 +121,27 @@
               <el-input
                 clearable
                 v-model="form.quoteLinkName"
+                @click.native="handHead"
                 placeholder="请输入"
               />
             </el-form-item>
-           
-          </el-col>
-        
-          <el-col :span="6">
-            <el-form-item label="是否接受拆单" prop="acceptUnpack" style="margin-bottom: 22px">
-              <el-select v-model="form.acceptUnpack" placeholder="请选择">
-               <el-option
-                 v-for="item in acceptUnpackoptions"
-                 :key="item.value"
-                 :label="item.label"
-                 :value="item.value">
-               </el-option>
-             </el-select>
-            </el-form-item>
-            <el-form-item
-              label="询价方传真"
-              prop="contactFax"
-              style="margin-bottom: 22px"
-            >
-              <el-input
+            <el-form-item prop="quoteTel" label="报价方联系电话">
+                <el-input
                 clearable
-                v-model="form.contactFax"
+                v-model="form.quoteTel"
                 placeholder="请输入"
               />
-            </el-form-item>
-            <el-form-item
-              label="报价方email"
+              </el-form-item>
+              <el-form-item prop="quoteFax" label="报价方传真">
+                <el-input
+                clearable
+                v-model="form.quoteFax"
+                placeholder="请输入"
+              />
+              </el-form-item>
+
+              <el-form-item
+              label="报价方Email"
               prop="quoteEmail"
               style="margin-bottom: 22px"
             >
@@ -190,42 +151,94 @@
                 placeholder="请输入"
               />
             </el-form-item>
+
             <el-form-item
-              label="报价方名称"
-              prop="quoteName"
+              label="报价方地址"
+              prop="quoteAddress"
               style="margin-bottom: 22px"
             >
               <el-input
                 clearable
-                v-model="form.quoteName"
+                v-model="form.quoteAddress"
                 placeholder="请输入"
               />
             </el-form-item>
+
           </el-col>
-         
         </el-row>
-      </el-card>
-      <el-card
-        shadow="never"
-        header="报价单产品清单"
-        body-style="padding: 22px 20px 0 20px;"
-      >
+
+
+
+      
+    
+      <headerTitle title="报价单产品清单"></headerTitle>
         <inventoryTable
           ref="inventoryTable"
           :delDetailIds="delDetailIds"
         ></inventoryTable>
-      </el-card>
+        <el-row style="margin-top:20px">
+          <el-col :span="6">
+            <el-form-item prop="taxRate" label="税率">
+              <el-input
+                clearable
+                v-model="form.taxRate"
+                placeholder="请输入"
+              >
+              <template slot="append">%</template>
+              </el-input>
+              </el-form-item>
+            </el-col>
+          <el-col :span="6">
+            <el-form-item prop="deliveryDate" label="交货日期">
+                <el-date-picker
+                v-model="form.deliveryDate"
+                  value-format="yyyy-MM-dd"
+                  placeholder="交货日期"
+                  type="date"
+                  class="filter-item"
+                ></el-date-picker>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+            <el-form-item
+              label="付款方式"
+              prop="payWay"
+              style="margin-bottom: 22px"
+            >
+            <DictSelection dictName="付款方式" clearable v-model="form.payWay">
+                </DictSelection>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="是否接受拆单" prop="acceptUnpack" style="margin-bottom: 22px">
+              <el-select v-model="form.acceptUnpack" placeholder="请选择">
+               <el-option
+                 v-for="item in acceptUnpackoptions"
+                 :key="item.value"
+                 :label="item.label"
+                 :value="item.value">
+               </el-option>
+             </el-select>
+            </el-form-item>
+           
+          
+          
+          </el-col>
+        </el-row>
     </el-form>
 
     <div slot="footer" class="footer">
       <el-button type="primary" @click="save">保存</el-button>
       <el-button @click="cancel">返回</el-button>
     </div>
+    
     <parentList ref="parentRef" classType="1" @changeParent="changeParent"></parentList>
+    <head-list ref="headRef"  @changeParent="changePersonel"></head-list>
   </ele-modal>
 </template>
 
 <script>
+import { emailReg, phoneReg,numberReg } from 'ele-admin';
 import {acceptUnpackoptions} from '@/enum/dict';
 import inventoryTable from './inventoryTable.vue'
 import {categoryData} from 'element-china-category-data';
@@ -234,9 +247,10 @@ import {cityData} from 'ele-admin/packages/utils/regions';
 import dictMixins from '@/mixins/dictMixins';
 import deptSelect from '@/components/CommomSelect/dept-select.vue';
 import personSelect from '@/components/CommomSelect/person-select.vue';
-import {listOrganizations} from '@/api/system/organization';
 import parentList from '@/views/saleManage/contact/components/parentList.vue'
-import { getDetail, UpdateInformation, addInformation,deleteInformation,updateStatus} from '@/api/saleManage/businessOpportunity';
+import { getDetail, UpdateInformation, addInformation,deleteInformation,updateStatus} from '@/api/saleManage/quotation';
+import {getcontactlink} from '@/api/saleManage/businessFollow';
+import headList from '@/views/saleManage/businessOpportunity/components/headList.vue'
 import {copyObj} from '@/utils/util';
 
 
@@ -247,6 +261,7 @@ export default {
     mixins: [dictMixins],
     components: {
       fileUpload,
+      headList,
       inventoryTable,
       deptSelect,
       parentList,
@@ -255,19 +270,34 @@ export default {
     data() {
       let formDef = {
           id:'',
-          contactName: '',
-          contactId: 0,
-          name: '',
-          remark: '',
-          responsibleName: '',
-          responsibleId: '',
-          source: '',
-          status: 1
+          acceptUnpack: null,
+          askFile: null,
+          contactAddress: '',
+          contactEmail: '',
+          contactFax: '',
+          contactId: '',
+          contactLinkId: '',
+          contactLinkName: '',
+          contactName:'',
+          contactTel:'',
+          deliveryDate:'',
+          payWay:'',
+          payWayName:'',
+          quoteAddress:'',
+          quoteEmail:'',
+          quoteFax:'',
+          quoteLinkId:'',
+          quoteLinkName:'',
+          quoteName:'',
+          quoteTel:'',
+          taxRate:null,
+          totalPrice:null
         };
    
       return {
         payWayOptions:[],
         delDetailIds:[],
+        linkNameOptions:[],
         acceptUnpackoptions,
         visible: false,
         title: '',
@@ -287,8 +317,41 @@ export default {
           name: [
             { required: true, message: '请输入客户名称', trigger: 'blur' }
           ],
-          responsibleName: [
-            { required: true, message: '请选择负责人', trigger: 'change' }
+          contactLinkName: [
+            { required: true, message: '请选择联系人', trigger: 'change' }
+          ],
+          acceptUnpack: [
+            { required: true, message: '请选择是否接受', trigger: 'change' }
+          ],
+          contactTel: [
+            { required: true,pattern:numberReg,  message: '请输入联系电话', trigger: 'blur' }
+          ],
+          deliveryDate: [
+            { required: true, message: '请选择交货日期', trigger: 'change' }
+          ],
+          payWay: [
+            { required: true, message: '请选择付款方式', trigger: 'change' }
+          ],
+          payWayName: [
+            { required: true, message: '请输入报价方名称', trigger: 'blur' }
+          ],
+          quoteLinkName: [
+            { required: true, message: '请输入报价方联系人', trigger: 'change' }
+          ],
+          quoteName: [
+            { required: true, message: '请输入报价方名称', trigger: 'blur' }
+          ],
+          quoteTel: [
+            { required: true,pattern:numberReg, message: '请输入报价方联系电话', trigger: 'blur' }
+          ],
+          quoteEmail: [
+            { pattern: emailReg, message: '邮箱格式不正确', trigger: 'blur' }
+          ],
+          contactEmail: [
+            { pattern: emailReg, message: '邮箱格式不正确', trigger: 'blur' }
+          ],
+          taxRate: [
+            { pattern: numberReg, message: '请输入数字', trigger: 'blur' }
           ]
         },
       
@@ -309,30 +372,83 @@ export default {
     },
   
     methods: {
-   
-      //选择客户回调
-      changeParent(obj) {
-        this.$set( this.form, 'contactId',  obj.id)
-        this.$set( this.form, 'contactName',  obj.name)
 
+      //获取详情
+      async getDetailData (id) {
+        this.loading = true;
+        const data = await getDetail(id);
+        this.loading = false;
+        if (data) {
+          this.$nextTick(()=>{
+            this.form = data;
+            if(data.askFile !== ""){
+              this.$set(this.form,'askFile',[data?.askFile])
+           }
+            this.$refs.inventoryTable&&this.$refs.inventoryTable.putTableValue(data.quoteProductList)
+            this.getLinkInfo(data.contactId)
+          })
+          
+          
+        }
+      },
+
+   //更新联系人数据
+   async getLinkInfo(contactId) {
+      const data = await getcontactlink({contactId});
+         if(data&&data?.length){
+           this.linkNameOptions=data
+         }
+    },
+  
+    selectFocus(){
+   if(this.linkNameOptions.length===0){
+    return this.$message.error('请先选择名称')
+   }
+    },
+    //选择下拉框
+    onchangeLink(selectedOptions){
+      const option = this.linkNameOptions.find(opt => opt.id === selectedOptions);
+    this.form=Object.assign({},this.form,{
+      contactEmail:option?.email,
+      contactLinkName:option?.linkName||'',
+      contactTel:option?.mobilePhone||option?.phone||'',
+      contactLinkId:option?.id})
+    },
+    handHead(){
+        let item={
+          id:this.form.quoteLinkId
+        }
+        this.$refs.headRef.open(item)
+      },
+    //选择报价方人回调
+   changePersonel(obj) {
+        this.$set( this.form, 'quoteLinkId',  obj.id)
+        this.$set(this.form, 'quoteLinkName',  obj.name)
+        this.$set(this.form, 'quoteTel',  obj.phone)
+        this.$set(this.form, 'quoteEmail',  obj.email)
       },
-      //选择负责人回调
-      changeHead(obj) {
-        this.$set( this.form, 'responsibleId',  obj.id)
-        this.$set( this.form, 'responsibleName',  obj.name)
+      //选择客户回调
+      changeParent(obj) {
+        this.form = Object.assign({},this.form,{
+         contactId: obj.id,
+         contactName: obj.name,
+         contactAddress: obj.addressName + obj.address,
+         contactLinkId:'',
+         contactLinkName:'',
+         contactEmail:'',
+         contactTel:''
+        })
+      this.getLinkInfo(obj.id)
       },
+    
+      
       handParent() {
         let item = {
           id:  this.form.contactId
         }
         this.$refs.parentRef.open(item)
       },
-      handHead(){
-        let item = {
-          id:  this.form.responsibleId
-        }
-        this.$refs.headRef.open(item)
-      },
+    
       async open(type, row, contactCategoryId) {
         this.title = type==='add'?'新增':'修改';
         this.row = row;
@@ -341,7 +457,7 @@ export default {
           this.isUpdate = false;
         } else {
           this.isUpdate = true;
-          this.form=row
+          this.getDetailData(row.id)
         }
       },
 
@@ -370,6 +486,30 @@ export default {
                 }
               });
             })
+     },
+     getValidate() {
+        return Promise.all([
+            new Promise((resolve, reject) => {
+              this.$refs.form.validate((valid) => {
+                if (!valid) {
+                  reject(false);
+                } else {
+                  resolve(true);
+                }
+              });
+            }),
+            new Promise((resolve, reject) => {
+              this.$refs.inventoryTable.validateForm((valid) => {
+                if (!valid) {
+                  reject(false);
+                } else {
+                  resolve(true);
+                }
+              });
+            }),
+         
+          
+          ]);
      },
       async save() {
         try {
@@ -380,9 +520,18 @@ export default {
         if (!this.isUpdate) {
           delete this.form.id;
         } 
-       
+        let payWayName=this.getDictValue('付款方式', this.form.payWay);
+
+        if(this.form.askFile && this.form.askFile.length > 0){
+          this.form.askFile = this.form.askFile[0];
+        } else {
+          this.form.askFile = null;
+        }
+        let commitData=Object.assign({},this.form,{payWayName,
+          quoteProductList:this.$refs.inventoryTable.getTableValue(),
+          totalPrice:this.$refs.inventoryTable.getTotalPrice()})
         if (this.isUpdate) {
-          UpdateInformation(this.form)
+          UpdateInformation(commitData)
             .then((res) => {
               this.loading = false;
               this.$message.success("修改成功");
@@ -393,7 +542,7 @@ export default {
               //this.loading = false;
             });
         } else {
-          addInformation(this.form)
+          addInformation(commitData)
             .then((res) => {
               this.loading = false;
               this.$message.success("新增成功");
@@ -425,3 +574,9 @@ export default {
     }
   };
 </script>
+<style scoped lang="scss">
+.TotalAmount{
+  font-size: 16px;
+  padding-right: 30px;
+}
+</style>

+ 0 - 216
src/views/saleManage/quotation/components/addFollowDialog.vue

@@ -1,216 +0,0 @@
-
-<template>
-  <div class="container">
-    <!-- 单据弹窗 -->
-    <el-dialog
-      :title="title"
-      :before-close="handleClose"
-      :visible.sync="dialogVisible"
-      :close-on-click-modal="false"
-      :append-to-body="true"
-      width="60%"
-    >
-    <el-form
-          label-width="100px"
-          ref="form"
-          :model="form"
-          :rules="rules"
-          style="margin-top: 30px;padding-right: 20px;"
-        >
-            <el-form-item label="跟进内容" prop="content">
-                <el-input placeholder="请输入" type="textarea" v-model="form.content" maxlength="500"></el-input>
-              </el-form-item>
-              <el-form-item label="达成共识" prop="agreement">
-                <el-input placeholder="请输入" type="textarea" v-model="form.agreement" maxlength="500"></el-input>
-              </el-form-item>
-              <el-form-item label="客户联系人" prop="linkId">
-                <el-select v-model="form.linkId" placeholder="请选择" @change="((value)=>{onchangeLink(value)})" >
-                 <el-option
-                   v-for="item in linkNameOptions"
-                   :key="item.id"
-                   :label="item.linkName"
-                   :value="item.id">
-                 </el-option>
-               </el-select>
-              </el-form-item>
-              <el-form-item label="跟进时间" prop="followupTime">
-                <el-date-picker
-                v-model="form.followupTime"
-                  value-format="yyyy-MM-dd HH:mm:ss"
-                  placeholder="结束时间"
-                  type="datetime"
-                  style="width: 200px"
-                  class="filter-item"
-                ></el-date-picker>
-              </el-form-item>
-              <el-form-item
-                label="下一步计划"
-                prop="nextPlan"
-              >
-              <el-input
-                  placeholder="请输入"
-                  v-model="form.nextPlan"
-                  type="textarea"
-                  maxlength="300"
-                ></el-input>
-              </el-form-item>
-        </el-form>
-
-      <div slot="footer" class="dialog-footer">
-        <el-button size="small" @click="handleClose">关 闭</el-button>
-        <el-button size="small" @click="sumbit" type="primary">确 认</el-button>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-  <script>
-import dictMixins from '@/mixins/dictMixins';
-import {copyObj} from '@/utils/util';
-import { getDetail, UpdateInformation, addInformation,deleteInformation,updateStatus,getcontactlink} from '@/api/saleManage/businessFollow';
-export default {
-  mixins: [dictMixins],
-  data() {
-    let formDef = {
-          agreement:'',
-          contactId:'',
-          content: '',
-          followupTime: '',
-          linkId: '',
-          linkName: '',
-          nextPlan: '',
-          opportunityId: ''
-        };
-   
-    return {
-      dialogVisible: false,
-      currentDetail:{},   //选择的客户信息
-      linkNameOptions:[],
-        title: '',
-        row: {},
-        activeName: 'base',
-        formDef,
-        form: copyObj(formDef),
-        rules: {
-          content: [
-            { required: true, message: '请输入跟进内容', trigger: 'blur' }
-          ],
-          followupTime: [
-            { required: true, message: '请选择跟进时间', trigger: 'change' }
-          ],
-          linkName: [
-            { required: true, message: '请选择客户联系人名称', trigger: 'change' }
-          ]
-        },
-      
-        // 提交状态
-        loading: false,
-        // 是否是修改
-        isUpdate: false,
-    };
-  },
-  created() {},
-  methods: {
-   
-    //更改弹框状态
-    async open(type, row, currentDetail) {
-        this.title = type==='add'?'新增':'修改';
-        this.currentDetail=currentDetail
-        this.row = row;
-        this.dialogVisible = true;
-        this.getInfo()
-        if (type == 'add') {
-          this.isUpdate = false;
-        } else {
-          this.isUpdate = true;
-          this.form=row
-        }
-      },
-
-      //表单验证
-      getValidate() {
-          return  new Promise((resolve, reject) => {
-              this.$refs.form.validate((valid) => {
-                if (!valid) {
-                  reject(false);
-                } else {
-                  resolve(true);
-                }
-              });
-            })
-     },
-
-    //初始数据
-    async getInfo() {
-      const data = await getcontactlink({contactId:this.currentDetail?.contactId});
-         if(data&&data?.length){
-           this.linkNameOptions=data
-         }
-    },
-  
-    //选择下拉框
-    onchangeLink(e){
-     let selectLable=this.linkNameOptions.find(v=>v.id===e).linkName
-     this.form.linkName=selectLable
-    },
-    //保存
-    async sumbit() {
-      try {
-           await this.getValidate();
-           // 表单验证通过,执行保存操作
-           this.loading = true;
-      
-        if (!this.isUpdate) {
-          delete this.form.id;
-        } 
-        let {contactId,id}=this.currentDetail
-        this.form=Object.assign({},this.form,{contactId:contactId,opportunityId:id})
-        if (this.isUpdate) {
-          UpdateInformation(this.form)
-            .then((res) => {
-              this.loading = false;
-              this.$message.success("修改成功");
-              this.cancel();
-              this.$emit('done');
-            })
-            .catch((e) => {
-              //this.loading = false;
-            });
-        } else {
-          addInformation(this.form)
-            .then((res) => {
-              this.loading = false;
-              this.$message.success("新增成功");
-              this.cancel();
-              this.$emit('done');
-            })
-            .catch((e) => {
-              //this.loading = false;
-            });
-          }
-        } catch (error) {
-          console.log(error)
-          // 表单验证未通过,不执行保存操作
-        }
-       
-    },
-    cancel() {
-        this.$nextTick(() => {
-          // 关闭后,销毁所有的表单数据
-          this.$refs['form'] &&  this.$refs['form'].resetFields();
-          this.form = copyObj(this.formDef),
-          this.dialogVisible = false;
-        })
-      },
-    handleClose() {
-    this.cancel()
-      
-    }
-  }
-};
-</script>
-
-  <style lang='scss' scoped>
-.container {
-  padding: 10px 0;
-}
-</style>

+ 0 - 137
src/views/saleManage/quotation/components/contactDetailDialog.vue

@@ -1,137 +0,0 @@
-<template>
-  <ele-modal
-    custom-class="ele-dialog-form"
-    v-if="visible"
-    :visible.sync="visible"
-    :title="title"
-    :close-on-click-modal="false"
-    width="80%"
-    @close="cancel"
-  >
-      <el-form
-          label-width="160px"
-          ref="formRef"
-          :model="form"
-          style="margin-top: 30px"
-        >
-          <el-row>
-            <el-col :span="8">
-              <el-form-item
-                label="客户名称:"
-                prop="contactName"
-              >
-                {{form.contactName}}
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="商机名称:" prop="name">
-                {{form.name}}
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="负责人名称:" prop="responsibleName">
-                {{form.responsibleName}}
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="商机来源:" prop="source">
-                {{form.source}}
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="状态:" prop="status">
-                {{ form.status === 1 ? "有效" : "失效"}}
-              </el-form-item>
-            </el-col>
-          
-            <el-col :span="16">
-              <el-form-item label="备注:" prop="remark">
-                {{form.remark}}
-              </el-form-item>
-            </el-col>
-          </el-row>
-        </el-form>
-
-    <div slot="footer" class="footer">
-      <el-button @click="cancel">返回</el-button>
-    </div>
-  </ele-modal>
-</template>
-
-<script>
-import {contactDetail} from '@/api/saleManage/contact';
-import {getFile} from '@/api/system/file';
-import {getInfoById as getCategoryInfo} from '@/api/classifyManage/index';
-import fileUpload from '@/components/upload/fileUpload';
-import dictMixins from '@/mixins/dictMixins';
-import deptSelect from '@/components/CommomSelect/dept-select.vue';
-import personSelect from '@/components/CommomSelect/person-select.vue';
-import {copyObj} from '@/utils/util';
-
-
-export default {
-    props: {
-      categoryTreeList: Array
-    },
-    mixins: [dictMixins],
-    components: {
-      fileUpload,
-      deptSelect,
-      personSelect
-    },
-    data() {
-      let formDef = {
-        id:'',
-          contactName: '',
-          contactId: 0,
-          name: '',
-          remark: '',
-          responsibleName: '',
-          responsibleId: '',
-          source: '',
-          status: 1
-        };
-    
-      return {
-        visible: false,
-        title: '详情',
-        row: {},
-        activeName: 'base',
-        formDef,
-        form: copyObj(formDef),
-        tableBankData: [],
-        tableLinkData: [],
-        ifChiefList: [
-          {
-            value: 0,
-            label: '否'
-          },
-          {
-            value: 1,
-            label: '是'
-          }
-        ],
-      };
-    },
-    methods: {
-      async open(row) {
-        this.form = row;
-        this.visible = true;
-      },
-
-      cancel() {
-        this.$nextTick(() => {
-          // 关闭后,销毁所有的表单数据
-          this.form = copyObj(this.formDef),
-          this.otherForm = copyObj(this.otherFormDef),
-          this.tableBankData = []
-          this.tableLinkData = []
-          this.visible = false;
-        })
-      },
-
-   
-
-    }
-  };
-</script>

+ 383 - 0
src/views/saleManage/quotation/components/detailDialog.vue

@@ -0,0 +1,383 @@
+<template>
+    <ele-modal
+    custom-class="ele-dialog-form long-dialog-form"
+      :centered="true"
+      v-if="visible"
+      :visible.sync="visible"
+      :title="title"
+      :close-on-click-modal="false"
+      width="80%"
+      @close="cancel"
+    >
+ 
+        <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+         
+     <headerTitle title="基本信息">
+      <el-button
+                  size="small"
+                  type="primary"
+                  icon="el-icon-s-grid"
+                  class="ele-btn-icon"
+                  @click="exportTable"
+                >
+                 导出
+                </el-button>
+     </headerTitle>
+       <el-row>
+         <el-col :span="12">
+           <el-form-item
+             label="询价方名称"
+             prop="contactName"
+             style="margin-bottom: 22px"
+           >
+           {{form.categoryName}}
+           </el-form-item>
+           <el-form-item
+             label="询价方联系人"
+             prop="contactLinkName"
+             style="margin-bottom: 22px"
+           >
+           {{form.contactLinkName}}
+           </el-form-item>
+           <el-form-item
+             label="询价方电话"
+             prop="contactTel"
+             style="margin-bottom: 22px"
+           >
+           {{form.contactTel}}
+           </el-form-item>
+           <el-form-item
+             label="询价方传真"
+             prop="contactFax"
+             style="margin-bottom: 22px"
+           >
+           {{form.contactFax}}
+           </el-form-item>
+           <el-form-item
+             label="询价方Email"
+             prop="contactEmail"
+             style="margin-bottom: 22px"
+           >
+           {{form.contactEmail}}
+           </el-form-item>
+           <el-form-item
+             label="询价方地址"
+             prop="contactAddress"
+             style="margin-bottom: 22px"
+           >
+           {{form.contactAddress}}
+           </el-form-item>
+         <el-form-item prop="askFile" label="询价单附件">
+          <el-link v-if="form.askFile && form.askFile !== ''"
+                         type="primary" :underline="false"
+                         @click="downloadFile(form.askFile)"> {{ form.askFile.name }}</el-link>
+             </el-form-item>
+         
+         </el-col>
+         <el-col :span="12">
+           <el-form-item
+             label="报价方名称"
+             prop="quoteName"
+             style="margin-bottom: 22px"
+           >
+           {{form.quoteName}}
+           </el-form-item>
+
+           <el-form-item
+             label="报价方联系人"
+             prop="quoteLinkName"
+             style="margin-bottom: 22px"
+           >
+           {{form.quoteLinkName}}
+           </el-form-item>
+           <el-form-item prop="quoteTel" label="报价方联系电话">
+            {{form.quoteTel}}
+             </el-form-item>
+             <el-form-item prop="quoteFax" label="报价方传真">
+              {{form.quoteFax}}
+             </el-form-item>
+
+             <el-form-item
+             label="报价方Email"
+             prop="quoteEmail"
+             style="margin-bottom: 22px"
+           >
+           {{form.quoteEmail}}
+           </el-form-item>
+
+           <el-form-item
+             label="报价方地址"
+             prop="quoteAddress"
+             style="margin-bottom: 22px"
+           >
+           {{form.quoteAddress}}
+           </el-form-item>
+
+         </el-col>
+       </el-row>
+
+
+
+     
+   
+    
+       <el-row style="margin-top:20px">
+         <el-col :span="6">
+           <el-form-item prop="taxRate" label="税率">
+            {{form.taxRate}}%
+             </el-form-item>
+           </el-col>
+         <el-col :span="6">
+           <el-form-item prop="deliveryDate" label="交货日期">
+            {{form.deliveryDate?.substr(0,10)}}
+             </el-form-item>
+           </el-col>
+           <el-col :span="6">
+           <el-form-item
+             label="付款方式"
+             prop="payWay"
+             style="margin-bottom: 22px"
+           >
+           {{form.payWayName}}
+           </el-form-item>
+         </el-col>
+         <el-col :span="6">
+           <el-form-item label="是否接受拆单" prop="acceptUnpack" style="margin-bottom: 22px">
+            {{form.acceptUnpack==1?'接受':'不接受'}}
+           </el-form-item>
+         </el-col>
+       </el-row>
+   </el-form>
+
+
+       
+        <headerTitle title="报价单产品清单"></headerTitle>
+        <ele-pro-table ref="table" :needPage="false" :columns="competAnalysisListcolumns"  :toolkit="[]" :datasource="detailData.quoteProductList" row-key="id">
+          <template v-slot:toolbar>
+        <div class="headbox">
+        <span class="amount">总计:{{form.totalPrice}}元</span>
+       
+      </div>
+      </template>
+          <template v-slot:technicalDrawings="{ row }">
+            <div v-if="row.technicalDrawings && row.technicalDrawings?.length">
+            <el-link 
+            v-for="link in row.technicalDrawings" :key="link.id"
+                         type="primary" :underline="false"
+                         @click="downloadFile(link)"> {{ link.name }}</el-link>
+                        </div>
+                        </template>
+                     
+          </ele-pro-table>
+       
+      <div slot="footer" class="footer">
+        <el-button @click="cancel">返回</el-button>
+      </div>
+    </ele-modal>
+  </template>
+  
+  <script>
+  import { getDetail,getExport} from '@/api/saleManage/quotation';
+  import {getFile} from '@/api/system/file';
+  import dictMixins from '@/mixins/dictMixins';
+  import {download } from '@/utils/file';
+  import {copyObj} from '@/utils/util';
+  
+  
+  export default {
+      mixins: [dictMixins],
+      data() {
+      
+        return {
+          visible: false,
+          detailId:'',
+          title: '详情',
+          row: {},
+          activeName: 'base',
+          form:{},
+          rules:{},
+          detailData:{},
+          competAnalysisListcolumns: [
+        
+          {
+          width: 45,
+          type: 'index',
+          columnKey: 'index',
+          align: 'center',
+          fixed: 'left'
+        },
+        {
+          width: 200,
+          prop: 'productName',
+          label: '名称',
+          slot: 'productName'
+        },
+        {
+          width: 120,
+          prop: 'productCode',
+          label: '编码',
+          slot: 'productCode'
+        },
+        {
+          width: 200,
+          prop: 'productCategoryName',
+          label: '类型',
+          slot: 'productCategoryName'
+        },
+        {
+          width: 160,
+          prop: 'productBrand',
+          label: '牌号',
+          slot: 'productBrand'
+        },
+        {
+          width: 120,
+          prop: 'modelType',
+          label: '型号',
+          slot: 'modelType'
+        },
+        {
+          width: 120,
+          prop: 'specification',
+          label: '规格',
+          slot: 'specification'
+        },
+       
+        {
+          width: 160,
+          prop: 'singlePrice',
+          label: '单价',
+          slot: 'singlePrice'
+        },
+        {
+          width: 120,
+          prop: 'totalCount',
+          label: '数量',
+          slot: 'totalCount'
+        },
+        {
+          width: 120,
+          prop: 'totalPrice',
+          label: '销售总金额',
+          slot: 'totalPrice',
+          formatter: (_row, _column, cellValue) => {
+              return _row.totalPrice+'元'
+            }
+        },
+        {
+          width: 120,
+          prop: 'measuringUnit',
+          label: '计量单位',
+          slot: 'measuringUnit'
+        },
+        {
+          width: 120,
+          prop: 'deliveryDays',
+          label: '交期(天)',
+          slot: 'deliveryDays'
+        },
+        {
+          width: 200,
+          prop: 'guaranteePeriod',
+          label: '质保期',
+          slot: 'guaranteePeriod',
+          formatter: (_row, _column, cellValue) => {
+              return _row.guaranteePeriod+_row.guaranteePeriodUnitName
+            }
+        },
+        // {
+        //   width: 120,
+        //   prop: 'guaranteePeriodUnitCode',
+        //   label: '',
+        //   slot: 'guaranteePeriodUnitCode'
+        // },
+         {
+          width: 120,
+          prop: 'technicalAnswerName',
+          label: '技术答疑人',
+          slot: 'technicalAnswerName'
+        },
+        {
+          width: 220,
+          prop: 'technicalParams',
+          label: '技术参数',
+          slot: 'technicalParams'
+        },
+        {
+          width:240,
+          prop: 'technicalDrawings',
+          label: '技术图纸',
+          slot: 'technicalDrawings',
+          formatter: (_row, _column, cellValue) => {
+              return _row.guaranteePeriod+_row.guaranteePeriodUnitName
+            }
+
+        },
+        {
+          width: 220,
+          prop: 'remark',
+          label: '备注',
+          slot: 'remark'
+        }
+           ],
+        };
+      },
+      methods: {
+         //导出
+       async exportTable(){
+        this.loading = true;
+          const response = await getExport(this.detailId);
+         
+     },
+        async open(row) {
+          this.form = row;
+          this.visible = true;
+          this.getDetailData(row.id)
+          this.detailId=row.id
+        },
+  
+        cancel() {
+          this.$nextTick(() => {
+            // 关闭后,销毁所有的表单数据
+            this.form = copyObj(this.formDef),
+            this.otherForm = copyObj(this.otherFormDef),
+            this.tableBankData = []
+            this.tableLinkData = []
+            this.visible = false;
+          })
+        },
+        downloadFile(file){
+        getFile({ objectName: file.storePath }, file.name);
+      },
+        async getDetailData (id) {
+          this.loading = true;
+          const data = await getDetail(id);
+          this.loading = false;
+          if (data) {
+            this.detailData = data;
+            
+          }
+        },
+  
+      }
+    };
+  </script>
+  
+  <style scoped lang="scss">
+  .ele-dialog-form{
+    .el-form-item{
+      margin-bottom: 10px;
+    }
+  }
+
+  .headbox{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  .amount{
+    font-size: 14px;
+    font-weight: bold;
+  }
+}
+  </style>
+  

+ 0 - 278
src/views/saleManage/quotation/components/follow-list.vue

@@ -1,278 +0,0 @@
-<template>
-    <el-dialog title="跟进列表" :visible.sync="visible" :before-close="handleClose" :multiple="true" :centered="false" :close-on-click-modal="false"  top="2vh"
-        :close-on-press-escape="false" append-to-body width="80%">
-        <el-card shadow="never">
-            <ele-pro-table ref="table" :columns="columns" :datasource="datasource" row-key="id"
-            :selection.sync="selection"
-                        height="calc(100vh - 350px)" class="dict-table" @cell-click="cellClick">
-                         <!-- 表头工具栏 -->
-              <template v-slot:toolbar>
-                <el-button
-                  size="small"
-                  type="primary"
-                  icon="el-icon-plus"
-                  class="ele-btn-icon"
-                  @click="openEdit('add',{})"
-                >
-                  新建
-                </el-button>
-                <el-button
-                  size="small"
-                  type="danger"
-                  el-icon-delete
-                  class="ele-btn-icon"
-                  @click="allDelBtn"
-                  :disabled="selection?.length===0"
-                >
-                  批量删除
-                </el-button>
-              </template>
-              <template v-slot:content="{ row }">
-                <el-link type="primary" :underline="false" @click="openDetail(row)"> {{ row.content }}</el-link>
-              </template>
-                          <!-- 操作列 -->
-              <template v-slot:action="{ row }">
-              
-                <el-link
-                  type="primary"
-                  :underline="false"
-                  icon="el-icon-edit"
-                  @click="openEdit('edit',row)"
-                >
-                  修改
-                </el-link>
-               
-
-                <el-popconfirm
-                  class="ele-action"
-                  title="确定要删除此信息吗?"
-                  @confirm="remove(row)"
-                >
-                  <template v-slot:reference>
-                    <el-link
-                      type="danger"
-                      :underline="false"
-                      icon="el-icon-delete"
-                    >
-                      删除
-                    </el-link>
-                  </template>
-                </el-popconfirm>
-              </template>
-                    </ele-pro-table>
-        </el-card>
-        <AddFollowDialog ref="addFollowDialogRef" @done="reload" ></AddFollowDialog>
-        <followDetailDialog ref="contactDetailDialogRef"></followDetailDialog>
-     <!-- 多选删除弹窗 -->
-    <pop-el-modal :popVisible.sync="delVisible" content="是否确定删除?" @done="commitBtn"/>
-  </el-dialog>
-</template>
-  
-<script>
-import AddFollowDialog from './addFollowDialog.vue';
-import popElModal from '@/components/pop-el-modal';
-import followDetailDialog from './followDetailDialog.vue';
-import { getTableList,deleteInformation } from '@/api/saleManage/businessFollow';
-export default {
-    components: {
-        AddFollowDialog,
-        followDetailDialog,
-        popElModal
-    },
-    data() {
-        return {
-            selection:[],
-            current:{},    //当前选择的信息
-            visible: false,
-            delVisible:false,
-             columns: [
-              {
-                width: 45,
-                type: 'selection',
-                columnKey: 'selection',
-               align: 'center'
-              },
-              {
-                  columnKey: 'index',
-                  label: '序号',
-                  type: 'index',
-                  width: 55,
-                  align: 'center',
-                  showOverflowTooltip: true,
-                  fixed: 'left'
-              },
-              {
-                prop: 'content',
-                label: '跟进内容',
-                slot: 'content',
-                showOverflowTooltip: true,
-                minWidth: 200
-              },
-              {
-                prop: 'agreement',
-                label: '达成共识',
-                showOverflowTooltip: true,
-                minWidth: 110
-              },
-              {
-                prop: 'linkName',
-                label: '客户联系人名称',
-                showOverflowTooltip: true,
-                minWidth: 110
-              },
-              {
-                prop: 'nextPlan',
-                label: '下一步计划',
-                showOverflowTooltip: true,
-                minWidth: 110
-              },
-              {
-                prop: 'followupTime',
-                label: '跟进时间',
-                align: 'center',
-                showOverflowTooltip: true,
-                minWidth: 110,
-                formatter: (_row, _column, cellValue) => {
-                  return this.$util.toDateString(cellValue);
-                }
-              },
-              {
-                prop: 'createTime',
-                label: '创建时间',
-                align: 'center',
-                showOverflowTooltip: true,
-                minWidth: 110,
-                formatter: (_row, _column, cellValue) => {
-                  return this.$util.toDateString(cellValue);
-                }
-              },
-              {
-            columnKey: 'action',
-            label: '操作',
-            width: 230,
-            align: 'center',
-            resizable: false,
-            slot: 'action',
-            showOverflowTooltip: true,
-            fixed: 'right',
-          }
-            ],
-
-            radio: null,
-        }
-    },
-
-    watch: {
-        visible(visible) {
-            if(visible){
-                this.$nextTick(()=>{
-                   this.reload();
-                })
-                
-            }
-        }
-    },
-    methods: {
-        open(item) {
-            if (item) {
-              this.current = item
-            }
-            this.visible = true
-        },
-        openEdit(type,row) {
-        this.$refs.addFollowDialogRef.open( type,row,this.current);
-        this.$refs.addFollowDialogRef.$refs.form &&
-        this.$refs.addFollowDialogRef.$refs.form.clearValidate();
-      },
-
-      //查看详情
-      openDetail(row){
-        this.$refs.contactDetailDialogRef.open(row);
-      },
-       //批量删除
-       allDelBtn(){
-        if(this.selection?.length===0) return
-        this.delVisible=true
-      },
-      commitBtn(){
-        console.log(this.selection)
-        const dataId=this.selection.map(v=>v.id)
-        deleteInformation(dataId).then((res) => {
-          this.$message.success('删除成功!');
-          this.reload();
-        });
-      },
-      remove(row) {
-        deleteInformation([row.id]).then((res) => {
-          this.$message.success('删除成功!');
-          this.reload();
-        });
-      },
-        /* 表格数据源 */
-        datasource({ page, limit, where, order }) {
-            return getTableList({
-                pageNum: page,
-                size: limit,
-                opportunityId:this.current.id,
-                ...where
-            });
-        },
-
-
-        /* 刷新表格 */
-        reload(where) {
-            this.$refs.table.reload({ pageNum: 1, where: where  });
-        },
-
-        handleNodeClick(data, node) {
-            this.curNodeData = data;
-            this.reload({ groupId: data.id });
-        },
-
-
-        // 单击获取id
-        cellClick(row) {
-            // this.current = row
-            // this.radio = row.id
-        },
-        handleClose() {
-            this.visible = false
-            this.current = null
-            this.radio = ''
-        },
-    }
-}
-</script>
-  
-<style lang="scss" scoped>
-.tree_col {
-    border: 1px solid #eee;
-    padding: 10px 0;
-    box-sizing: border-box;
-    height: 500px;
-    overflow: auto;
-}
-
-.table_col {
-    padding-left: 10px;
-
-    ::v-deep .el-table th.el-table__cell {
-        background: #f2f2f2;
-    }
-}
-
-.pagination {
-    text-align: right;
-    padding: 10px 0;
-}
-
-.btns {
-    text-align: center;
-    padding: 10px 0;
-}
-
-.topsearch {
-    margin-bottom: 15px;
-}
-</style>
-  

+ 0 - 139
src/views/saleManage/quotation/components/followDetailDialog.vue

@@ -1,139 +0,0 @@
-<template>
-  <el-dialog
-    custom-class="ele-dialog-form"
-    v-if="visible"
-    :visible.sync="visible"
-    :title="title"
-    :close-on-click-modal="false"
-    :append-to-body="true"
-    width="70%"
-    @close="cancel"
-  >
-      <el-form
-          label-width="160px"
-          ref="formRef"
-          :model="form"
-          style="margin-top: 30px"
-        >
-          <el-row>
-            <el-col :span="8">
-              <el-form-item
-                label="跟进内容:"
-                prop="content"
-              >
-                {{form.content}}
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="达成共识:" prop="agreement">
-                {{form.agreement}}
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="下一步计划:" prop="nextPlan">
-                {{form.nextPlan}}
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="创建时间:" prop="createTime">
-                {{form.createTime}}
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="跟进时间:" prop="followupTime">
-                {{form.followupTime}}
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="客户联系人名称:" prop="linkName">
-                {{ form.linkName}}
-              </el-form-item>
-            </el-col>
-          
-           
-          </el-row>
-        </el-form>
-
-    <div slot="footer" class="footer">
-      <el-button @click="cancel">返回</el-button>
-    </div>
-  </el-dialog>
-</template>
-
-<script>
-import {contactDetail} from '@/api/saleManage/contact';
-import {getFile} from '@/api/system/file';
-import {getInfoById as getCategoryInfo} from '@/api/classifyManage/index';
-import fileUpload from '@/components/upload/fileUpload';
-import dictMixins from '@/mixins/dictMixins';
-import deptSelect from '@/components/CommomSelect/dept-select.vue';
-import personSelect from '@/components/CommomSelect/person-select.vue';
-import {copyObj} from '@/utils/util';
-
-
-export default {
-    props: {
-      categoryTreeList: Array
-    },
-    mixins: [dictMixins],
-    components: {
-      fileUpload,
-      deptSelect,
-      personSelect
-    },
-    data() {
-      let formDef = {
-        id:'',
-          contactName: '',
-          contactId: 0,
-          name: '',
-          remark: '',
-          responsibleName: '',
-          responsibleId: '',
-          source: '',
-          status: 1
-        };
-    
-      return {
-        visible: false,
-        title: '详情',
-        row: {},
-        activeName: 'base',
-        formDef,
-        form: copyObj(formDef),
-        tableBankData: [],
-        tableLinkData: [],
-        ifChiefList: [
-          {
-            value: 0,
-            label: '否'
-          },
-          {
-            value: 1,
-            label: '是'
-          }
-        ],
-      };
-    },
-    methods: {
-      async open(row) {
-        this.form = row;
-        this.visible = true;
-      },
-
-      cancel() {
-        this.$nextTick(() => {
-          // 关闭后,销毁所有的表单数据
-          this.form = copyObj(this.formDef),
-          this.otherForm = copyObj(this.otherFormDef),
-          this.tableBankData = []
-          this.tableLinkData = []
-          this.visible = false;
-        })
-      },
-
-   
-
-    }
-  };
-</script>

+ 223 - 168
src/views/saleManage/quotation/components/inventoryTable.vue

@@ -1,21 +1,23 @@
 <template>
   <el-form ref="form" :model="form" :rules="rules">
-    <ele-pro-table ref="table" :needPage="false" :columns="columns" :datasource="form.datasource"
+    <ele-pro-table ref="table" :needPage="false" :columns="columns" :toolkit="[]" :datasource="form.datasource"
       cache-key="systemRoleTable17" class="time-form">
       <!-- 表头工具栏 -->
       <template v-slot:toolbar>
-        <el-button size="small" type="primary" icon="el-icon-plus" class="ele-btn-icon" @click="handlAdd"
-          :disabled="canHandl ? true : false">
+        <div class="headbox">
+        <el-button size="small" type="primary" icon="el-icon-plus" class="ele-btn-icon" @click="handlAdd">
           新增
         </el-button>
+        <span class="amount">总计:{{getTotalPrice()}}元</span>
+      </div>
       </template>
-      <template v-slot:productName="scope">
-        <el-form-item style="margin-bottom: 20px;" :prop="'datasource.' + scope.$index + '.productName'" :rules="{
+      <template v-slot:productName="{ row, $index }">
+        <el-form-item style="margin-bottom: 20px;" :prop="'datasource.' + $index + '.productName'" :rules="{
           required: true,
           message: '请输入',
           trigger: 'change'
         }">
-          <el-input v-model="scope.row.productName" placeholder="请输入"></el-input>
+          <el-input v-model="row.productName" placeholder="请输入"  @click.native="handParent(row, $index)"></el-input>
         </el-form-item>
       </template>
       <template v-slot:productCode="scope">
@@ -24,7 +26,7 @@
           message: '请输入',
           trigger: 'change'
         }">
-          <el-input v-model="scope.row.productCode" placeholder="请输入"></el-input>
+          <el-input v-model="scope.row.productCode" disabled placeholder="请输入"></el-input>
         </el-form-item>
       </template>
       <template v-slot:productCategoryName="scope">
@@ -33,89 +35,70 @@
           message: '请输入',
           trigger: 'change'
         }">
-          <el-input v-model="scope.row.productCategoryName" placeholder="请输入"></el-input>
+          <el-input v-model="scope.row.productCategoryName" disabled placeholder="请输入"></el-input>
         </el-form-item>
       </template>
       <template v-slot:totalCount="scope">
         <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.totalCount'" :rules="{
           required: true,
-          message: '请输入',
-          trigger: 'change'
+          pattern:numberReg,
+          message: '请输入数字',
+          trigger: 'blur'
         }">
           <el-input v-model="scope.row.totalCount" placeholder="请输入"></el-input>
         </el-form-item>
       </template>
       <template v-slot:totalPrice="scope">
-        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.totalPrice'" :rules="{
-          required: true,
-          message: '请输入',
-          trigger: 'change'
-        }">
-            <el-input v-model="scope.row.totalPrice" placeholder="请输入"></el-input>
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.totalPrice'" >
+          {{(scope.row.totalCount*scope.row.singlePrice||0).toFixed(2)}}元
         </el-form-item>
       </template>
 
       <template v-slot:productBrand="scope">
-        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.productBrand'" :rules="{
-          required: true,
-          message: '请输入',
-          trigger: 'change'
-        }">
-            <el-input v-model="scope.row.productBrand" placeholder="请输入"></el-input>
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.productBrand'">
+            <el-input v-model="scope.row.productBrand" disabled placeholder="请输入"></el-input>
         </el-form-item>
       </template>
 
       <template v-slot:modelType="scope">
-        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.modelType'" :rules="{
-          required: true,
-          message: '请输入',
-          trigger: 'change'
-        }">
-            <el-input v-model="scope.row.modelType" placeholder="请输入"></el-input>
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.modelType'" >
+            <el-input v-model="scope.row.modelType" disabled placeholder="请输入"></el-input>
         </el-form-item>
       </template>
       <template v-slot:specification="scope">
-        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.specification'" :rules="{
-          required: true,
-          message: '请输入',
-          trigger: 'change'
-        }">
-            <el-input v-model="scope.row.specification" placeholder="请输入"></el-input>
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.specification'" >
+            <el-input v-model="scope.row.specification" disabled placeholder="请输入"></el-input>
         </el-form-item>
       </template>
       <template v-slot:deliveryDays="scope">
         <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.deliveryDays'" :rules="{
-          required: true,
-          message: '请输入',
-          trigger: 'change'
+          pattern:numberReg,
+          message: '请输入数字',
+          trigger: 'blur'
         }">
             <el-input v-model="scope.row.deliveryDays" placeholder="请输入"></el-input>
         </el-form-item>
       </template>
       <template v-slot:guaranteePeriod="scope">
-        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.guaranteePeriod'" :rules="{
-          required: true,
-          message: '请输入',
-          trigger: 'change'
+        <div class="period">
+          <div class="borderleftnone">
+        <el-form-item style="margin-bottom: 20px;" :prop="'datasource.' + scope.$index + '.guaranteePeriod'" :rules="{
+          pattern:numberReg,
+          message: '请输入数字',
+          trigger: 'blur'
         }">
             <el-input v-model="scope.row.guaranteePeriod" placeholder="请输入"></el-input>
         </el-form-item>
+      </div>
+      <div class="borderrightnone">
+        <DictSelection dictName="质保期单位" clearable v-model="scope.row.guaranteePeriodUnitCode">
+                </DictSelection>
+              </div>
+      </div>
       </template>
-      <template v-slot:guaranteePeriodUnitCode="scope">
-        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.guaranteePeriodUnitCode'" :rules="{
-          required: true,
-          message: '请输入',
-          trigger: 'change'
-        }">
-            <el-input v-model="scope.row.guaranteePeriodUnitCode" placeholder="请输入"></el-input>
-        </el-form-item>
-      </template>
+      <!-- <template v-slot:guaranteePeriodUnitCode="scope"> </template> -->
       <template v-slot:measuringUnit="scope">
-        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.measuringUnit'" :rules="{
-          required: true,
-          message: '请输入',
-          trigger: 'change'
-        }">
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.measuringUnit'">
             <el-input v-model="scope.row.measuringUnit" placeholder="请输入"></el-input>
         </el-form-item>
       </template>
@@ -125,25 +108,28 @@
           message: '请输入',
           trigger: 'change'
         }">
-            <el-input v-model="scope.row.remark" placeholder="请输入"></el-input>
+            <el-input v-model="scope.row.remark" type="textarea" placeholder="请输入"></el-input>
         </el-form-item>
       </template>
       <template v-slot:singlePrice="scope">
         <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.singlePrice'" :rules="{
           required: true,
-          message: '请输入',
+          pattern:numberReg,
+          message: '请输入正确的单价',
           trigger: 'change'
         }">
-            <el-input v-model="scope.row.singlePrice" placeholder="请输入"></el-input>
+            <el-input v-model="scope.row.singlePrice" placeholder="请输入">
+              <template slot="append">元</template>
+            </el-input>
         </el-form-item>
       </template>
-      <template v-slot:technicalAnswerName="scope">
-        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.technicalAnswerName'" :rules="{
+      <template v-slot:technicalAnswerName="{ row, $index }">
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + $index + '.technicalAnswerName'" :rules="{
           required: true,
           message: '请输入',
           trigger: 'change'
         }">
-            <el-input v-model="scope.row.technicalAnswerName" placeholder="请输入"></el-input>
+            <el-input v-model="row.technicalAnswerName" placeholder="请输入" @click.native="handHead(row, $index)"></el-input>
         </el-form-item>
       </template>
       <template v-slot:technicalParams="scope">
@@ -155,6 +141,21 @@
             <el-input v-model="scope.row.technicalParams" placeholder="请输入"></el-input>
         </el-form-item>
       </template>
+      <template v-slot:technicalDrawings="scope">
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.technicalDrawings'" :rules="{
+          required: false,
+          message: '请输入',
+          trigger: 'change'
+        }">
+            <fileUpload
+                  v-model="scope.row.technicalDrawings"
+                  module="main"
+                  :showLib="false"
+                  :limit="5"
+                />
+        </el-form-item>
+      </template>
+     
       
 
       <template v-slot:workHour="scope">
@@ -162,30 +163,32 @@
       </template>
       <!-- 操作列 -->
       <template v-slot:action="{ row }">
-        <el-popconfirm class="ele-action" title="确定要删除此工作时间段吗?" @confirm="remove(row)">
+        <el-popconfirm class="ele-action" title="确定要删除吗?" @confirm="remove(row)">
           <template v-slot:reference>
             <el-link type="danger" :underline="false" icon="el-icon-delete">
               删除
             </el-link>
           </template>
         </el-popconfirm>
-
-        <!--        <el-link
-          type="primary"
-          :underline="false"
-          v-if="!row.isLeader"
-          @click="setFirst(row)"
-        >
-          设为首班
-        </el-link> -->
       </template>
     </ele-pro-table>
-    <!-- <el-button @click="verification">ada</el-button> -->
+    <product-list ref="productListRef" classType="1" @changeParent="changeParent"></product-list>
+    <head-list ref="headRef"  @changeParent="changeAnswer"></head-list>
   </el-form>
 </template>
 <script>
+import { emailReg, phoneReg,numberReg } from 'ele-admin';
+import productList from './product-list.vue'
+import dictMixins from '@/mixins/dictMixins';
+import fileUpload from '@/components/upload/fileUpload';
+import headList from '@/views/saleManage/businessOpportunity/components/headList.vue'
 export default {
-
+  mixins: [dictMixins],
+  components: {
+    productList,
+    fileUpload,
+    headList
+    },
   data() {
     const defaultForm = {
       key: null,
@@ -196,6 +199,7 @@ export default {
       workHour: ''
     };
     return {
+      numberReg,
       defaultForm,
       form: {
         datasource: []
@@ -210,39 +214,27 @@ export default {
           fixed: 'left'
         },
         {
-          width: 120,
+          width: 200,
           prop: 'productName',
-          label: '产品名称',
+          label: '名称',
           slot: 'productName'
         },
         {
           width: 120,
           prop: 'productCode',
-          label: '产品编号',
+          label: '编码',
           slot: 'productCode'
         },
         {
-          width: 120,
+          width: 200,
           prop: 'productCategoryName',
-          label: '产品分类',
+          label: '类',
           slot: 'productCategoryName'
         },
         {
-          width: 120,
-          prop: 'totalCount',
-          label: '数量',
-          slot: 'totalCount'
-        },
-        {
-          width: 120,
-          prop: 'totalPrice',
-          label: '产品销售总金额',
-          slot: 'totalPrice'
-        },
-        {
-          width: 120,
+          width: 160,
           prop: 'productBrand',
-          label: '产品品牌',
+          label: '牌号',
           slot: 'productBrand'
         },
         {
@@ -257,23 +249,18 @@ export default {
           label: '规格',
           slot: 'specification'
         },
+       
         {
-          width: 120,
-          prop: 'deliveryDays',
-          label: '交期(天)',
-          slot: 'deliveryDays'
-        },
-        {
-          width: 120,
-          prop: 'guaranteePeriod',
-          label: '质保期',
-          slot: 'guaranteePeriod'
+          width: 160,
+          prop: 'singlePrice',
+          label: '单价',
+          slot: 'singlePrice'
         },
         {
           width: 120,
-          prop: 'guaranteePeriodUnitCode',
-          label: '质保期单位名称',
-          slot: 'guaranteePeriodUnitCode'
+          prop: 'totalCount',
+          label: '数量',
+          slot: 'totalCount'
         },
         {
           width: 120,
@@ -283,29 +270,52 @@ export default {
         },
         {
           width: 120,
-          prop: 'remark',
-          label: '备注',
-          slot: 'remark'
+          prop: 'totalPrice',
+          label: '合计',
+          slot: 'totalPrice'
         },
         {
           width: 120,
-          prop: 'singlePrice',
-          label: '销售单价',
-          slot: 'singlePrice'
+          prop: 'deliveryDays',
+          label: '交期(天)',
+          slot: 'deliveryDays'
         },
         {
+          width: 200,
+          prop: 'guaranteePeriod',
+          label: '质保期',
+          slot: 'guaranteePeriod'
+        },
+        // {
+        //   width: 120,
+        //   prop: 'guaranteePeriodUnitCode',
+        //   label: '',
+        //   slot: 'guaranteePeriodUnitCode'
+        // },
+         {
           width: 120,
           prop: 'technicalAnswerName',
-          label: '技术答疑人名称',
+          label: '技术答疑人',
           slot: 'technicalAnswerName'
         },
         {
-          width: 120,
+          width: 220,
           prop: 'technicalParams',
           label: '技术参数',
           slot: 'technicalParams'
         },
-        
+        {
+          width:240,
+          prop: 'technicalDrawings',
+          label: '技术图纸',
+          slot: 'technicalDrawings'
+        },
+        {
+          width: 220,
+          prop: 'remark',
+          label: '备注',
+          slot: 'remark'
+        },
         {
           columnKey: 'action',
           label: '操作',
@@ -322,9 +332,75 @@ export default {
   computed: {
     canHandl() {
       return this.form.datasource.length;
-    }
+    },
+   
   },
   methods: {
+      // 返回列表数据
+      getTableValue(){
+        let comitDatasource=this.form.datasource
+        if(comitDatasource.length===0) return []
+        comitDatasource.forEach(v=>{
+          v.totalPrice=(v.totalCount*v.singlePrice)?.toFixed(2)||0
+          v.guaranteePeriodUnitName=this.getDictValue('质保期单位', v.guaranteePeriodUnitCode)
+        })
+         return comitDatasource
+      },
+    //计算总金额
+    getTotalPrice(){
+   if(this.form.datasource.length){
+    let datasource=this.form.datasource,sum=0
+    datasource.forEach(r=>{
+      if(r.singlePrice&&r.totalCount){
+        sum+=r.singlePrice*r.totalCount
+      }
+    })
+    return sum.toFixed(2)
+   }else{
+    return 0.00
+   }
+    },
+      //修改回显
+      putTableValue(data){
+        if(data&&data?.length){
+            this.form.datasource=data
+        }
+      },
+    //选择产品
+    handParent(row,index) {
+      let item={
+          id:row.productCode
+        }
+        this.$refs.productListRef.open(item,index)
+      },
+//选择技术人回调
+changeAnswer(obj,idx) {
+        this.$set( this.form.datasource[idx], 'technicalAnswerId',  obj.id)
+        this.$set(this.form.datasource[idx], 'technicalAnswerName',  obj.name)
+      },
+      handHead(row,index){
+        let item={
+          id:row.technicalAnswerId
+        }
+        this.$refs.headRef.open(item,index)
+      },
+      //选择产品回调
+      changeParent(obj,idx) {
+        console.log(obj,'33333')
+
+        this.$set(this.form.datasource[idx], 'categoryName', obj.name)
+        this.$set(this.form.datasource[idx], 'productCategoryId',  obj.categoryLevelId)
+        this.$set(this.form.datasource[idx], 'productBrand',  obj.brandNum)
+        this.$set(this.form.datasource[idx], 'productCategoryName',  obj.categoryLevelPath)
+        this.$set(this.form.datasource[idx], 'productCode',  obj.code)
+        this.$set(this.form.datasource[idx], 'productName',  obj.name)
+        this.$set(this.form.datasource[idx], 'modelType',  obj.modelType)
+        this.$set(this.form.datasource[idx], 'measuringUnit',  obj.measuringUnit)
+        this.$set(this.form.datasource[idx], 'specification',  obj.specification)
+        
+
+
+      },
     remove(row) {
       let index = this.form.datasource.findIndex((n) => n.key == row.key);
       if (index !== -1) {
@@ -384,66 +460,45 @@ export default {
       this.$emit('timeAll', this.gettimeAll());
       return result;
     },
-    // 获取工作日时常
-    gettimeAll() {
-      let result = 0;
-      this.form.datasource.forEach((n) => {
-        result += n.workHour;
-      });
-      return result;
-    },
-    verification() {
-      return new Promise((resolve, reject) => {
+
+    validateForm (callback) {
+        //开始表单校验
         this.$refs.form.validate((valid) => {
-          if (!valid) {
-            reject();
-            return false;
-          }
-          if (this.isOverlap()) {
-            reject();
-            return false;
-          }
-          resolve();
+          callback(valid);
         });
-      });
-    },
-    // 判断时间段是否重叠
-    isOverlap() {
-      let timeRanges = JSON.parse(JSON.stringify(this.form.datasource));
-
-      // 按开始时间排序
-      timeRanges.sort(function (a, b) {
-        return (
-          new Date(`1970-01-01 ${a.startTime}`) -
-          new Date(`1970-01-01 ${b.startTime}`)
-        );
-      });
-      console.log(timeRanges);
-      for (var i = 0; i < timeRanges.length - 1; i++) {
-        let endTime = timeRanges[i].endTime;
-        let NstartTime = timeRanges[i + 1].startTime;
-        if (endTime > NstartTime) {
-          // 出现重叠
-          this.$message.error(
-            `上班时间${NstartTime}与下班时间${endTime}存在重叠`
-          );
-          return true;
-        }
-      }
-
-      return false;
-    },
-    changeStartTime(val) {
-      this.isOverlap();
-    },
-    changeEndTime(val) {
-      this.isOverlap();
-    }
+      },
+ 
   }
 };
 </script>
 <style lang="scss" scoped>
+.headbox{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  .amount{
+    font-size: 14px;
+    font-weight: bold;
+  }
+}
 .time-form .el-form-item {
   margin-bottom: 0 !important;
 }
+
+::v-deep .period{
+display: flex;
+.borderleftnone{
+  .el-input--medium .el-input__inner{
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+  }
+}
+.borderrightnone{
+  .el-input--medium .el-input__inner{
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
+  }
+}
+ 
+}
 </style>

+ 96 - 73
src/views/saleManage/quotation/components/product-list.vue

@@ -2,9 +2,10 @@
     <el-dialog title="选择产品" :visible.sync="visible" :before-close="handleClose" :close-on-click-modal="false"  top="5vh"
         :close-on-press-escape="false" append-to-body width="80%">
         <el-card shadow="never">
+            <searchProduct @search="reload"></searchProduct>
             <ele-split-layout width="244px" allow-collapse :right-style="{ overflow: 'hidden' }">
                 <div class="ele-border-lighter split-layout-right-content">
-                    <DepartmentTree @handleNodeClick="handleNodeClick" :isFirstRefreshTable="false" ref="treeList" />
+                    <productTree @handleNodeClick="handleNodeClick" :isFirstRefreshTable="false" ref="treeList" />
                 </div>
                 <!-- 表格 -->
                 <template v-slot:content>
@@ -12,7 +13,7 @@
                         height="calc(100vh - 350px)" class="dict-table" @cell-click="cellClick">
                         <!-- 表头工具栏 -->
                         <template v-slot:action="{ row }">
-                            <el-radio class="radio" v-model="radio" :label="row.id"><i></i></el-radio>
+                            <el-radio class="radio" v-model="radio" :label="row.code"><i></i></el-radio>
                         </template>
                     </ele-pro-table>
                 </template>
@@ -36,24 +37,19 @@
   
 <script>
 
-import { getUserPage } from '@/api/system/organization';
-import DepartmentTree from '@/components/DepartmentTree';
+import { getProductList } from '@/api/saleManage/quotation';
+import searchProduct from './searchProduct.vue';
+import productTree from '@/components/productTree';
 export default {
     components: {
-        DepartmentTree
+        productTree,
+        searchProduct
     },
  
     data() {
         return {
             visible: false,
-            statusOptions: [
-          { value: 1, label: '全职' },
-          { value: 2, label: '兼职' },
-          { value: 3, label: '实习' },
-          { value: 4, label: '正式' },
-          { value: 5, label: '试用' },
-          { value: 6, label: '离职' }
-        ],
+            currentIndex:null,
              columns: [
 
                 {
@@ -63,61 +59,87 @@ export default {
                     label: '选择'
                 },
                 {
-                    columnKey: 'index',
-                    label: '序号',
-                    type: 'index',
-                    width: 55,
-                    align: 'center',
-                    showOverflowTooltip: true,
-                    fixed: 'left'
-                },
-          {
-            prop: 'name',
-            label: '姓名',
-            sortable: 'custom',
-            showOverflowTooltip: true,
-            minWidth: 110
-          },
-          {
-            prop: 'jobNumber',
-            label: '工号',
-            sortable: 'custom',
-            showOverflowTooltip: true,
-            minWidth: 110
-          },
-          {
-            prop: 'loginName',
-            label: '用户账号',
-            sortable: 'custom',
-            showOverflowTooltip: true,
-            minWidth: 110
-          },
-          {
-            prop: 'sex',
-            label: '性别',
-            sortable: 'custom',
-            showOverflowTooltip: true,
-            minWidth: 80,
-            formatter: (_row, _column, cellValue) => {
-              return cellValue == 1 ? '男' : cellValue == 2 ? '女' : '';
-            }
-          },
-          {
-            prop: 'status',
-            label: '状态',
-            align: 'center',
-            sortable: 'custom',
-            width: 80,
-            formatter: (_row, _column, cellValue) => {
-              const dom = this.statusOptions.find((item) => {
-                return item.value == cellValue;
-              });
-              return dom ? dom.label : '';
-            }
-          },
+          columnKey: 'index',
+          type: 'index',
+          width: 50,
+          align: 'center',
+          showOverflowTooltip: true,
+          label: '序号'
+        },
+        {
+          prop: 'code',
+          label: '编码',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+        {
+          prop: 'name',
+          label: '名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+
+        {
+          prop: 'brandNum',
+          align: 'center',
+          label: '牌号',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'modelType',
+          label: '型号',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'specification',
+          label: '规格',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'measuringUnit',
+          label: '计量单位',
+          showOverflowTooltip: true,
+          minWidth: 90
+        },
+
+        {
+          prop: 'weightUnit',
+          label: '重量单位',
+          showOverflowTooltip: true,
+          minWidth: 90
+        },
+
+        {
+          prop: 'roughWeight',
+          label: '毛重',
+          showOverflowTooltip: true,
+          minWidth: 90
+        },
 
+        {
+          prop: 'netWeight',
+          label: '净重',
+          showOverflowTooltip: true,
+          minWidth: 90
+        },
 
-            ],
+
+        {
+          prop: 'packingUnit',
+          align: 'center',
+          label: '包装单位',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'categoryLevelPath',
+          label: '分类',
+          align: 'center',
+          showOverflowTooltip: true
+        }  ],
 
             radio: null,
         }
@@ -127,18 +149,19 @@ export default {
 
     },
     methods: {
-        open(item) {
-            if (item) {
-
+        open(item,currentIndex) {
+            this.currentIndex = currentIndex
+            if (item&&item.id) {
                 this.radio = item.id
             }
+           
             this.visible = true
         },
 
 
         /* 表格数据源 */
         datasource({ page, limit, where, order }) {
-            return getUserPage({
+            return getProductList({
                 pageNum: page,
                 size: limit,
                 ...where
@@ -153,7 +176,7 @@ export default {
 
         handleNodeClick(data, node) {
             this.curNodeData = data;
-            this.reload({ groupId: data.id });
+            this.reload({ categoryLevelId: data.id });
         },
 
 
@@ -170,9 +193,9 @@ export default {
 
         selected() {
             if (!this.current) {
-                return this.$message.warning('请选择上级客户')
+                return this.$message.warning('请至少选择一条数据')
             }
-            this.$emit('changeParent', this.current)
+            this.$emit('changeParent', this.current,this.currentIndex)
             this.handleClose()
         },
 

+ 112 - 0
src/views/saleManage/quotation/components/searchProduct.vue

@@ -0,0 +1,112 @@
+<!-- 搜索表单 -->
+<template>
+    <el-form
+      size="small"
+      label-width="60px"
+      class="ele-form-search"
+      @keyup.enter.native="search"
+      @submit.native.prevent
+    >
+      <el-row :gutter="10">
+  
+        
+        <el-col v-bind="styleResponsive ? { md: 6 } : { span: 6 }">
+          <el-form-item label="关键词">
+            <el-input
+              clearable
+              size="small"
+              v-model="where.keyWord"
+              placeholder="型号、牌号"
+            />
+          </el-form-item>
+        </el-col>
+  
+  
+  
+        <el-col v-bind="styleResponsive ? { md: 6 } : { span: 6 }">
+          <el-form-item label="编码">
+            <el-input
+              clearable
+              size="small"
+              v-model="where.code"
+              placeholder="请输入"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col v-bind="styleResponsive ? { md: 6 } : { span: 6 }">
+          <el-form-item label="名称">
+            <el-input
+              clearable
+              size="small"
+              v-model="where.name"
+              placeholder="请输入"
+            />
+          </el-form-item>
+        </el-col>
+  
+  
+  
+        <el-col v-bind="styleResponsive ? { md: 6 } : { span: 4 }">
+          <el-form-item>
+            <el-button
+              size="small"
+              type="primary"
+              icon="el-icon-search"
+              class="ele-btn-icon"
+              @click="search"
+            >
+              查询
+            </el-button>
+  
+            <el-button
+              @click="reset"
+              icon="el-icon-refresh"
+              class="ele-btn-icon"
+              size="medium"
+              >重置</el-button
+            >
+  
+            <slot></slot>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </template>
+  
+  <script>
+    export default {
+      data() {
+        // 默认表单数据
+        const defaultWhere = {
+          name: '',
+          code: '',
+          modelType: ''
+        };
+        return {
+          defaultWhere,
+          // 表单数据
+          where: { ...defaultWhere },
+          loading:false
+        };
+      },
+      computed: {
+        // 是否开启响应式布局
+        styleResponsive() {
+          return this.$store.state.theme.styleResponsive;
+        }
+      },
+      methods: {
+        /* 搜索 */
+        search() {
+          this.$emit('search', this.where);
+        },
+        /*  重置 */
+        reset() {
+          this.where = { ...this.defaultWhere };
+          this.search();
+        },
+      
+      }
+    };
+  </script>
+  

+ 4 - 4
src/views/saleManage/quotation/components/contactSearch.vue → src/views/saleManage/quotation/components/searchQuotation.vue

@@ -29,16 +29,16 @@
       </el-col>
       <el-col v-bind="styleResponsive ? { lg:6, md: 12 } : { span:6 }">
         <el-form-item label="总金额最小:" prop="totalPriceMin">
-          <el-input-number
+          <el-input
           placeholder="请输入"
-           v-model.trim="params.totalPriceMin" controls-position="right" :min="0" ></el-input-number>
+           v-model.trim="params.totalPriceMin" controls-position="right" :min="0" ></el-input>
         </el-form-item>
       </el-col> 
       <el-col v-bind="styleResponsive ? { lg:6, md: 12 } : { span:6 }">
         <el-form-item label="总金额最大:" prop="totalPriceMax">
-          <el-input-number
+          <el-input
           placeholder="请输入"
-           v-model.trim="params.totalPriceMax" controls-position="right" :min="0" ></el-input-number>
+           v-model.trim="params.totalPriceMax" controls-position="right" :min="0" ></el-input>
         </el-form-item>
       </el-col> 
 

+ 23 - 29
src/views/saleManage/quotation/index.vue

@@ -2,7 +2,7 @@
   <div class="ele-body">
     <el-card shadow="never" v-loading="loading">
       <div class="ele-border-lighter form-content" v-loading="loading">
-            <contact-search @search="reload"> </contact-search>
+            <search-quotation @search="reload"> </search-quotation>
 
             <!-- 数据表格 -->
             <ele-pro-table
@@ -26,6 +26,7 @@
                 >
                   新建
                 </el-button>
+              
                 <el-button
                   size="small"
                   type="danger"
@@ -39,8 +40,8 @@
               </template>
 
               <!-- 查看详情列 -->
-              <template v-slot:name="{ row }">
-                <el-link type="primary" :underline="false" @click="openDetail(row)"> {{ row.name }}</el-link>
+              <template v-slot:contactName="{ row }">
+                <el-link type="primary" :underline="false" @click="openDetail(row)"> {{ row.contactName }}</el-link>
               </template>
 
               <!-- 操作列 -->
@@ -75,17 +76,17 @@
     </el-card>
 
 
-    <addDialog ref="addDialogRef"  @done="reload"></addDialog>
-    <ContactDetailDialog ref="contactDetailDialogRef"></ContactDetailDialog>
+    <add-dialog ref="addDialogRef"  @done="reload"></add-dialog>
+    <detail-dialog ref="contactDetailDialogRef"></detail-dialog>
 <!-- 多选删除弹窗 -->
     <pop-modal :visible.sync="delVisible" content="是否确定删除?" @done="commitBtn"/>
   </div>
 </template>
 
 <script>
-import ContactSearch from './components/contactSearch.vue';
+import searchQuotation from './components/searchQuotation.vue';
 import addDialog from './components/addDialog.vue';
-import ContactDetailDialog from './components/contactDetailDialog.vue';
+import detailDialog from './components/detailDialog.vue';
 import popModal from '@/components/pop-modal';
 import {reviewStatus} from '@/enum/dict';
 import {getTableList, getDetail, UpdateInformation, addInformation,deleteInformation,updateStatus} from '@/api/saleManage/quotation';
@@ -95,10 +96,10 @@ import dictMixins from '@/mixins/dictMixins';
 export default {
     mixins: [dictMixins],
     components: {
-      ContactSearch,
+      searchQuotation,
       popModal,
       addDialog,
-      ContactDetailDialog,
+      detailDialog,
     },
     data() {
       return {
@@ -127,7 +128,7 @@ export default {
             align: 'center',
             slot: 'contactName',
             showOverflowTooltip: true,
-            minWidth: 140
+            minWidth: 200
           },
          
           {
@@ -142,24 +143,17 @@ export default {
             label: '是否接受拆单',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 100,
+            minWidth: 200,
             formatter: (_row, _column, cellValue) => {
               return _row.status === 1 ? '接受' : '不接受';
             }
           },
-          {
-            prop: 'askFile',
-            label: '询价单附件',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 120
-          },
           {
             prop: 'contactAddress',
             label: '询价方地址',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 120
+            minWidth: 200
           },
          
           {
@@ -167,7 +161,7 @@ export default {
             label: '询价方email',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 100
+            minWidth: 180
           },
           {
             prop: 'contactFax',
@@ -212,49 +206,49 @@ export default {
             label: '报价方地址',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 100
+            minWidth: 200
           },
           {
             prop: 'quoteEmail',
             label: '报价方email',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 100
+            minWidth: 180
           },
           {
             prop: 'quoteFax',
             label: '报价方传真',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 100
+            minWidth: 140
           },
           {
             prop: 'quoteLinkName',
             label: '报价方联系人',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 100
+            minWidth: 140
           },
           {
             prop: 'quoteName',
             label: '报价方名称',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 100
+            minWidth: 200
           },
           {
             prop: 'quoteTel',
             label: '报价方联系电话',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 100
+            minWidth: 140
           },
           {
             prop: 'reviewerName',
             label: '审核人名称',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 100
+            minWidth: 140
           },
           {
             prop: 'reviewerTime',
@@ -268,7 +262,7 @@ export default {
             label: '税率',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 100
+            minWidth: 140
           },
           {
             prop: 'totalPrice',
@@ -325,7 +319,7 @@ export default {
         this.$refs.addDialogRef.$refs.form &&
         this.$refs.addDialogRef.$refs.form.clearValidate();
       },
-      
+     
       //批量删除
       allDelBtn(){
         if(this.selection.length===0) return