Răsfoiți Sursa

Merge branch 'develop' of http://code.dashoo.cn/chengjian/opms_frontend into feature/product_management

wangxingcheng 3 ani în urmă
părinte
comite
c03f11c807

+ 4 - 4
src/api/customer/index.js

@@ -28,7 +28,7 @@ export default {
   },
   // 客户联系人详情
   getContact(query) {
-    return micro_request.postRequest(basePath, 'Contant', 'GetEntityById', query)
+    return micro_request.postRequest(basePath, 'Contact', 'GetList', query)
   },
   // 客户动态
   dynamicsList(query) {
@@ -40,11 +40,11 @@ export default {
   },
   // 编辑联系人
   updateContact(query) {
-    return micro_request.postRequest(basePath, 'Contant', 'UpdateById', query)
+    return micro_request.postRequest(basePath, 'Contact', 'UpdateById', query)
   },
   // 删除联系人
   deleteContact(query) {
-    return micro_request.postRequest(basePath, 'Contant', 'DeleteById', query)
+    return micro_request.postRequest(basePath, 'Contact', 'DeleteById', query)
   },
   // 公海列表
   getList(query) {
@@ -84,6 +84,6 @@ export default {
   },
   // 新建联系人
   createContact(query) {
-    return micro_request.postRequest(basePath, 'Contant', 'Create', query)
+    return micro_request.postRequest(basePath, 'Contact', 'Create', query)
   },
 }

+ 27 - 0
src/api/proj/business.js

@@ -0,0 +1,27 @@
+import micro_request from '@/utils/micro_request'
+
+const basePath = process.env.VUE_APP_ParentPath
+export default {
+  // 获取列表
+  getList(query) {
+    return micro_request.postRequest(basePath, 'Business', 'GetList', query)
+  },
+  getEntityById(query) {
+    return micro_request.postRequest(basePath, 'Business', 'GetEntityById', query)
+  },
+  doAdd(query) {
+    return micro_request.postRequest(basePath, 'Business', 'Create', query)
+  },
+  doEdit(query) {
+    return micro_request.postRequest(basePath, 'Business', 'UpdateById', query)
+  },
+  doDelete(query) {
+    return micro_request.postRequest(basePath, 'Business', 'DeleteByIds', query)
+  },
+  businessGradation(query) {
+    return micro_request.postRequest(basePath, 'Business', 'BusinessGradation', query)
+  },
+  businessTransfer(query) {
+    return micro_request.postRequest(basePath, 'Business', 'BusinessTransfer', query)
+  },
+}

+ 212 - 0
src/components/select/SelectBusiness.vue

@@ -0,0 +1,212 @@
+<template>
+  <el-dialog append-to-body :title="title" :visible.sync="innerVisible">
+    <el-row>
+      <el-col :span="24">
+        <div style="float: right">
+          <el-button size="mini" type="primary" @click="handleAdd">新建项目</el-button>
+          <el-dropdown style="margin-left: 10px" trigger="click">
+            <el-button icon="el-icon-more" size="mini" />
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item icon="el-icon-upload2">导入</el-dropdown-item>
+              <el-dropdown-item icon="el-icon-download">导出</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </div>
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col :span="24">
+        <el-input
+          v-model="queryForm.nboName"
+          clearable
+          placeholder="项目名称"
+          style="width: 30%; margin-right: 10px"
+          suffix-icon="el-icon-search" />
+        <!--        <span>显示:</span>-->
+        <!--        <el-radio-group v-model="queryForm.type">-->
+        <!--          <el-radio-button label="全部客户" />-->
+        <!--          <el-radio-button label="我负责的客户" />-->
+        <!--        </el-radio-group>-->
+        <table-tool :check-list.sync="checkList" :columns="columns" style="float: right" />
+      </el-col>
+    </el-row>
+    <el-table ref="table" v-loading="listLoading" :data="list" @selection-change="setSelectRows">
+      <el-table-column align="center" type="selection" />
+      <el-table-column
+        v-for="(item, index) in finallyColumns"
+        :key="index"
+        align="center"
+        :label="item.label"
+        :prop="item.prop"
+        show-overflow-tooltip
+        :sortable="item.sortable"
+        :width="item.width">
+        <template #default="{ row }">
+          <span v-if="item.prop === 'custStatus'">
+            {{ row.custStatus == 10 ? '正常' : '异常' }}
+          </span>
+          <span v-else>{{ row[item.prop] }}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      background
+      :current-page="queryForm.pageNo"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
+    <span slot="footer">
+      <el-button size="mini" type="primary" @click="save">保存</el-button>
+      <el-button size="mini" @click="innerVisible = false">取消</el-button>
+    </span>
+    <!-- 新建项目弹窗 -->
+    <business-edit ref="businessEdit" />
+  </el-dialog>
+</template>
+
+<script>
+  import businessApi from '@/api/proj/business'
+  import TableTool from '@/components/table/TableTool'
+  import BusinessEdit from '@/views/proj/business/components/BusinessEdit'
+
+  export default {
+    name: 'SelectBusiness',
+    components: {
+      TableTool,
+      BusinessEdit,
+    },
+    props: {
+      title: {
+        type: String,
+        default: '选择',
+      },
+      multiple: Boolean,
+      queryParams: {
+        type: Object,
+        default() {
+          return {}
+        },
+      },
+    },
+    data() {
+      return {
+        innerVisible: false,
+        queryForm: {
+          nboName: '',
+          type: '全部客户',
+          pageNum: 1,
+          pageSize: 10,
+        },
+        checkList: [],
+        columns: [
+          {
+            label: '商机标题',
+            width: 'auto',
+            prop: 'nboName',
+            sortable: true,
+            disableCheck: true,
+          },
+          {
+            label: '关联客户',
+            width: 'auto',
+            prop: 'custName',
+          },
+          {
+            label: '审批状态',
+            width: 'auto',
+            prop: 'approStatus',
+          },
+          {
+            label: '商机状态',
+            width: 'auto',
+            prop: 'nboPhase',
+          },
+          {
+            label: '商机类别',
+            width: 'auto',
+            prop: 'nboType',
+          },
+          {
+            label: '商机金额',
+            width: 'auto',
+            prop: 'nboBudget',
+          },
+          {
+            label: '最后跟进时间',
+            width: 'auto',
+            prop: 'finalFollowTime',
+          },
+          {
+            label: '下次跟进时间',
+            width: 'auto',
+            prop: 'nextFollowTime',
+          },
+        ],
+        list: [],
+        listLoading: true,
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        selectRows: [],
+      }
+    },
+    computed: {
+      finallyColumns() {
+        return this.columns.filter((item) => this.checkList.includes(item.label))
+      },
+    },
+    mounted() {
+      this.fetchData()
+    },
+    methods: {
+      open() {
+        this.innerVisible = true
+      },
+      save() {
+        this.innerVisible = false
+        this.$emit('save', this.selectRows)
+      },
+      handleAdd() {
+        this.$refs.businessEdit.showEdit()
+      },
+      async fetchData() {
+        this.listLoading = true
+        let query = Object.assign(this.queryForm, this.queryParams)
+        const {
+          data: { list, total },
+        } = await businessApi.getList(query)
+        this.list = list
+        this.total = total
+        this.listLoading = false
+      },
+      setSelectRows(val) {
+        if (!this.multiple && val.length === this.list.length) {
+          // 返回单条数据情况下-控制全选情况下单选第一条数据
+          if (this.selectRows.length === 1) {
+            this.$refs.table.clearSelection()
+            return
+          }
+          this.$refs.table.clearSelection()
+          this.$refs.table.toggleRowSelection(val.shift(), true)
+        } else if (!this.multiple && val.length > 1) {
+          // 返回单条数据情况下-控制选择当前点击数据
+          this.$refs.table.clearSelection()
+          this.$refs.table.toggleRowSelection(val.pop(), true)
+        } else {
+          this.selectRows = val
+        }
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNo = val
+        this.fetchData()
+      },
+    },
+  }
+</script>
+
+<style scoped></style>

+ 215 - 0
src/components/select/SelectContact.vue

@@ -0,0 +1,215 @@
+<template>
+  <el-dialog append-to-body :title="title" :visible.sync="innerVisible">
+    <el-row>
+      <el-col :span="24">
+        <div style="float: right">
+          <el-button size="mini" type="primary" @click="handleAdd">新建联系人</el-button>
+          <el-dropdown style="margin-left: 10px" trigger="click">
+            <el-button icon="el-icon-more" size="mini" />
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item icon="el-icon-upload2">导入</el-dropdown-item>
+              <el-dropdown-item icon="el-icon-download">导出</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </div>
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col :span="24">
+        <el-input
+          v-model="queryForm.keyword"
+          clearable
+          placeholder="客户名称/手机/电话"
+          style="width: 30%; margin-right: 10px"
+          suffix-icon="el-icon-search" />
+        <!--        <span>显示:</span>-->
+        <!--        <el-radio-group v-model="queryForm.type">-->
+        <!--          <el-radio-button label="全部客户" />-->
+        <!--          <el-radio-button label="我负责的客户" />-->
+        <!--        </el-radio-group>-->
+        <table-tool :check-list.sync="checkList" :columns="columns" style="float: right" />
+      </el-col>
+    </el-row>
+    <el-table ref="table" v-loading="listLoading" :data="list" @selection-change="setSelectRows">
+      <el-table-column align="center" type="selection" />
+      <el-table-column
+        v-for="(item, index) in finallyColumns"
+        :key="index"
+        align="center"
+        :label="item.label"
+        :prop="item.prop"
+        show-overflow-tooltip
+        :sortable="item.sortable"
+        :width="item.width">
+        <template #default="{ row }">
+          <span v-if="item.prop === 'custStatus'">
+            {{ row.custStatus == 10 ? '正常' : '异常' }}
+          </span>
+          <span v-else>{{ row[item.prop] }}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      background
+      :current-page="queryForm.pageNo"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
+    <span slot="footer">
+      <el-button size="mini" type="primary" @click="save">保存</el-button>
+      <el-button size="mini" @click="innerVisible = false">取消</el-button>
+    </span>
+    <!-- 新建联系人弹窗 -->
+    <customer-contact ref="contact" />
+  </el-dialog>
+</template>
+
+<script>
+  import customerApi from '@/api/customer/index'
+  import TableTool from '@/components/table/TableTool'
+  import CustomerContact from '@/views/customer/components/Contact'
+
+  export default {
+    name: 'SelectContact',
+    components: {
+      TableTool,
+      CustomerContact,
+    },
+    props: {
+      title: {
+        type: String,
+        default: '选择',
+      },
+      multiple: Boolean,
+      queryParams: {
+        type: Object,
+        default() {
+          return {}
+        },
+      },
+    },
+    data() {
+      return {
+        innerVisible: false,
+        queryForm: {
+          keyword: '',
+          type: '全部客户',
+          pageNum: 1,
+          pageSize: 10,
+        },
+        checkList: [],
+        columns: [
+          {
+            label: '联系人姓名',
+            width: 'auto',
+            prop: 'cuctName',
+            // sortable: true,
+            disableCheck: true,
+          },
+          {
+            label: '客户名称',
+            width: 'auto',
+            prop: 'custName',
+          },
+          {
+            label: '手机号码',
+            width: 'auto',
+            prop: 'telephone',
+          },
+          {
+            label: '微信',
+            width: 'auto',
+            prop: 'wechat',
+          },
+          {
+            label: '邮箱',
+            width: 'auto',
+            prop: 'email',
+          },
+          {
+            label: '职务',
+            width: 'auto',
+            prop: 'postion',
+          },
+          {
+            label: '关键决策人',
+            width: 'auto',
+            prop: 'policy',
+          },
+          {
+            label: '性别',
+            width: 'auto',
+            prop: 'cuctGender',
+            // sortable: true,
+          },
+        ],
+        list: [],
+        listLoading: true,
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        selectRows: [],
+      }
+    },
+    computed: {
+      finallyColumns() {
+        return this.columns.filter((item) => this.checkList.includes(item.label))
+      },
+    },
+    mounted() {
+      this.fetchData()
+    },
+    methods: {
+      open() {
+        this.innerVisible = true
+      },
+      save() {
+        this.innerVisible = false
+        this.$emit('save', this.selectRows)
+      },
+      handleAdd(res) {
+        this.$refs.contact.contactForm.custId = res.id
+        this.$refs.contact.contactForm.custName = res.name
+        this.$refs.contact.contactVisible = true
+      },
+      async fetchData() {
+        this.listLoading = true
+        let query = Object.assign(this.queryForm, this.queryParams)
+        const {
+          data: { list, total },
+        } = await customerApi.getContact(query)
+        this.list = list
+        this.total = total
+        this.listLoading = false
+      },
+      setSelectRows(val) {
+        if (!this.multiple && val.length === this.list.length) {
+          // 返回单条数据情况下-控制全选情况下单选第一条数据
+          if (this.selectRows.length === 1) {
+            this.$refs.table.clearSelection()
+            return
+          }
+          this.$refs.table.clearSelection()
+          this.$refs.table.toggleRowSelection(val.shift(), true)
+        } else if (!this.multiple && val.length > 1) {
+          // 返回单条数据情况下-控制选择当前点击数据
+          this.$refs.table.clearSelection()
+          this.$refs.table.toggleRowSelection(val.pop(), true)
+        } else {
+          this.selectRows = val
+        }
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNo = val
+        this.fetchData()
+      },
+    },
+  }
+</script>
+
+<style scoped></style>

+ 222 - 0
src/components/select/SelectCustomer.vue

@@ -0,0 +1,222 @@
+<template>
+  <el-dialog append-to-body :title="title" :visible.sync="innerVisible">
+    <el-row>
+      <el-col :span="24">
+        <div style="float: right">
+          <el-button size="mini" type="primary" @click="handleAdd">新建客户</el-button>
+          <el-dropdown style="margin-left: 10px" trigger="click">
+            <el-button icon="el-icon-more" size="mini" />
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item icon="el-icon-upload2">导入</el-dropdown-item>
+              <el-dropdown-item icon="el-icon-download">导出</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </div>
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col :span="24">
+        <el-input
+          v-model="queryForm.custName"
+          clearable
+          placeholder="客户名称"
+          style="width: 30%; margin-right: 10px"
+          suffix-icon="el-icon-search" />
+        <!--        <span>显示:</span>-->
+        <!--        <el-radio-group v-model="queryForm.type">-->
+        <!--          <el-radio-button label="全部客户" />-->
+        <!--          <el-radio-button label="我负责的客户" />-->
+        <!--        </el-radio-group>-->
+        <table-tool :check-list.sync="checkList" :columns="columns" style="float: right" />
+      </el-col>
+    </el-row>
+    <el-table ref="table" v-loading="listLoading" :data="list" @selection-change="setSelectRows">
+      <el-table-column align="center" type="selection" />
+      <el-table-column
+        v-for="(item, index) in finallyColumns"
+        :key="index"
+        align="center"
+        :label="item.label"
+        :prop="item.prop"
+        show-overflow-tooltip
+        :sortable="item.sortable"
+        :width="item.width">
+        <template #default="{ row }">
+          <span v-if="item.prop === 'custStatus'">
+            {{ row.custStatus == 10 ? '正常' : '异常' }}
+          </span>
+          <span v-else>{{ row[item.prop] }}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      background
+      :current-page="queryForm.pageNo"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
+    <span slot="footer">
+      <el-button size="mini" type="primary" @click="save">保存</el-button>
+      <el-button size="mini" @click="innerVisible = false">取消</el-button>
+    </span>
+    <!-- 新增编辑客户弹窗 -->
+    <customer-edit ref="edit" @createContact="createContact" @customerSave="fetchData" />
+    <!-- 新建联系人弹窗 -->
+    <customer-contact ref="contact" />
+  </el-dialog>
+</template>
+
+<script>
+  import customerApi from '@/api/customer/index'
+  import TableTool from '@/components/table/TableTool'
+  import CustomerEdit from '@/views/customer/components/Edit'
+  import CustomerContact from '@/views/customer/components/Contact'
+
+  export default {
+    name: 'SelectCustomer',
+    components: {
+      TableTool,
+      CustomerEdit,
+      CustomerContact,
+    },
+    props: {
+      title: {
+        type: String,
+        default: '选择',
+      },
+      multiple: Boolean,
+      queryParams: {
+        type: Object,
+        default() {
+          return {}
+        },
+      },
+    },
+    data() {
+      return {
+        innerVisible: false,
+        queryForm: {
+          custName: '',
+          pageNum: 1,
+          pageSize: 10,
+        },
+        checkList: [],
+        columns: [
+          {
+            label: '客户名称',
+            width: 'auto',
+            prop: 'custName',
+            // sortable: true,
+            disableCheck: true,
+          },
+          {
+            label: '助记名',
+            width: 'auto',
+            prop: 'abbrName',
+          },
+          {
+            label: '所在地区',
+            width: 'auto',
+            prop: 'custLocation',
+          },
+          {
+            label: '客户行业',
+            width: 'auto',
+            prop: 'custIndustry',
+          },
+          {
+            label: '客户级别',
+            width: 'auto',
+            prop: 'custLevel',
+          },
+          {
+            label: '客户状态',
+            width: 'auto',
+            prop: 'custStatus',
+          },
+          {
+            label: '创建人',
+            width: 'auto',
+            prop: 'createdName',
+          },
+          {
+            label: '创建时间',
+            width: 'auto',
+            prop: 'createdTime',
+            // sortable: true,
+          },
+        ],
+        list: [],
+        listLoading: true,
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        selectRows: [],
+      }
+    },
+    computed: {
+      finallyColumns() {
+        return this.columns.filter((item) => this.checkList.includes(item.label))
+      },
+    },
+    mounted() {
+      this.fetchData()
+    },
+    methods: {
+      open() {
+        this.innerVisible = true
+      },
+      save() {
+        this.innerVisible = false
+        this.$emit('save', this.selectRows)
+      },
+      handleAdd() {
+        this.$refs.edit.init()
+      },
+      // 联系人弹窗
+      async createContact(res) {
+        this.$refs.contact.contactForm.custId = res.id
+        this.$refs.contact.contactForm.custName = res.name
+        this.$refs.contact.contactVisible = true
+      },
+      async fetchData() {
+        this.listLoading = true
+        let query = Object.assign(this.queryForm, this.queryParams)
+        const {
+          data: { list, total },
+        } = await customerApi.getList(query)
+        this.list = list
+        this.total = total
+        this.listLoading = false
+      },
+      setSelectRows(val) {
+        if (!this.multiple && val.length === this.list.length) {
+          // 返回单条数据情况下-控制全选情况下单选第一条数据
+          if (this.selectRows.length === 1) {
+            this.$refs.table.clearSelection()
+            return
+          }
+          this.$refs.table.clearSelection()
+          this.$refs.table.toggleRowSelection(val.shift(), true)
+        } else if (!this.multiple && val.length > 1) {
+          // 返回单条数据情况下-控制选择当前点击数据
+          this.$refs.table.clearSelection()
+          this.$refs.table.toggleRowSelection(val.pop(), true)
+        } else {
+          this.selectRows = val
+        }
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNo = val
+        this.fetchData()
+      },
+    },
+  }
+</script>
+
+<style scoped></style>

+ 212 - 0
src/components/select/SelectDistributor.vue

@@ -0,0 +1,212 @@
+<template>
+  <el-dialog append-to-body :title="title" :visible.sync="innerVisible">
+    <el-row>
+      <el-col :span="24">
+        <div style="float: right">
+          <el-button size="mini" type="primary" @click="handleAdd">新建经销商</el-button>
+          <el-dropdown style="margin-left: 10px" trigger="click">
+            <el-button icon="el-icon-more" size="mini" />
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item icon="el-icon-upload2">导入</el-dropdown-item>
+              <el-dropdown-item icon="el-icon-download">导出</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </div>
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col :span="24">
+        <el-input
+          v-model="queryForm.distName"
+          clearable
+          placeholder="经销商名称"
+          style="width: 30%; margin-right: 10px"
+          suffix-icon="el-icon-search" />
+        <table-tool :check-list.sync="checkList" :columns="columns" style="float: right" />
+      </el-col>
+    </el-row>
+    <el-table ref="table" v-loading="listLoading" :data="list" @selection-change="setSelectRows">
+      <el-table-column align="center" type="selection" />
+      <el-table-column
+        v-for="(item, index) in finallyColumns"
+        :key="index"
+        align="center"
+        :label="item.label"
+        :prop="item.prop"
+        show-overflow-tooltip
+        :sortable="item.sortable"
+        :width="item.width">
+        <template #default="{ row }">
+          <span v-if="item.prop === 'custStatus'">
+            {{ row.custStatus == 10 ? '正常' : '异常' }}
+          </span>
+          <span v-else>{{ row[item.prop] }}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      background
+      :current-page="queryForm.pageNo"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
+    <span slot="footer">
+      <el-button size="mini" type="primary" @click="save">保存</el-button>
+      <el-button size="mini" @click="innerVisible = false">取消</el-button>
+    </span>
+    <!-- 新增编辑经销商弹窗 -->
+    <distributor-edit ref="edit" @customerSave="fetchData" />
+  </el-dialog>
+</template>
+
+<script>
+  import distributorApi from '@/api/base/distr/distr'
+  import TableTool from '@/components/table/TableTool'
+  import DistributorEdit from '@/views/base/distributor/components/DistrEdit'
+
+  export default {
+    name: 'SelectDistributor',
+    components: {
+      TableTool,
+      DistributorEdit,
+    },
+    props: {
+      title: {
+        type: String,
+        default: '选择',
+      },
+      multiple: Boolean,
+      queryParams: {
+        type: Object,
+        default() {
+          return {}
+        },
+      },
+    },
+    data() {
+      return {
+        innerVisible: false,
+        queryForm: {
+          distName: '',
+          pageNum: 1,
+          pageSize: 10,
+        },
+        checkList: [],
+        columns: [
+          {
+            label: '经销商名称',
+            width: 'auto',
+            prop: 'distName',
+            // sortable: true,
+            disableCheck: true,
+          },
+          {
+            label: '助记名',
+            width: 'auto',
+            prop: 'abbrName',
+          },
+          {
+            label: '所在省份',
+            width: 'auto',
+            prop: 'provinceDesc',
+          },
+          {
+            label: '归属销售',
+            width: 'auto',
+            prop: 'belongSale',
+          },
+          {
+            label: '业务范围',
+            width: 'auto',
+            prop: 'businessScope',
+          },
+          {
+            label: '负责人',
+            width: 'auto',
+            prop: 'distBoss',
+          },
+          {
+            label: '负责人电话',
+            width: 'auto',
+            prop: 'distBossPhone',
+          },
+          {
+            label: '创建人',
+            width: 'auto',
+            prop: 'createdName',
+          },
+          {
+            label: '创建时间',
+            width: 'auto',
+            prop: 'createdTime',
+            // sortable: true,
+          },
+        ],
+        list: [],
+        listLoading: true,
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        selectRows: [],
+      }
+    },
+    computed: {
+      finallyColumns() {
+        return this.columns.filter((item) => this.checkList.includes(item.label))
+      },
+    },
+    mounted() {
+      this.fetchData()
+    },
+    methods: {
+      open() {
+        this.innerVisible = true
+      },
+      save() {
+        this.innerVisible = false
+        this.$emit('save', this.selectRows)
+      },
+      handleAdd() {
+        this.$refs.edit.showEdit()
+      },
+      async fetchData() {
+        this.listLoading = true
+        let query = Object.assign(this.queryForm, this.queryParams)
+        const {
+          data: { list, total },
+        } = await distributorApi.getList(query)
+        this.list = list
+        this.total = total
+        this.listLoading = false
+      },
+      setSelectRows(val) {
+        if (!this.multiple && val.length === this.list.length) {
+          // 返回单条数据情况下-控制全选情况下单选第一条数据
+          if (this.selectRows.length === 1) {
+            this.$refs.table.clearSelection()
+            return
+          }
+          this.$refs.table.clearSelection()
+          this.$refs.table.toggleRowSelection(val.shift(), true)
+        } else if (!this.multiple && val.length > 1) {
+          // 返回单条数据情况下-控制选择当前点击数据
+          this.$refs.table.clearSelection()
+          this.$refs.table.toggleRowSelection(val.pop(), true)
+        } else {
+          this.selectRows = val
+        }
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNo = val
+        this.fetchData()
+      },
+    },
+  }
+</script>
+
+<style scoped></style>

+ 213 - 0
src/components/select/SelectProduct.vue

@@ -0,0 +1,213 @@
+<template>
+  <el-dialog append-to-body :title="title" :visible.sync="innerVisible">
+    <el-row>
+      <el-col :span="24">
+        <div style="float: right">
+          <el-button size="mini" type="primary" @click="handleAdd">新建产品</el-button>
+          <el-dropdown style="margin-left: 10px" trigger="click">
+            <el-button icon="el-icon-more" size="mini" />
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item icon="el-icon-upload2">导入</el-dropdown-item>
+              <el-dropdown-item icon="el-icon-download">导出</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </div>
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col :span="24">
+        <el-input
+          v-model="queryForm.prodName"
+          clearable
+          placeholder="产品名称"
+          style="width: 30%; margin-right: 10px"
+          suffix-icon="el-icon-search" />
+        <table-tool :check-list.sync="checkList" :columns="columns" style="float: right" />
+      </el-col>
+    </el-row>
+    <el-table ref="table" v-loading="listLoading" :data="list" @selection-change="setSelectRows">
+      <el-table-column align="center" type="selection" />
+      <el-table-column
+        v-for="(item, index) in finallyColumns"
+        :key="index"
+        align="center"
+        :label="item.label"
+        :prop="item.prop"
+        show-overflow-tooltip
+        :sortable="item.sortable"
+        :width="item.width">
+        <template #default="{ row }">
+          <span v-if="item.prop === 'custStatus'">
+            {{ row.custStatus == 10 ? '正常' : '异常' }}
+          </span>
+          <span v-else>{{ row[item.prop] }}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      background
+      :current-page="queryForm.pageNo"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
+    <span slot="footer">
+      <el-button size="mini" type="primary" @click="save">保存</el-button>
+      <el-button size="mini" @click="innerVisible = false">取消</el-button>
+    </span>
+    <!-- 新增编辑产品弹窗 -->
+    <product-edit ref="edit" @fetch-data="fetchData" />
+  </el-dialog>
+</template>
+
+<script>
+  import productApi from '@/api/product'
+  import TableTool from '@/components/table/TableTool'
+  import ProductEdit from '@/views/product/components/ProductEdit'
+
+  export default {
+    name: 'SelectProduct',
+    components: {
+      TableTool,
+      ProductEdit,
+    },
+    props: {
+      title: {
+        type: String,
+        default: '选择',
+      },
+      multiple: Boolean,
+      queryParams: {
+        type: Object,
+        default() {
+          return {}
+        },
+      },
+    },
+    data() {
+      return {
+        innerVisible: false,
+        queryForm: {
+          prodName: '',
+          type: '全部客户',
+          pageNum: 1,
+          pageSize: 10,
+        },
+        checkList: [],
+        columns: [
+          {
+            label: '产品名称',
+            width: 'auto',
+            prop: 'prodName',
+            // sortable: true,
+            disableCheck: true,
+          },
+          {
+            label: '产品类别',
+            width: 'auto',
+            prop: 'prodClass',
+          },
+          {
+            label: '产品型号',
+            width: 'auto',
+            prop: 'prodCode',
+          },
+          {
+            label: '签约代理价',
+            width: 'auto',
+            prop: 'agentPrice',
+          },
+          {
+            label: '经销商价',
+            width: 'auto',
+            prop: 'distPrice',
+          },
+          {
+            label: '建议成交价',
+            width: 'auto',
+            prop: 'guidPrice',
+          },
+          {
+            label: '市场报价',
+            width: 'auto',
+            prop: 'marketPrice',
+          },
+          {
+            label: '创建人',
+            width: 'auto',
+            prop: 'createdName',
+          },
+          {
+            label: '创建时间',
+            width: 'auto',
+            prop: 'createdTime',
+            // sortable: true,
+          },
+        ],
+        list: [],
+        listLoading: true,
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        selectRows: [],
+      }
+    },
+    computed: {
+      finallyColumns() {
+        return this.columns.filter((item) => this.checkList.includes(item.label))
+      },
+    },
+    mounted() {
+      this.fetchData()
+    },
+    methods: {
+      open() {
+        this.innerVisible = true
+      },
+      save() {
+        this.innerVisible = false
+        this.$emit('save', this.selectRows)
+      },
+      handleAdd() {
+        this.$refs.edit.showEdit()
+      },
+      async fetchData() {
+        this.listLoading = true
+        let query = Object.assign(this.queryForm, this.queryParams)
+        const {
+          data: { list, total },
+        } = await productApi.getList(query)
+        this.list = list
+        this.total = total
+        this.listLoading = false
+      },
+      setSelectRows(val) {
+        if (!this.multiple && val.length === this.list.length) {
+          // 返回单条数据情况下-控制全选情况下单选第一条数据
+          if (this.selectRows.length === 1) {
+            this.$refs.table.clearSelection()
+            return
+          }
+          this.$refs.table.clearSelection()
+          this.$refs.table.toggleRowSelection(val.shift(), true)
+        } else if (!this.multiple && val.length > 1) {
+          // 返回单条数据情况下-控制选择当前点击数据
+          this.$refs.table.clearSelection()
+          this.$refs.table.toggleRowSelection(val.pop(), true)
+        } else {
+          this.selectRows = val
+        }
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNo = val
+        this.fetchData()
+      },
+    },
+  }
+</script>
+
+<style scoped></style>

+ 1 - 1
src/views/base/distributor/components/DistrEdit.vue

@@ -50,7 +50,7 @@
   </el-dialog>
 </template> -->
 <template>
-  <el-dialog :title="title" :visible.sync="dialogFormVisible" @close="handleClose">
+  <el-dialog append-to-body :title="title" :visible.sync="dialogFormVisible" @close="handleClose">
     <el-form ref="form" :model="form" :rules="rules">
       <el-row :gutter="20">
         <el-col :span="12">

+ 20 - 4
src/views/customer/components/Allocate.vue

@@ -2,7 +2,7 @@
  * @Author: wanglj 471442253@qq.com
  * @Date: 2022-12-26 14:34:34
  * @LastEditors: wanglj
- * @LastEditTime: 2023-01-05 09:15:25
+ * @LastEditTime: 2023-01-05 18:17:04
  * @Description: file content
  * @FilePath: \opms_frontend\src\views\customer\components\allocate.vue
 -->
@@ -16,7 +16,7 @@
       </el-form-item>
     </el-form>
     <span slot="footer">
-      <el-button size="mini" type="primary">保存</el-button>
+      <el-button size="mini" type="primary" @click="handleSubmit">保存</el-button>
       <el-button size="mini" @click="visible = false">取消</el-button>
     </span>
     <!--    <Transfer ref="transfer" />-->
@@ -27,7 +27,8 @@
 <script>
   // import Transfer from './Transfer.vue'
   import SelectUser from '@/components/select/SelectUser'
-
+  import api from '@/api/customer'
+  import to from 'await-to-js'
   export default {
     components: {
       // Transfer,
@@ -56,6 +57,8 @@
         allocate: [],
         data: generateData(),
         options: [],
+        ids: [],
+        userList: [],
       }
     },
     methods: {
@@ -65,7 +68,20 @@
         this.$refs.selectUser.open()
       },
       selectUser(userList) {
-        console.log(userList)
+        this.userList = userList
+        this.form.allocate = userList.map((item) => item.userName).join()
+      },
+      async handleSubmit() {
+        let params = {
+          salesId: this.userList[0].id,
+          ids: this.ids,
+          salesName: this.userList[0].userName,
+        }
+        const [err, res] = await to(api.receiveCustomer(params))
+        if (err) return
+        this.$message.success(res.msg)
+        this.visible = false
+        this.$emit('refresh')
       },
     },
   }

