zhujun 2 лет назад
Родитель
Сommit
a8800519a5

+ 11 - 0
src/api/saleManage/businessFollow.js

@@ -68,3 +68,14 @@ export async function updateStatus(id, status) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+/**
+ * 查询客户联系人列表
+ */
+export async function getcontactlink(params) {
+  const res = await request.get(`/eom/contactlink/list/`, {params});
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 67 - 0
src/api/saleManage/quotation.js

@@ -0,0 +1,67 @@
+import request from '@/utils/request';
+
+/**
+ * 获取信息列表
+ */
+export async function getTableList(params) {
+  const res = await request.get(`/eom/quote/page`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 获取信息详情
+ */
+export async function getDetail(id) {
+  const res = await request.get(`/eom/quote/getById/${id}`, {});
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 更新信息
+ */
+export async function UpdateInformation(data) {
+  const res = await request.put(`/eom/quote/update`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 新增信息
+ */
+export async function addInformation(data) {
+  const res = await request.post(`/eom/quote/save`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 删除
+ */
+export async function deleteInformation(data) {
+  const res = await request.delete('/eom/quote/delete', {data});
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 导出报价单
+ */
+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));
+  }

+ 70 - 0
src/components/pop-el-modal/index.vue

@@ -0,0 +1,70 @@
+<template>
+    <div class="pop-modal">
+        <el-dialog
+        width="400px"
+        :title="title"
+        :visible.sync="popVisible"
+        custom-class="ele-dialog-form"
+        :close-on-click-modal="true"
+        :append-to-body="true"
+        @update:visible="updateVisible"
+    >
+        <div style="padding: 10px 0 20px;">{{content}}</div>
+        <template v-slot:footer>
+      <el-button @click="updateVisible(false)">取消</el-button>
+      <el-button type="primary" :loading="loading" @click="handleCommit">
+        提交
+      </el-button>
+    </template>
+    </el-dialog>
+    </div>
+  </template>
+  
+  <script>
+    export default {
+        data(){
+          return {
+            loading:false
+        }
+        },
+      props: {
+        title: {
+          typeof: String,
+          default: '温馨提示'
+        },
+        content:{
+            typeof: String,
+          default: ''
+        },
+        popVisible: {
+          typeof: Boolean,
+          default: false
+        }
+      },
+      methods:{
+          /* 更新visible */
+      updateVisible(value) {
+        this.$emit('update:popVisible', value);
+      },
+      handleCommit(){
+        this.loading = true;
+        this.$emit('done');
+        setTimeout(() => {
+            this.updateVisible(false);
+            this.loading = false;
+        }, 800);
+      }
+      }
+    };
+  </script>
+  <style lang="scss" scoped>
+    ::v-deep .ele-dialog-form {
+     .el-dialog__header{
+        border-bottom: 0;
+     }
+     .el-dialog__footer{
+        border-top: 0;
+     }
+    }
+  </style>
+  

+ 17 - 0
src/enum/dict.js

@@ -20,6 +20,7 @@ export default {
   客户状态: 'contact_status',
   企业类型: 'company_category',
   结算方式: 'settlement_mode',
+  付款方式: 'pay_way',
   客户联系人状态: 'contact_link_status'
 };
 
@@ -32,5 +33,21 @@ export const numberList = [
   'order_source',
   'production_status',
   'plan_type',
+  'pay_way',
   'delivery_status'
 ];
+
+
+ //报价管理-审核枚举
+ export const reviewStatus={
+  0:'未提交',
+  1:'待审核',
+  2:'已审核',
+  3:'审核不通过'
+}
+
+//报价单-是否接受拆单
+export const acceptUnpackoptions=[
+  {label:'接受',value:1},
+  {label:'不接受',value:0}
+]

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

@@ -0,0 +1,216 @@
+
+<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>

+ 16 - 21
src/views/saleManage/businessOpportunity/components/contactSearch.vue

@@ -25,28 +25,17 @@
           ></el-input>
         </el-form-item>
       </el-col> 
-      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
-        <el-form-item label="创建开始时间:" prop="createTimeStart">
+      <el-col v-bind="styleResponsive ? { lg: 12, md: 12 } : { span: 6 }">
+        <el-form-item label="创建时间:" prop="createTimeStart">
           <el-date-picker
-          v-model="params.createTimeStart"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            placeholder="开始时间"
-            type="datetime"
-            style="width: 200px"
-            class="filter-item"
-          ></el-date-picker>
-        </el-form-item>
-      </el-col>
-      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
-        <el-form-item label="创建结束时间:"  prop="createTimeEnd">
-          <el-date-picker
-          v-model="params.createTimeEnd"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            placeholder="结束时间"
-            type="datetime"
-            style="width: 200px"
-            class="filter-item"
-          ></el-date-picker>
+      v-model="createTime"
+      @change="changeDate"
+      type="datetimerange"
+      value-format="yyyy-MM-dd HH:mm:ss"
+      start-placeholder="开始时间"
+      end-placeholder="结束时间"
+      :default-time="['00:00:00', '23:59:59']">
+    </el-date-picker>
         </el-form-item>
       </el-col>
       <el-col v-bind="styleResponsive ? { lg:4, md: 12 } : { span:4 }">
@@ -76,6 +65,7 @@
         status: ''
       };
       return {
+        createTime:[],
         where:{createTimeStart:'',createTimeEnd:''},
         defaultParams,
         // 表单数据
@@ -94,9 +84,14 @@
       }
     },
     methods: {
+      changeDate(e){
+       this.createTime=e
+      },
       /* 搜索 */
       search () {
         console.log(this.current);
+        const [createTimeStart,createTimeEnd]=this.createTime
+        this.params=Object.assign({},this.params,{createTimeStart,createTimeEnd})
         this.$emit('search', {
           ...this.params
         });

+ 131 - 42
src/views/saleManage/businessOpportunity/components/follow-list.vue

@@ -1,38 +1,96 @@
 <template>
-    <el-dialog title="跟进列表" :visible.sync="visible" :before-close="handleClose" :close-on-click-modal="false"  top="5vh"
+    <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:action="{ row }">
-                            <el-radio class="radio" v-model="radio" :label="row.id"><i></i></el-radio>
-                        </template>
+                         <!-- 表头工具栏 -->
+              <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>
-
-        <div class="btns">
-            <el-button type="primary" size="small" @click="selected">选择</el-button>
-            <el-button size="small" @click="handleClose">关闭</el-button>
-        </div>
-
-    </el-dialog>
+        <AddFollowDialog ref="addFollowDialogRef" @done="reload" ></AddFollowDialog>
+        <followDetailDialog ref="contactDetailDialogRef"></followDetailDialog>
+     <!-- 多选删除弹窗 -->
+    <pop-el-modal :popVisible.sync="delVisible" content="是否确定删除?" @done="commitBtn"/>
+  </el-dialog>
 </template>
   
 <script>
-
-import { getTableList } from '@/api/saleManage/businessFollow';
+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: [
               {
-                  action: 'action',
-                  slot: 'action',
-                  align: 'center',
-                  label: '选择'
+                width: 45,
+                type: 'selection',
+                columnKey: 'selection',
+               align: 'center'
               },
               {
                   columnKey: 'index',
@@ -46,6 +104,7 @@ export default {
               {
                 prop: 'content',
                 label: '跟进内容',
+                slot: 'content',
                 showOverflowTooltip: true,
                 minWidth: 200
               },
@@ -53,7 +112,7 @@ export default {
                 prop: 'agreement',
                 label: '达成共识',
                 showOverflowTooltip: true,
-                minWidth: 200
+                minWidth: 110
               },
               {
                 prop: 'linkName',
@@ -72,7 +131,7 @@ export default {
                 label: '跟进时间',
                 align: 'center',
                 showOverflowTooltip: true,
-                minWidth: 160,
+                minWidth: 110,
                 formatter: (_row, _column, cellValue) => {
                   return this.$util.toDateString(cellValue);
                 }
@@ -82,12 +141,21 @@ export default {
                 label: '创建时间',
                 align: 'center',
                 showOverflowTooltip: true,
-                minWidth: 160,
+                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,
@@ -95,23 +163,57 @@ export default {
     },
 
     watch: {
-
+        visible(visible) {
+            if(visible){
+                this.$nextTick(()=>{
+                   this.reload();
+                })
+                
+            }
+        }
     },
     methods: {
         open(item) {
             if (item) {
-
-                this.radio = item.id
+              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
             });
         },
@@ -130,27 +232,14 @@ export default {
 
         // 单击获取id
         cellClick(row) {
-            this.current = row
-            this.radio = row.id
+            // this.current = row
+            // this.radio = row.id
         },
         handleClose() {
             this.visible = false
             this.current = null
             this.radio = ''
         },
-
-        selected() {
-            if (!this.current) {
-                return this.$message.warning('请选择上级客户')
-            }
-            this.$emit('changeParent', this.current)
-            this.handleClose()
-        },
-
-
-
-
-
     }
 }
 </script>

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

@@ -0,0 +1,139 @@
+<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>

+ 9 - 1
src/views/saleManage/businessOpportunity/index.vue

@@ -48,7 +48,7 @@
                   type="primary"
                   :underline="false"
                   icon="el-icon-edit"
-                  @click="openEdit('follow',row)"
+                  @click="handleFollow(row)"
                 >
                   跟进
                 </el-link>
@@ -102,6 +102,7 @@
 
     <AddContactDialog ref="addContactDialogRef" :categoryTreeList="treeList" @done="reload"></AddContactDialog>
     <ContactDetailDialog ref="contactDetailDialogRef"></ContactDetailDialog>
+    <follow-list ref="followDialogRef"></follow-list>
 <!-- 多选删除弹窗 -->
     <pop-modal :visible.sync="delVisible" content="是否确定删除?" @done="commitBtn"/>
   </div>
@@ -111,6 +112,7 @@
 import ContactSearch from './components/contactSearch.vue';
 import AddContactDialog from './components/addContactDialog.vue';
 import ContactDetailDialog from './components/contactDetailDialog.vue';
+import followList from './components/follow-list.vue';
 import popModal from '@/components/pop-modal';
 import {getTableList, getDetail, UpdateInformation, addInformation,deleteInformation,updateStatus} from '@/api/saleManage/businessOpportunity';
 import dictMixins from '@/mixins/dictMixins';
@@ -119,6 +121,7 @@ export default {
     mixins: [dictMixins],
     components: {
       ContactSearch,
+      followList,
       popModal,
       AddContactDialog,
       ContactDetailDialog,
@@ -252,6 +255,11 @@ export default {
         this.$refs.addContactDialogRef.$refs.form &&
         this.$refs.addContactDialogRef.$refs.form.clearValidate();
       },
+      //跟进
+      handleFollow(row){
+        this.current = row;
+        this.$refs.followDialogRef.open(row)
+      },
       //批量删除
       allDelBtn(){
         if(this.selection.length===0) return

+ 432 - 0
src/views/saleManage/quotation/components/addDialog.vue

@@ -0,0 +1,432 @@
+<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 ref="form" :model="form" :rules="rules" label-width="120px">
+      <el-card
+        shadow="never"
+        header="基本信息"
+        body-style="padding: 22px 20px 0 0;"
+      >
+        <el-row>
+          <el-col :span="6">
+            <el-form-item
+              label="询价方名称"
+              prop="contactName"
+              style="margin-bottom: 22px"
+            >
+              <el-input
+                clearable
+                v-model="form.contactName"
+                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="contactTel"
+              style="margin-bottom: 22px"
+            >
+              <el-input
+                clearable
+                :maxlength="20"
+                v-model="form.contactTel"
+                placeholder="请输入"
+              />
+            </el-form-item>
+            <el-form-item
+              label="询价方地址"
+              prop="contactAddress"
+              style="margin-bottom: 22px"
+            >
+              <el-input
+                clearable
+                v-model="form.contactAddress"
+                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"
+              style="margin-bottom: 22px"
+            >
+              <el-input
+                clearable
+                :maxlength="20"
+                v-model="form.contactLinkName"
+                placeholder="请输入"
+              />
+            </el-form-item>
+            <el-form-item
+              label="	询价方email"
+              prop="contactEmail"
+              style="margin-bottom: 22px"
+            >
+              <el-input
+                clearable
+                v-model="form.contactEmail"
+                placeholder="请输入"
+              />
+            </el-form-item>
+            <el-form-item
+              label="报价方地址"
+              prop="quoteAddress"
+              style="margin-bottom: 22px"
+            >
+              <el-input
+                clearable
+                v-model="form.quoteAddress"
+                placeholder="请输入"
+              />
+            </el-form-item>
+            <el-form-item
+              label="报价方联系人"
+              prop="quoteLinkName"
+              style="margin-bottom: 22px"
+            >
+              <el-input
+                clearable
+                v-model="form.quoteLinkName"
+                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
+                clearable
+                v-model="form.contactFax"
+                placeholder="请输入"
+              />
+            </el-form-item>
+            <el-form-item
+              label="报价方email"
+              prop="quoteEmail"
+              style="margin-bottom: 22px"
+            >
+              <el-input
+                clearable
+                v-model="form.quoteEmail"
+                placeholder="请输入"
+              />
+            </el-form-item>
+            <el-form-item
+              label="报价方名称"
+              prop="quoteName"
+              style="margin-bottom: 22px"
+            >
+              <el-input
+                clearable
+                v-model="form.quoteName"
+                placeholder="请输入"
+              />
+            </el-form-item>
+          </el-col>
+         
+        </el-row>
+      </el-card>
+      <el-card
+        shadow="never"
+        header="报价单产品清单"
+        body-style="padding: 22px 20px 0 0;"
+      >
+        <inventoryTable
+          ref="inventoryTable"
+          @timeAll="getDetailTable"
+          :delDetailIds="delDetailIds"
+        ></inventoryTable>
+      </el-card>
+    </el-form>
+
+    <div slot="footer" class="footer">
+      <el-button type="primary" @click="save">保存</el-button>
+      <el-button @click="cancel">返回</el-button>
+    </div>
+    <head-list ref="headRef"  @changeParent="changeHead"></head-list>
+    <parentList ref="parentRef" classType="1" @changeParent="changeParent"></parentList>
+  </ele-modal>
+</template>
+
+<script>
+import {acceptUnpackoptions} from '@/enum/dict';
+import inventoryTable from './inventoryTable.vue'
+import {categoryData} from 'element-china-category-data';
+import fileUpload from '@/components/upload/fileUpload';
+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 headList from './head-list.vue'
+import {copyObj} from '@/utils/util';
+
+
+export default {
+    props: {
+      categoryTreeList: Array
+    },
+    mixins: [dictMixins],
+    components: {
+      fileUpload,
+      inventoryTable,
+      deptSelect,
+      headList,
+      parentList,
+      personSelect
+    },
+    data() {
+      let formDef = {
+          id:'',
+          contactName: '',
+          contactId: 0,
+          name: '',
+          remark: '',
+          responsibleName: '',
+          responsibleId: '',
+          source: '',
+          status: 1
+        };
+   
+      return {
+        payWayOptions:[],
+        acceptUnpackoptions,
+        visible: false,
+        title: '',
+        row: {},
+        activeName: 'base',
+        formDef,
+        form: copyObj(formDef),
+        // removeBankList: [],
+        // removeLinkList: [],
+        tableBankData: [],
+        tableLinkData: [],
+     
+        rules: {
+          contactName: [
+            { required: true, message: '请选择客户', trigger: 'change' }
+          ],
+          name: [
+            { required: true, message: '请输入客户名称', trigger: 'blur' }
+          ],
+          responsibleName: [
+            { required: true, message: '请选择负责人', trigger: 'change' }
+          ]
+        },
+      
+        options: {
+          cityData,
+          categoryData,
+        },
+        // 提交状态
+        loading: false,
+        // 是否是修改
+        isUpdate: false,
+
+        // 组织机构树形结构数据
+        groupTreeData: [],
+        // 组织机构平铺数据
+        groupData: [],
+      };
+    },
+  
+    methods: {
+       //
+      getDetailTable (val) {
+        this.form.totalWorkHour = val;
+      },
+      //选择客户回调
+      changeParent(obj) {
+        this.$set( this.form, 'contactId',  obj.id)
+        this.$set( this.form, 'contactName',  obj.name)
+
+      },
+      //选择负责人回调
+      changeHead(obj) {
+        this.$set( this.form, 'responsibleId',  obj.id)
+        this.$set( this.form, 'responsibleName',  obj.name)
+      },
+      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;
+        this.visible = true;
+        if (type == 'add') {
+          this.isUpdate = false;
+        } else {
+          this.isUpdate = true;
+          this.form=row
+        }
+      },
+
+      salesmanChange(val, info){
+        this.otherForm.salesmanName = info.name;
+      },
+      settlementModeChange(info){
+        this.otherForm.settlementModeName = info.dictValue;
+      },
+      ifChiefChange(value, idx){
+        if(value === 1){
+          this.tableLinkData.forEach(e => e.ifChief = 0);
+          this.tableLinkData[idx].ifChief = 1;
+        }
+      },
+ 
+    
+   
+      getValidate() {
+          return  new Promise((resolve, reject) => {
+              this.$refs.form.validate((valid) => {
+                if (!valid) {
+                  reject(false);
+                } else {
+                  resolve(true);
+                }
+              });
+            })
+     },
+      async save() {
+        try {
+           await this.getValidate();
+           // 表单验证通过,执行保存操作
+           this.loading = true;
+      
+        if (!this.isUpdate) {
+          delete this.form.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.activeName = 'base';
+          // 关闭后,销毁所有的表单数据
+          this.$refs['otherForm'] &&  this.$refs['otherForm'].resetFields();
+          this.$refs['formRef'] &&  this.$refs['formRef'].resetFields();
+          this.form = copyObj(this.formDef)
+          this.visible = false;
+        })
+      },
+    
+
+    }
+  };
+</script>

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

@@ -0,0 +1,216 @@
+
+<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>

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

@@ -0,0 +1,137 @@
+<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>

+ 105 - 0
src/views/saleManage/quotation/components/contactSearch.vue

@@ -0,0 +1,105 @@
+<!-- 搜索表单 -->
+<template>
+  <el-form
+    label-width="100px"
+    class="ele-form-search"
+    @keyup.enter.native="search"
+    @submit.native.prevent
+  >
+    <el-row :gutter="15">
+      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <el-form-item label="询价方名称:" prop="contactName">
+          <el-input
+            clearable
+            placeholder="请输入"
+            v-model.trim="params.contactName"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="创建时间:" prop="createTimeStart">
+          <el-date-picker
+            v-model="createTime"
+            @change="changeDate"
+            type="datetimerange"
+            value-format="yyyy-MM-dd HH:mm:ss"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
+            :default-time="['00:00:00', '23:59:59']">
+          </el-date-picker>
+        </el-form-item>
+      </el-col>
+      <el-col v-bind="styleResponsive ? { lg:6, md: 12 } : { span:6 }">
+        <el-form-item label="总金额最小:" prop="totalPriceMin">
+          <el-input-number
+          placeholder="请输入"
+           v-model.trim="params.totalPriceMin" controls-position="right" :min="0" ></el-input-number>
+        </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
+          placeholder="请输入"
+           v-model.trim="params.totalPriceMax" controls-position="right" :min="0" ></el-input-number>
+        </el-form-item>
+      </el-col> 
+
+      <el-col v-bind="styleResponsive ? { lg:6, md: 12 } : { span:4 }">
+        <div class="ele-form-actions">
+          <el-button
+            type="primary"
+            icon="el-icon-search"
+            class="ele-btn-icon"
+            @click="search"
+          >
+            查询
+          </el-button>
+          <el-button @click="reset">重置</el-button>
+        </div>
+      </el-col>
+    </el-row>
+  </el-form>
+</template>
+<script>
+  export default {
+    data () {
+      // 默认表单数据
+      const defaultParams = {
+        contactName: '',
+        createTimeStart: '',
+        createTimeEnd:'',
+        totalPriceMax: null,
+        totalPriceMin: null
+      };
+      return {
+        createTime:[],
+        defaultParams,
+        // 表单数据
+        params: { ...defaultParams }
+      };
+    },
+    computed: {
+      // 是否开启响应式布局
+      styleResponsive () {
+        return this.$store.state.theme.styleResponsive;
+      }
+    },
+    methods: {
+      //选择时间
+      changeDate(e){
+       this.createTime=e
+      },
+      /* 搜索 */
+      search () {
+        const [createTimeStart,createTimeEnd]=this.createTime
+        this.params=Object.assign({},this.params,{createTimeStart,createTimeEnd})
+        this.$emit('search', {
+          ...this.params
+        });
+      },
+      /*  重置 */
+      reset () {
+        this.params = { ...this.defaultParams };
+        this.search();
+      }
+    }
+  };
+</script>

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

@@ -0,0 +1,278 @@
+<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>
+  

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

@@ -0,0 +1,139 @@
+<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>

+ 218 - 0
src/views/saleManage/quotation/components/head-list.vue

@@ -0,0 +1,218 @@
+<template>
+    <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">
+            <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" />
+                </div>
+                <!-- 表格 -->
+                <template v-slot:content>
+                    <ele-pro-table ref="table" :columns="columns" :datasource="datasource" row-key="id"
+                        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>
+                        </template>
+                    </ele-pro-table>
+                </template>
+            </ele-split-layout>
+
+
+
+
+
+
+
+        </el-card>
+
+        <div class="btns">
+            <el-button type="primary" size="small" @click="selected">选择</el-button>
+            <el-button size="small" @click="handleClose">关闭</el-button>
+        </div>
+
+    </el-dialog>
+</template>
+  
+<script>
+
+import { getUserPage } from '@/api/system/organization';
+import DepartmentTree from '@/components/DepartmentTree';
+export default {
+    components: {
+        DepartmentTree
+    },
+ 
+    data() {
+        return {
+            visible: false,
+            statusOptions: [
+          { value: 1, label: '全职' },
+          { value: 2, label: '兼职' },
+          { value: 3, label: '实习' },
+          { value: 4, label: '正式' },
+          { value: 5, label: '试用' },
+          { value: 6, label: '离职' }
+        ],
+             columns: [
+
+                {
+                    action: 'action',
+                    slot: 'action',
+                    align: 'center',
+                    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 : '';
+            }
+          },
+
+
+            ],
+
+            radio: null,
+        }
+    },
+
+    watch: {
+
+    },
+    methods: {
+        open(item) {
+            if (item) {
+
+                this.radio = item.id
+            }
+            this.visible = true
+        },
+
+
+        /* 表格数据源 */
+        datasource({ page, limit, where, order }) {
+            return getUserPage({
+                pageNum: page,
+                size: limit,
+                ...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 = ''
+        },
+
+        selected() {
+            if (!this.current) {
+                return this.$message.warning('请选择上级客户')
+            }
+            this.$emit('changeParent', this.current)
+            this.handleClose()
+        },
+
+
+
+
+
+    }
+}
+</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>
+  

+ 283 - 0
src/views/saleManage/quotation/components/inventoryTable.vue

@@ -0,0 +1,283 @@
+<template>
+  <el-form ref="form" :model="form" :rules="rules">
+    <ele-pro-table ref="table" :needPage="false" :columns="columns" :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">
+          新增
+        </el-button>
+      </template>
+      <template v-slot:name="scope">
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.name'" :rules="{
+          required: true,
+          message: '请输入',
+          trigger: 'change'
+        }">
+          <el-input v-model="scope.row.name" placeholder="请输入"></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:startTime="scope">
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.startTime'" :rules="{
+          required: true,
+          message: '请输入',
+          trigger: 'change'
+        }">
+          <el-time-picker style="width: 100%" placeholder="起始时间" v-model="scope.row.startTime" format="HH:mm"
+            value-format="HH:mm:ss" @change="changeStartTime">
+          </el-time-picker>
+        </el-form-item>
+      </template>
+      <template v-slot:endTime="scope">
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.endTime'" :rules="{
+          required: true,
+          message: '请输入',
+          trigger: 'change'
+        }">
+          <el-time-picker style="width: 100%" format="HH:mm" value-format="HH:mm:ss" placeholder="结束时间"
+            v-model="scope.row.endTime"  @change="changeEndTime">
+          </el-time-picker>
+          <!-- :picker-options="{
+              selectableRange: setEndTime(scope)
+            }" -->
+        </el-form-item>
+      </template>
+      <template v-slot:isFirst="scope">
+
+        <el-form-item style="margin-bottom: 20px" :prop="'datasource.' + scope.$index + '.isFirst'" :rules="{
+          required: true,
+          message: '请选择',
+          trigger: 'change'
+        }">
+          <el-select clearable class="ele-block" v-model="scope.row.isFirst" placeholder="请选择">
+            <el-option label="是" :value="1" />
+            <el-option label="否" :value="0" />
+          </el-select>
+        </el-form-item>
+
+
+
+      </template>
+      <template v-slot:workHour="scope">
+        {{ getHour(scope.row) }}
+      </template>
+      <!-- 操作列 -->
+      <template v-slot:action="{ row }">
+        <el-popconfirm class="ele-action" title="确定要删除此工作时间段吗?" @confirm="remove(row)">
+          <template v-slot:reference>
+            <el-link type="danger" :underline="false" icon="el-icon-delete">
+              删除
+            </el-link>
+          </template>
+        </el-popconfirm>
+
+        <!--        <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> -->
+  </el-form>
+</template>
+<script>
+export default {
+  props: {
+    delDetailIds: Array
+  },
+  data() {
+    const defaultForm = {
+      key: null,
+      endTime: '',
+      isFirst: 0,
+      name: '',
+      startTime: '',
+      workHour: ''
+    };
+    return {
+      defaultForm,
+      form: {
+        datasource: []
+      },
+      rules: {},
+      columns: [
+        {
+          width: 45,
+          type: 'index',
+          columnKey: 'index',
+          align: 'center',
+          fixed: 'left'
+        },
+        {
+          prop: 'name',
+          label: '时段名称',
+          slot: 'name'
+        },
+        {
+          prop: 'startTime',
+          label: '上班时间',
+          slot: 'startTime'
+        },
+        {
+          prop: 'endTime',
+          label: '下班时间',
+          slot: 'endTime'
+        },
+        {
+          prop: 'workHour',
+          label: '工作时数',
+          slot: 'workHour'
+        },
+        {
+          prop: 'isFirst',
+          label: '是否当日首班',
+          slot: 'isFirst'
+        },
+        {
+          columnKey: 'action',
+          label: '操作',
+          width: 220,
+          align: 'center',
+          resizable: false,
+          slot: 'action',
+          showOverflowTooltip: true
+        }
+      ],
+    };
+  },
+  computed: {
+    canHandl() {
+      return this.form.datasource.length;
+    }
+  },
+  methods: {
+    remove(row) {
+      let index = this.form.datasource.findIndex((n) => n.key == row.key);
+      if (index !== -1) {
+        this.form.datasource.splice(index, 1);
+        this.setSort();
+        if (row.id) {
+          this.delDetailIds.push(row.id);
+        }
+      }
+    },
+    // 清空表格
+    restTable() {
+      this.form.datasource = [];
+    },
+    // 重新排序
+    setSort() {
+      this.form.datasource.forEach((n, index) => {
+        n.key = index + 1;
+      });
+    },
+    // 添加
+    handlAdd() {
+      let item = JSON.parse(JSON.stringify(this.defaultForm));
+      item.key = this.form.datasource.length + 1;
+      this.form.datasource.push(item);
+    },
+    // 设为首班
+    setFirst(row) {
+      this.form.datasource.forEach((n) => {
+        n.isFirst = 0;
+      });
+      row.isFirst = 1;
+    },
+    setEndTime(scope) {
+      if (scope.row.startTime) {
+        return `${scope.row.startTime} - 23:59:59`;
+      } else {
+        return '00:00:00 - 23:59:59';
+      }
+    },
+    // 计算小时
+    getHour(row) {
+      let s1 = row.startTime;
+      let s2 = row.endTime;
+      let result = 0;
+      if (!s1 || !s2) {
+        result = 0;
+      }
+      var reDate = /\d{4}-\d{1,2}-\d{1,2} /;
+      s1 = new Date(
+        (reDate.test(s1) ? s1 : '1970-01-01 ' + s1).replace(/-/g, '/')
+      );
+      s2 = new Date(
+        (reDate.test(s2) ? s2 : '1970-01-01 ' + s2).replace(/-/g, '/')
+      );
+      var ms = s2.getTime() - s1.getTime();
+      if (ms < 0) return 0;
+      result = Math.floor(ms / 1000 / 60 / 60); //小时
+      row.workHour = result;
+      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) => {
+        this.$refs.form.validate((valid) => {
+          if (!valid) {
+            reject();
+            return false;
+          }
+          if (this.isOverlap()) {
+            reject();
+            return false;
+          }
+          resolve();
+        });
+      });
+    },
+    // 判断时间段是否重叠
+    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>
+.time-form .el-form-item {
+  margin-bottom: 0 !important;
+}
+</style>

+ 375 - 0
src/views/saleManage/quotation/index.vue

@@ -0,0 +1,375 @@
+<template>
+  <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>
+
+            <!-- 数据表格 -->
+            <ele-pro-table
+              ref="table"
+              :columns="columns"
+              :datasource="datasource"
+              height="calc(100vh - 350px)"
+              full-height="calc(100vh - 116px)"
+              tool-class="ele-toolbar-form"
+              :selection.sync="selection"
+              cache-key="eomContactPageTable"
+            >
+              <!-- 表头工具栏 -->
+              <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:name="{ row }">
+                <el-link type="primary" :underline="false" @click="openDetail(row)"> {{ row.name }}</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.id])"
+                >
+                  <template v-slot:reference>
+                    <el-link
+                      type="danger"
+                      :underline="false"
+                      icon="el-icon-delete"
+                    >
+                      删除
+                    </el-link>
+                  </template>
+                </el-popconfirm>
+              </template>
+            </ele-pro-table>
+          </div>
+    </el-card>
+
+
+    <addDialog ref="addDialogRef"  @done="reload"></addDialog>
+    <ContactDetailDialog ref="contactDetailDialogRef"></ContactDetailDialog>
+<!-- 多选删除弹窗 -->
+    <pop-modal :visible.sync="delVisible" content="是否确定删除?" @done="commitBtn"/>
+  </div>
+</template>
+
+<script>
+import ContactSearch from './components/contactSearch.vue';
+import addDialog from './components/addDialog.vue';
+import ContactDetailDialog from './components/contactDetailDialog.vue';
+import popModal from '@/components/pop-modal';
+import {reviewStatus} from '@/enum/dict';
+import {getTableList, getDetail, UpdateInformation, addInformation,deleteInformation,updateStatus} from '@/api/saleManage/quotation';
+import dictMixins from '@/mixins/dictMixins';
+
+
+export default {
+    mixins: [dictMixins],
+    components: {
+      ContactSearch,
+      popModal,
+      addDialog,
+      ContactDetailDialog,
+    },
+    data() {
+      return {
+        selection:[],   //单选中集合
+        delVisible:false,  //批量删除弹框状态
+        loading: false,  // 加载状态
+        columns: [
+          {
+             width: 45,
+             type: 'selection',
+             columnKey: 'selection',
+             align: 'center'
+          },
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+          {
+            prop: 'contactName',
+            label: '询价方名称',
+            align: 'center',
+            slot: 'contactName',
+            showOverflowTooltip: true,
+            minWidth: 140
+          },
+         
+          {
+            prop: 'contactTel',
+            label: '询价方联系电话',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 140
+          },
+          {
+            prop: 'acceptUnpack',
+            label: '是否接受拆单',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100,
+            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
+          },
+         
+          {
+            prop: 'contactEmail',
+            label: '询价方email',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'contactFax',
+            label: '询价方传真',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'contactLinkName',
+            label: '询价方联系人',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 140
+          },
+          {
+            prop: 'createTime',
+            label: '创建时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100,
+            formatter: (_row, _column, cellValue) => {
+              return this.$util.toDateString(cellValue);
+            }
+          },
+          {
+            prop: 'deliveryDate',
+            label: '交货日期',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'payWayName',
+            label: '付款方式',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'quoteAddress',
+            label: '报价方地址',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'quoteEmail',
+            label: '报价方email',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'quoteFax',
+            label: '报价方传真',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'quoteLinkName',
+            label: '报价方联系人',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'quoteName',
+            label: '报价方名称',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'quoteTel',
+            label: '报价方联系电话',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'reviewerName',
+            label: '审核人名称',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'reviewerTime',
+            label: '审核时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'taxRate',
+            label: '税率',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'totalPrice',
+            label: '总金额',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100
+          },
+          {
+            prop: 'status',
+            label: '审核状态',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 100,
+            formatter: (_row, _column, cellValue) => {
+              return reviewStatus[_row.status];
+            }
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            width: 230,
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            showOverflowTooltip: true,
+            fixed: 'right',
+          }
+        ]
+      };
+    },
+    computed: {},
+    created() {
+      this.requestDict('客户状态');
+    },
+    methods: {
+      /* 表格数据源 */
+      datasource({ page, limit, where, order }) {
+        return getTableList({
+          pageNum: page,
+          size: limit,
+          ...where
+        });
+      },
+    
+      /* 刷新表格 */
+      reload(where) {
+        this.$refs.table.reload({ page: 1, where });
+      },
+      
+      //新增编辑
+      openEdit(type,row) {
+        this.$refs.addDialogRef.open( type,row, row.id);
+        this.$refs.addDialogRef.$refs.form &&
+        this.$refs.addDialogRef.$refs.form.clearValidate();
+      },
+      
+      //批量删除
+      allDelBtn(){
+        if(this.selection.length===0) return
+        this.delVisible=true
+      },
+      
+      //删除接口
+      remove(delData) {
+        deleteInformation(delData).then((res) => {
+          this.$message.success('删除成功!');
+          this.reload();
+        });
+      },
+
+    //删除弹框确定
+      commitBtn(){
+        const dataId=this.selection.map(v=>v.id)
+        this.remove(dataId)
+      },
+
+    //查看详情
+      openDetail(row){
+        this.$refs.contactDetailDialogRef.open(row);
+      },
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+:deep(.el-link--inner){
+  margin-left: 0px !important;
+}
+
+.sys-organization-list {
+  height: calc(100vh - 264px);
+  box-sizing: border-box;
+  border-width: 1px;
+  border-style: solid;
+  overflow: auto;
+}
+.sys-organization-list :deep(.el-tree-node__content) {
+  height: 40px;
+  & > .el-tree-node__expand-icon {
+    margin-left: 10px;
+  }
+}
+</style>