Преглед изворни кода

feature(订单管理系统):
1、项目管理.this.$refs.table.doLayout() 修改
2、项目添加和项目编辑分开
3、跟进时间和联系时间不允许修改

niezch пре 3 година
родитељ
комит
5a6e45b94a

+ 516 - 0
src/views/proj/business/components/BusinessAdd.vue

@@ -0,0 +1,516 @@
+<template>
+  <el-dialog append-to-body :title="title" :visible.sync="dialogFormVisible" width="60%" @close="close">
+    <el-steps :active="activeSteps" align-center style="margin: -15px 0 15px 0">
+      <el-step title="创建项目" />
+      <el-step title="添加产品" />
+      <!--      <el-step title="跟进日程" />-->
+    </el-steps>
+
+    <el-form ref="form" :model="form" :rules="rules">
+      <el-row v-if="activeSteps === 1" :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="关联客户" prop="custName">
+            <el-input
+              v-model="form.custName"
+              :disabled="Boolean(custInfo.custName)"
+              readonly
+              suffix-icon="el-icon-search"
+              @focus="handleSelectCustomer" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="产品线" prop="productLine">
+            <el-select v-model="form.productLine" placeholder="请选择" style="width: 100%" @change="changeProductLine">
+              <el-option v-for="item in productLineOptions" :key="item.key" :label="item.value" :value="item.key" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="项目名称" prop="nboName">
+            <el-input v-model="form.nboName" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="主要联系人" prop="contactName">
+            <el-input v-model="form.contactName" readonly suffix-icon="el-icon-search" @focus="handleSelectContact" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="职位" prop="contactPostion">
+            <el-input v-model="form.contactPostion" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="联系电话" prop="contactTelephone">
+            <el-input v-model="form.contactTelephone" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="项目来源" prop="nboSource">
+            <el-select v-model="form.nboSource" clearable placeholder="项目来源" style="width: 100%">
+              <el-option v-for="dict in nboSourceOptions" :key="dict.key" :label="dict.value" :value="dict.key" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="销售工程师" prop="saleName">
+            <el-input
+              v-model="form.saleName"
+              :disabled="form.id > 0"
+              readonly
+              suffix-icon="el-icon-search"
+              @focus="handleSelectSale" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="销售模式" prop="salesModel">
+            <el-select
+              v-model="form.salesModel"
+              clearable
+              placeholder="销售模式"
+              style="width: 100%"
+              @change="changeSalesModel">
+              <el-option v-for="dict in salesModelOptions" :key="dict.key" :label="dict.value" :value="dict.key" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item
+            label="经销商/代理商"
+            prop="distributorName"
+            :required="form.salesModel && form.salesModel !== '10'">
+            <el-input
+              v-model="form.distributorName"
+              :disabled="form.salesModel === '10'"
+              readonly
+              suffix-icon="el-icon-search"
+              @focus="handleSelectDistributor" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="项目预算" prop="nboBudget">
+            <amount-input v-model.trim="form.nboBudget" placeholder="请输入金额" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="是否大项目" prop="isBig">
+            <el-select v-model="form.isBig" placeholder="请选择" style="width: 100%">
+              <el-option v-for="item in yesOrNoOptions" :key="item.key" :label="item.value" :value="item.key" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <!--        <el-col :span="8">-->
+        <!--          <el-form-item label="预计成交价格" prop="estTransPrice">-->
+        <!--            <amount-input v-model.trim="form.estTransPrice" placeholder="请输入金额" />-->
+        <!--          </el-form-item>-->
+        <!--        </el-col>-->
+        <el-col :span="8">
+          <el-form-item label="预计成交时间" prop="estTransTime">
+            <el-date-picker v-model="form.estTransTime" placeholder="选择日期" style="width: 100%" type="datetime" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="计划采购时间" prop="planPurchaseTime">
+            <el-date-picker
+              v-model="form.planPurchaseTime"
+              placeholder="选择日期"
+              style="width: 100%"
+              type="datetime" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="风险情况" prop="riskProfile">
+            <el-input v-model="form.riskProfile" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="困难点" prop="difficulty">
+            <el-input v-model="form.difficulty" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="竞争公司" prop="competitor">
+            <el-input v-model="form.competitor" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="介入情况" prop="intervention">
+            <el-input v-model="form.intervention" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="备注信息" prop="remark">
+            <el-input v-model="form.remark" placeholder="请输入备注信息" rows="3" show-word-limit type="textarea" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row v-if="activeSteps === 2" :gutter="20">
+        <el-col :span="24">
+          <el-button size="mini" type="primary" @click="handleSelectProduct">添加产品</el-button>
+          <product-table
+            ref="productTable"
+            :product-data="productData"
+            @changeProductData="changeProductData"
+            @delProductData="delProductData" />
+        </el-col>
+      </el-row>
+
+      <!--      <el-row v-if="activeSteps === 3" :gutter="20">-->
+      <!--        <el-col :span="12">-->
+      <!--          <el-form-item label="跟进时间" prop="followTime">-->
+      <!--            <el-date-picker v-model="form.followTime" placeholder="选择时间" style="width: 100%" type="datetime" />-->
+      <!--          </el-form-item>-->
+      <!--        </el-col>-->
+      <!--        <el-col :span="12">-->
+      <!--          <el-form-item label="负责人员" prop="followUserName">-->
+      <!--            <el-input-->
+      <!--              v-model="form.followUserName"-->
+      <!--              readonly-->
+      <!--              suffix-icon="el-icon-search"-->
+      <!--              @focus="handleSelectFollowUser" />-->
+      <!--          </el-form-item>-->
+      <!--        </el-col>-->
+      <!--        <el-col :span="24">-->
+      <!--          <el-form-item label="跟进内容" prop="followContent">-->
+      <!--            <el-input-->
+      <!--              v-model="form.followContent"-->
+      <!--              placeholder="请输入跟进内容"-->
+      <!--              rows="5"-->
+      <!--              show-word-limit-->
+      <!--              type="textarea" />-->
+      <!--          </el-form-item>-->
+      <!--        </el-col>-->
+      <!--      </el-row>-->
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button v-if="activeSteps !== 1" type="primary" @click="activeSteps--">上一步</el-button>
+      <el-button v-if="activeSteps !== 2" type="primary" @click="nextStep">下一步</el-button>
+      <el-button v-if="activeSteps === 2" type="primary" @click="save">提 交</el-button>
+    </div>
+    <!-- 选择客户弹窗 -->
+    <select-customer ref="selectCustomer" @save="selectCustomer" />
+    <!-- 选择客户联系人弹窗 -->
+    <select-contact
+      ref="selectContact"
+      :default-customer="customerInfo"
+      :query-params="queryContact"
+      @save="selectContact" />
+    <!-- 选择销售工程师弹窗 -->
+    <select-user
+      ref="selectSales"
+      :query-params="{ roles: ['SalesEngineer', 'ProductLineManager'] }"
+      @save="selectSales" />
+    <!-- 选择经销商弹窗 -->
+    <select-distributor ref="selectDistributor" @save="selectDistributor" />
+    <!-- 选择产品弹窗 -->
+    <select-product ref="selectProduct" multiple @save="selectProduct" />
+    <!-- 选择跟进负责人弹窗 -->
+    <select-user ref="selectFollowUser" @save="selectFollowUser" />
+  </el-dialog>
+</template>
+
+<script>
+  import businessApi from '@/api/proj/business'
+  import AmountInput from '@/components/currency'
+  import { mapGetters } from 'vuex'
+  import ProductTable from './ProductTable'
+  import SelectContact from '@/components/select/SelectCustomerContact'
+  import SelectCustomer from '@/components/select/SelectCustomer'
+  import SelectUser from '@/components/select/SelectUser'
+  import SelectDistributor from '@/components/select/SelectDistributor'
+  import SelectProduct from '@/components/select/SelectProduct'
+
+  export default {
+    name: 'BusinessEdit',
+    components: {
+      AmountInput,
+      ProductTable,
+      SelectContact,
+      SelectProduct,
+      SelectDistributor,
+      SelectCustomer,
+      SelectUser,
+    },
+    props: {
+      // 客户信息{ custId: id, custName: custName}
+      custInfo: {
+        type: Object,
+        default() {
+          return {}
+        },
+      },
+    },
+    data() {
+      const validateDistributor = (rule, value, callback) => {
+        if (!value && this.form.salesModel && this.form.salesModel !== '10') callback(new Error('请选择经销商/代理商'))
+        else callback()
+      }
+      return {
+        activeSteps: 1,
+        form: {
+          nboName: '',
+          custId: undefined,
+          custName: '',
+          obtainTime: undefined,
+          nboSource: undefined,
+          contactId: undefined,
+          contactName: undefined,
+          contactPostion: undefined,
+          contactTelephone: undefined,
+          saleId: undefined,
+          saleName: undefined,
+          distributorId: undefined,
+          distributorName: undefined,
+          productLine: undefined,
+          nboBudget: 0,
+          isBig: '20',
+          planPurchaseTime: undefined,
+          estTransTime: undefined,
+          estTransPrice: undefined,
+          riskProfile: undefined,
+          difficulty: undefined,
+          competitor: undefined,
+          intervention: undefined,
+          remark: undefined,
+          products: undefined,
+
+          // 跟进
+          followTime: new Date(),
+          followUserId: undefined,
+          followUserName: undefined,
+          followContent: undefined,
+        },
+        rules: {
+          nboName: [{ required: true, trigger: ['blur', 'change'], message: '请输入项目名称' }],
+          custName: [{ required: true, trigger: ['blur', 'change'], message: '请选择关联客户' }],
+          nboSource: [{ required: true, trigger: ['blur', 'change'], message: '请选择项目来源' }],
+          contactName: [{ required: true, trigger: ['blur', 'change'], message: '请选择主要联系人' }],
+          saleName: [{ required: true, trigger: ['blur', 'change'], message: '请选择销售工程师' }],
+          salesModel: [{ required: true, trigger: ['blur', 'change'], message: '请选择销售模式' }],
+          distributorName: [
+            { validator: validateDistributor, trigger: ['blur', 'change'], message: '请选择经销商/代理商' },
+          ],
+          isBig: [{ required: true, trigger: ['blur', 'change'], message: '请选择是否大项目' }],
+          productLine: [{ required: true, trigger: ['blur', 'change'], message: '请选择产品线' }],
+          // 跟进
+          followTime: [{ required: true, trigger: ['blur', 'change'], message: '请输入跟进时间' }],
+          followContent: [{ required: true, trigger: ['blur', 'change'], message: '请输入跟进内容' }],
+        },
+        title: '',
+        dialogFormVisible: false,
+        nboSourceOptions: [],
+        salesModelOptions: [],
+        productLineOptions: [],
+        yesOrNoOptions: [],
+        queryContact: {},
+        customerInfo: {},
+        productData: [],
+      }
+    },
+    watch: {
+      custInfo: function (val) {
+        this.form.custId = val.custId
+        this.queryContact.custId = val.custId
+        this.form.custName = val.custName
+        this.customerInfo = val
+      },
+    },
+    computed: {
+      ...mapGetters({
+        userId: 'user/id',
+        nickName: 'user/nickName',
+        roleKeys: 'user/roleKeys',
+      }),
+    },
+    created() {},
+    mounted() {
+      this.getOptions()
+    },
+    methods: {
+      getOptions() {
+        Promise.all([
+          this.getDicts('proj_nbo_source'),
+          this.getDicts('proj_sales_model'),
+          this.getDicts('sys_product_line'),
+          this.getDicts('sys_yes_no'),
+        ]).then(([nboSource, salesModel, productLine, yesOrNo]) => {
+          this.nboSourceOptions = nboSource.data.values || []
+          this.salesModelOptions = salesModel.data.values || []
+          this.productLineOptions = productLine.data.values || []
+          this.yesOrNoOptions = yesOrNo.data.values || []
+        })
+      },
+      nextStep() {
+        console.log(typeof this.form.nboBudget)
+        if (this.activeSteps === 1) {
+          this.$refs['form'].validate(async (valid) => {
+            if (valid) {
+              this.activeSteps++
+            }
+          })
+        } else if (this.activeSteps === 2) {
+          this.form.products = this.productData
+          this.activeSteps++
+        }
+      },
+      changeSalesModel() {
+        if (this.form.salesModel === '10') {
+          this.form.distributorId = undefined
+          this.form.distributorName = undefined
+        }
+      },
+      changeProductLine() {
+        this.form.nboName = this.form.custName + this.selectDictLabel(this.productLineOptions, this.form.productLine)
+      },
+      handleSelectCustomer() {
+        this.$refs.selectCustomer.open()
+      },
+      handleSelectContact() {
+        if (!this.queryContact.custId) {
+          this.$message.warning('请先选择客户')
+          return
+        }
+        this.$refs.selectContact.open()
+      },
+      handleSelectSale() {
+        this.$refs.selectSales.open()
+      },
+      handleSelectDistributor() {
+        this.$refs.selectDistributor.open()
+      },
+      handleSelectProduct() {
+        this.$refs.selectProduct.open()
+      },
+      handleSelectFollowUser() {
+        this.$refs.selectFollowUser.open()
+      },
+      selectCustomer(val) {
+        if (val && val.length > 0) {
+          this.queryContact.custId = val[0].id
+          this.customerInfo = {
+            custId: val[0].id,
+            custName: val[0].custName,
+          }
+          this.form.custId = val[0].id
+          this.form.custName = val.map((item) => item.custName).join()
+          this.form.contactId = undefined
+          this.form.contactName = undefined
+          this.form.contactPostion = undefined
+          this.form.contactTelephone = undefined
+
+          let productLineName = this.selectDictLabel(this.productLineOptions, this.form.productLine)
+          this.form.nboName = this.form.custName + productLineName
+        }
+      },
+      selectContact(val) {
+        if (val && val.length > 0) {
+          this.form.contactId = val[0].id
+          this.form.contactName = val.map((item) => item.cuctName).join()
+          this.form.contactPostion = val.map((item) => item.postion).join()
+          this.form.contactTelephone = val.map((item) => item.telephone).join()
+        }
+      },
+      selectSales(val) {
+        if (val && val.length > 0) {
+          this.form.saleId = val[0].id
+          this.form.saleName = val.map((item) => item.nickName).join()
+        }
+      },
+      selectDistributor(val) {
+        if (val && val.length > 0) {
+          this.form.distributorId = val[0].id
+          this.form.distributorName = val.map((item) => item.distName).join()
+        }
+      },
+      selectFollowUser(val) {
+        this.form.followUserName = val.map((item) => item.nickName).join()
+      },
+      selectProduct(data) {
+        let projData = data.map((item) => ({
+          prodId: item.id,
+          prodCode: item.prodCode,
+          prodName: item.prodName,
+          prodClass: item.prodClass,
+          guidPrice: item.guidPrice,
+          prodPrice: item.marketPrice,
+          prodNum: 1,
+        }))
+        this.productData.push(...projData)
+        this.productData = this.removeDuplicateObj(this.productData)
+      },
+      // 数组对象去重
+      removeDuplicateObj(arr) {
+        let obj = {}
+        arr = arr.reduce((newArr, next) => {
+          obj[next.prodId] ? '' : (obj[next.prodId] = true && newArr.push(next))
+          return newArr
+        }, [])
+        return arr
+      },
+      // 修改产品列表数据
+      changeProductData(data) {
+        this.productData = this.productData.map((item) => {
+          return item.prodId === data.prodId ? data : item
+        })
+      },
+      delProductData(data) {
+        this.productData = this.productData.filter((item) => item.prodId !== data.prodId)
+      },
+      async getProductData(busId) {
+        const { data } = await businessApi.getProductByBusinessId({ id: busId })
+        if (data) {
+          this.productData = data
+        }
+      },
+      showEdit(row) {
+        this.activeSteps = 1
+        this.productData = []
+        if (!row) {
+          this.title = '添加'
+          if (this.roleKeys.includes('SalesEngineer') || this.roleKeys.includes('ProductLineManager')) {
+            this.form.saleId = this.userId
+            this.form.saleName = this.nickName
+          }
+        } else {
+          this.title = '编辑'
+          this.form = Object.assign({}, row)
+          this.queryContact.custId = this.form.custId
+          this.customerInfo = {
+            custId: this.form.custId,
+            custName: this.form.custName,
+          }
+          this.getProductData(row.id)
+        }
+        this.dialogFormVisible = true
+      },
+      close() {
+        this.$refs['form'].resetFields()
+        this.form = this.$options.data().form
+        this.dialogFormVisible = false
+      },
+      save() {
+        this.form.products = this.productData
+        this.$refs['form'].validate(async (valid) => {
+          if (valid) {
+            let res
+            if (this.form.id) {
+              res = await businessApi.doEdit(this.form)
+            } else {
+              res = await businessApi.doAdd(this.form)
+            }
+            this.$baseMessage(res.msg, 'success')
+            this.$emit('fetch-data')
+            this.close()
+          } else {
+            return false
+          }
+        })
+      },
+    },
+  }
+</script>
+<style lang="scss" scoped>
+  .el-form-item--small.el-form-item {
+    margin-bottom: 10px;
+  }
+</style>