+ 1 - 1
src/views/customer/components/Contact.vue

@@ -1,6 +1,6 @@
 <template>
   <!-- 新建联系人弹窗 -->
-  <el-dialog :title="title" :visible.sync="contactVisible" @close="contactClose">
+  <el-dialog append-to-body :title="title" :visible.sync="contactVisible" @close="contactClose">
     <el-form ref="contactForm" :model="contactForm" :rules="contactRules">
       <el-row :gutter="20">
         <el-col :span="12">

+ 1 - 1
src/views/customer/components/Edit.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-dialog :title="title" :visible.sync="editVisible" @close="handleClose">
+  <el-dialog append-to-body :title="title" :visible.sync="editVisible" @close="handleClose">
     <el-form ref="editForm" :model="editForm" :rules="editRules">
       <el-row :gutter="20">
         <el-col :span="12">

+ 1 - 1
src/views/product/components/ProductEdit.vue

@@ -36,7 +36,7 @@
   </el-dialog>
 </template> -->
 <template>
-  <el-dialog :title="title" :visible.sync="dialogFormVisible" @close="handleClose">
+  <el-dialog append-to-body :title="title" :visible.sync="dialogFormVisible" @close="handleClose">
     <el-form ref="form" :model="form" :rules="rules">
       <el-row :gutter="20">
         <el-col :span="12">