+ 15 - 5
src/views/proj/business/components/BusinessEdit.vue

@@ -140,12 +140,22 @@
         </el-col>
         <el-col :span="8">
           <el-form-item label="下次联系时间" prop="nextFollowTime">
-            <el-date-picker v-model="form.nextFollowTime" placeholder="选择日期" style="width: 100%" type="datetime" />
+            <el-date-picker
+              v-model="form.nextFollowTime"
+              :disabled="true"
+              placeholder="选择日期"
+              style="width: 100%"
+              type="datetime" />
           </el-form-item>
         </el-col>
         <el-col :span="8">
           <el-form-item label="最新跟进时间" prop="finalFollowTime">
-            <el-date-picker v-model="form.finalFollowTime" placeholder="选择日期" style="width: 100%" type="datetime" />
+            <el-date-picker
+              v-model="form.finalFollowTime"
+              :disabled="true"
+              placeholder="选择日期"
+              style="width: 100%"
+              type="datetime" />
           </el-form-item>
         </el-col>
         <el-col :span="8">
@@ -217,18 +227,18 @@
             <el-input v-model="form.accendant" />
           </el-form-item>
         </el-col>
-        <el-col :span="8">
+        <!-- <el-col :span="8">
           <el-form-item label="是否采纳大数技术参数" prop="isAdoptDashoo">
             <el-select
               v-model="form.isAdoptDashoo"
               clearable
               placeholder="是否采纳"
               style="width: 100%"
-              @change="changeSalesModel">
+              @change="changeSalesModel" :disabled="true">
               <el-option v-for="dict in yesOrNoOptions" :key="dict.key" :label="dict.value" :value="dict.key" />
             </el-select>
           </el-form-item>
-        </el-col>
+        </el-col> -->
         <el-col :span="24">
           <el-form-item label="备注信息" prop="remark">
             <el-input v-model="form.remark" placeholder="请输入备注信息" rows="3" show-word-limit type="textarea" />

+ 6 - 3
src/views/proj/business/index.vue

@@ -190,6 +190,8 @@
       :total="total"
       @current-change="handleCurrentChange"
       @size-change="handleSizeChange" />
+    <!-- 添加 -->
+    <add ref="add" @fetch-data="fetchData" />
     <!-- 编辑 -->
     <edit ref="edit" @fetch-data="fetchData" />
     <!-- 转移 -->
@@ -202,13 +204,14 @@
 <script>
   import businessApi from '@/api/proj/business'
   import Edit from './components/BusinessEdit'
+  import Add from './components/BusinessAdd'
   import Transfer from './components/Transfer'
   import FollowAdd from './components/FollowAdd'
   import TableTool from '@/components/table/TableTool'
 
   export default {
     name: 'Business',
-    components: { Edit, Transfer, TableTool, FollowAdd },
+    components: { Edit, Transfer, TableTool, FollowAdd, Add },
     data() {
       return {
         tableKey: 0,
@@ -432,7 +435,7 @@
     watch: {
       showColumns: function () {
         this.tableKey++
-        this.$nextTick(() => this.$refs.tableTool.doLayout())
+        this.$nextTick(() => this.$refs.busTable.doLayout())
       },
       activeName(newValue) {
         this.tableType = 'businessTable' + this.selectDictLabel(this.nboTypeOptions, newValue)
@@ -541,7 +544,7 @@
         if (row.id) {
           this.$refs['edit'].showEdit(row)
         } else {
-          this.$refs['edit'].showEdit()
+          this.$refs['add'].showEdit()
         }
       },
       handleDelete(row) {