+ 241 - 0
src/views/proj/business/components/BusinessEdit.vue

@@ -0,0 +1,241 @@
+<template>
+  <el-dialog append-to-body :title="title" :visible.sync="dialogFormVisible" @close="close">
+    <el-form ref="form" label-width="120px" :model="form" :rules="rules">
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="项目标题" prop="nboName">
+            <el-input v-model="form.nboName" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="关联客户" prop="custName">
+            <el-input v-model="form.custName" readonly @focus="handleSelectCustomer" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="获取日期" prop="title">
+            <el-date-picker v-model="form.value1" placeholder="选择日期" style="width: 100%" type="datetime" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="项目来源" prop="nboSource">
+            <el-input v-model="form.nboSource" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="主要联系人" prop="contactName">
+            <el-input v-model="form.contactName" readonly @focus="handleSelectContact" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="职位" prop="contactPostion">
+            <el-input v-model="form.contactPostion" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="联系电话" prop="contactTelephone">
+            <el-input v-model="form.contactTelephone" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="负责人员" prop="makerName">
+            <el-input v-model="form.makerName" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="销售模式" prop="salesModel">
+            <el-input v-model="form.salesModel" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="经销商名称" prop="distributorName">
+            <el-input v-model="form.distributorName" readonly @focus="handleSelectDistributor" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="经销商负责人" prop="title">
+            <el-input v-model="form.title" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="经销商联系方式" prop="title">
+            <el-input v-model="form.title" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="备注信息" prop="remark">
+            <el-input v-model="form.remark" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <!--      <el-row :gutter="20">-->
+      <!--        <el-col :span="24">-->
+      <!--          <div style="margin: -10px 0 10px 120px">-->
+      <!--            <el-checkbox v-model="form.checked">创建跟进任务</el-checkbox>-->
+      <!--          </div>-->
+      <!--        </el-col>-->
+      <!--      </el-row>-->
+      <!--      <el-row :gutter="20">-->
+      <!--        <el-col :span="12">-->
+      <!--          <el-form-item label="开始时间" prop="title">-->
+      <!--            <el-date-picker v-model="form.value1" placeholder="选择时间" style="width: 100%" type="datetime" />-->
+      <!--          </el-form-item>-->
+      <!--        </el-col>-->
+      <!--        <el-col :span="12">-->
+      <!--          <el-form-item label="结束时间" prop="title">-->
+      <!--            <el-date-picker v-model="form.value1" placeholder="选择时间" style="width: 100%" type="datetime" />-->
+      <!--          </el-form-item>-->
+      <!--        </el-col>-->
+      <!--        <el-col :span="12">-->
+      <!--          <el-form-item label="负责人员" prop="title">-->
+      <!--            <el-input v-model="form.title" />-->
+      <!--          </el-form-item>-->
+      <!--        </el-col>-->
+      <!--        <el-col :span="12">-->
+      <!--          <el-form-item label="跟进内容" prop="followContent">-->
+      <!--            <el-input v-model="form.followContent" />-->
+      <!--          </el-form-item>-->
+      <!--        </el-col>-->
+      <!--        <el-col :span="12">-->
+      <!--          <el-form-item label="任务提醒" prop="title">-->
+      <!--            <el-input v-model="form.title" />-->
+      <!--          </el-form-item>-->
+      <!--        </el-col>-->
+      <!--        <el-col :span="12">-->
+      <!--          <el-form-item label="提醒方式" prop="title">-->
+      <!--            <el-checkbox v-model="form.checked">系统消息</el-checkbox>-->
+      <!--          </el-form-item>-->
+      <!--        </el-col>-->
+      <!--      </el-row>-->
+      <el-row :gutter="20">
+        <el-col :span="24">
+          <el-form-item label="产品(含版本)" prop="title">
+            <el-button size="mini" type="primary" @click="handleSelectProduct">添加产品</el-button>
+
+            <el-table>
+              <el-table-column align="center" label="产品名称" prop="custCode" />
+              <el-table-column align="center" label="产品类别" prop="custName" />
+              <el-table-column align="center" label="单位" prop="abbrName" />
+              <el-table-column align="center" label="价格" prop="custLocation" />
+              <el-table-column align="center" label="数量" prop="custIndustry" />
+              <el-table-column align="center" label="操作" width="80">
+                <template #default="{ row }">
+                  <el-button type="text">删除{{ row }}</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="save">提 交</el-button>
+      <el-button @click="close">重 置</el-button>
+    </div>
+    <!-- 选择客户弹窗 -->
+    <select-customer ref="selectCustomer" @save="selectCustomer" />
+    <!-- 选择客户弹窗 -->
+    <select-contact ref="selectContact" :query-params="queryContact" @save="selectContact" />
+    <!-- 选择经销商弹窗 -->
+    <select-distributor ref="selectDistributor" @save="selectDistributor" />
+    <!-- 选择产品弹窗 -->
+    <select-product ref="selectProduct" @save="selectProduct" />
+  </el-dialog>
+</template>
+
+<script>
+  import businessApi from '@/api/proj/business'
+  import SelectContact from '@/components/select/SelectContact'
+  import SelectCustomer from '@/components/select/SelectCustomer'
+  import SelectDistributor from '@/components/select/SelectDistributor'
+  import SelectProduct from '@/components/select/SelectProduct'
+
+  export default {
+    name: 'BusinessEdit',
+    components: { SelectContact, SelectProduct, SelectDistributor, SelectCustomer },
+    data() {
+      return {
+        form: {
+          title: '',
+          custId: undefined,
+          custName: undefined,
+          contactName: undefined,
+          distributorName: undefined,
+        },
+        rules: {
+          title: [{ required: true, trigger: 'blur', message: '请输入标题' }],
+        },
+        title: '',
+        dialogFormVisible: false,
+        queryContact: {},
+      }
+    },
+    created() {},
+    methods: {
+      handleSelectCustomer() {
+        this.$refs.selectCustomer.open()
+      },
+      handleSelectContact() {
+        if (!this.queryContact.custId) {
+          this.$message.warning('请选择联系人')
+        }
+        this.$refs.selectContact.open()
+      },
+      handleSelectDistributor() {
+        this.$refs.selectDistributor.open()
+      },
+      handleSelectProduct() {
+        this.$refs.selectProduct.open()
+      },
+      selectCustomer(val) {
+        if (val && val.length > 0) {
+          this.queryContact.custId = val[0].id
+        }
+        this.form.custName = val.map((item) => item.custName).join()
+        console.log(this.form.custName)
+        console.log(val)
+      },
+      selectContact(val) {
+        this.form.contactName = val.map((item) => item.cuctName).join()
+        console.log(this.form.contactName)
+
+        console.log(val)
+      },
+      selectDistributor(val) {
+        this.form.distributorName = val.map((item) => item.distName).join()
+        console.log(this.form.distributorName)
+
+        console.log(val)
+      },
+      selectProduct(val) {
+        console.log(val)
+      },
+      showEdit(row) {
+        if (!row) {
+          this.title = '添加'
+        } else {
+          this.title = '编辑'
+          this.form = Object.assign({}, row)
+        }
+        this.dialogFormVisible = true
+      },
+      close() {
+        this.$refs['form'].resetFields()
+        this.form = this.$options.data().form
+        this.dialogFormVisible = false
+      },
+      save() {
+        this.$refs['form'].validate(async (valid) => {
+          if (valid) {
+            const { msg } = await businessApi.doEdit(this.form)
+            this.$baseMessage(msg, 'success')
+            this.$emit('fetch-data')
+            this.close()
+          } else {
+            return false
+          }
+        })
+      },
+    },
+  }
+</script>

+ 66 - 0
src/views/proj/business/components/Transfer.vue

@@ -0,0 +1,66 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogFormVisible" width="500px" @close="close">
+    <el-form ref="form" label-width="80px" :model="form" :rules="rules">
+      <el-form-item label="接收对象" prop="userName">
+        <el-input
+          v-model="form.userName"
+          placeholder="选择人员"
+          readonly
+          suffix-icon="el-icon-user-solid"
+          @focus="selectUser" />
+      </el-form-item>
+      <el-form-item label="备注信息" prop="remark">
+        <el-input
+          v-model="form.remark"
+          maxlength="300"
+          placeholder="请输入备注信息"
+          rows="5"
+          show-word-limit
+          type="textarea" />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="close">取 消</el-button>
+      <el-button type="primary" @click="save">确 定</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script>
+  import businessApi from '@/api/proj/business'
+
+  export default {
+    name: 'Transfer',
+    data() {
+      return {
+        form: {},
+        rules: {
+          userName: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        },
+        title: '转移项目',
+        dialogFormVisible: false,
+      }
+    },
+    methods: {
+      selectUser() {},
+      open() {
+        this.dialogFormVisible = true
+      },
+      close() {
+        this.$refs['form'].resetFields()
+        this.form = this.$options.data().form
+        this.dialogFormVisible = false
+      },
+      save() {
+        this.$refs['form'].validate(async (valid) => {
+          if (valid) {
+            const { msg } = await businessApi.businessTransfer(this.form)
+            this.$baseMessage(msg, 'success')
+            this.$emit('fetch-data')
+            this.close()
+          }
+        })
+      },
+    },
+  }
+</script>

+ 232 - 0
src/views/proj/business/index.vue

@@ -0,0 +1,232 @@
+<template>
+  <div class="business-container">
+    <vab-query-form>
+      <vab-query-form-top-panel>
+        <el-form ref="queryForm" :inline="true" :model="queryForm" @submit.native.prevent>
+          <el-form-item prop="nboName">
+            <el-input v-model="queryForm.nboName" clearable placeholder="商机标题" @keyup.enter.native="queryData" />
+          </el-form-item>
+
+          <el-form-item prop="custName">
+            <el-input
+              v-model="queryForm.custName"
+              clearable
+              placeholder="客户名称"
+              size="small"
+              @keyup.enter.native="queryData" />
+          </el-form-item>
+
+          <el-form-item prop="nboType">
+            <el-select v-model="queryForm.nboType" clearable placeholder="商机类别">
+              <el-option v-for="dict in nboTypeOptions" :key="dict.key" :label="dict.value" :value="dict.key" />
+            </el-select>
+          </el-form-item>
+          <el-form-item prop="saleName">
+            <el-input
+              v-model="queryForm.saleName"
+              clearable
+              placeholder="归属人员"
+              size="small"
+              @keyup.enter.native="queryData" />
+          </el-form-item>
+
+          <el-form-item>
+            <el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
+            <el-button icon="el-icon-refresh" type="primary" @click="resetQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+      </vab-query-form-top-panel>
+
+      <vab-query-form-left-panel :span="12">
+        <el-button icon="el-icon-plus" type="primary" @click="handleEdit">新增项目</el-button>
+        <el-button icon="el-icon-refresh" type="primary" @click="handleTransfer">转移项目</el-button>
+        <el-button icon="el-icon-plus" type="primary" @click="handleEdit">创建任务</el-button>
+        <el-button icon="el-icon-plus" type="primary" @click="handleEdit">创建工单</el-button>
+        <el-button icon="el-icon-plus" type="primary" @click="handleEdit">创建合同</el-button>
+        <!--        <el-button icon="el-icon-delete" type="danger" @click="handleDelete">删除</el-button>-->
+      </vab-query-form-left-panel>
+      <vab-query-form-right-panel :span="12">
+        <table-tool :check-list.sync="checkList" :columns="columns" />
+      </vab-query-form-right-panel>
+    </vab-query-form>
+
+    <el-table v-loading="listLoading" :data="list" :height="height" @selection-change="setSelectRows">
+      <el-table-column align="center" show-overflow-tooltip type="selection" />
+      <el-table-column
+        v-for="(item, index) in finallyColumns"
+        :key="index"
+        align="center"
+        :label="item.label"
+        :prop="item.prop"
+        show-overflow-tooltip
+        :sortable="item.sortable"
+        :width="item.width" />
+
+      <el-table-column align="center" label="操作" width="120">
+        <template #default="{ row }">
+          <el-button type="text" @click="handleEdit(row)">跟进</el-button>
+          <el-button type="text" @click="handleEdit(row)">编辑</el-button>
+          <!--          <el-button type="text" @click="handleDelete(row)">删除</el-button>-->
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      background
+      :current-page="queryForm.pageNo"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
+    <edit ref="edit" @fetch-data="fetchData" />
+    <transfer ref="transfer" @fetch-data="fetchData" />
+  </div>
+</template>
+
+<script>
+  import businessApi from '@/api/proj/business'
+  import Edit from './components/BusinessEdit'
+  import Transfer from './components/Transfer'
+  import TableTool from '@/components/table/TableTool'
+
+  export default {
+    name: 'Business',
+    components: { Edit, Transfer, TableTool },
+    data() {
+      return {
+        height: this.$baseTableHeight(2),
+        checkList: [],
+        columns: [
+          {
+            label: '商机标题',
+            width: 'auto',
+            prop: 'nboName',
+            sortable: true,
+            disableCheck: true,
+          },
+          {
+            label: '关联客户',
+            width: 'auto',
+            prop: 'custName',
+          },
+          {
+            label: '审批状态',
+            width: 'auto',
+            prop: 'approStatus',
+          },
+          {
+            label: '商机状态',
+            width: 'auto',
+            prop: 'nboPhase',
+          },
+          {
+            label: '商机类别',
+            width: 'auto',
+            prop: 'nboType',
+          },
+          {
+            label: '商机金额',
+            width: 'auto',
+            prop: 'nboBudget',
+          },
+          {
+            label: '最后跟进时间',
+            width: 'auto',
+            prop: 'finalFollowTime',
+          },
+          {
+            label: '下次跟进时间',
+            width: 'auto',
+            prop: 'nextFollowTime',
+          },
+        ],
+        list: [],
+        listLoading: true,
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        selectRows: '',
+        queryForm: {
+          pageNo: 1,
+          pageSize: 10,
+          nboName: undefined,
+          custName: undefined,
+          nboType: undefined,
+          saleName: undefined,
+        },
+        nboTypeOptions: [],
+      }
+    },
+    computed: {
+      finallyColumns() {
+        return this.columns.filter((item) => this.checkList.includes(item.label))
+      },
+    },
+    created() {
+      this.fetchData()
+      this.getDicts('proj-nbo-type').then((response) => {
+        this.nboTypeOptions = response.data.values || []
+      })
+    },
+    methods: {
+      setSelectRows(val) {
+        this.selectRows = val
+      },
+      handleTransfer(row) {
+        this.$refs['transfer'].open(row)
+      },
+      handleEdit(row) {
+        if (row.id) {
+          this.$refs['edit'].showEdit(row)
+        } else {
+          this.$refs['edit'].showEdit()
+        }
+      },
+      handleDelete(row) {
+        if (row.id) {
+          this.$baseConfirm('你确定要删除当前项吗', null, async () => {
+            const { msg } = await businessApi.doDelete({ ids: [row.id] })
+            this.$baseMessage(msg, 'success')
+            await this.fetchData()
+          })
+        } else {
+          if (this.selectRows.length > 0) {
+            const ids = this.selectRows.map((item) => item.id)
+            this.$baseConfirm('你确定要删除选中项吗', null, async () => {
+              const { msg } = await businessApi.doDelete({ ids })
+              this.$baseMessage(msg, 'success')
+              await this.fetchData()
+            })
+          } else {
+            this.$baseMessage('未选中任何行', 'error')
+            return false
+          }
+        }
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNo = val
+        this.fetchData()
+      },
+      queryData() {
+        this.queryForm.pageNo = 1
+        this.fetchData()
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.resetForm('queryForm')
+        this.fetchData()
+      },
+      async fetchData() {
+        this.listLoading = true
+        const { data } = await businessApi.getList(this.queryForm)
+        const { list, total } = data
+        this.list = list
+        this.total = total
+        this.listLoading = false
+      },
+    },
+  }
+</script>