Ver Fonte

feature(工单): 1、支持工单支持手动创建,类型为“经销商支持”
2、经销商支持、技术文件支持、售前讲解支持,销售总结时可以评价

likai há 2 anos atrás
pai
commit
03f6aa52d4

+ 314 - 0
src/views/work/order/components/AddDealerSupportWorkOrder.vue

@@ -0,0 +1,314 @@
+<template>
+  <el-dialog append-to-body :title="title" :visible.sync="dialogFormVisible" @close="close">
+    <el-form ref="form" label-position="top" label-width="100px" :model="form" :rules="rules">
+      <el-row :gutter="20">
+        <!-- <el-col :span="12">
+          <el-form-item label="工单名称" prop="name">
+            <el-input v-model="form.name" />
+          </el-form-item>
+        </el-col> -->
+        <el-col :span="12">
+          <el-form-item label="支持人员" prop="assignUserName">
+            <el-input v-model="form.assignUserName" readonly suffix-icon="el-icon-search" @focus="handleSelectUser" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="经销商" prop="dealerNames">
+            <el-input
+              v-model="form.dealerNames"
+              readonly
+              suffix-icon="el-icon-search"
+              @focus="handleSelectDistributor('10')" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="代理商" prop="agentNames">
+            <el-input
+              v-model="form.agentNames"
+              readonly
+              suffix-icon="el-icon-search"
+              @focus="handleSelectDistributor('20')" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <!--      钉钉审批流表单-->
+      <DingTalkFromToVue ref="dingTalkFrom" :col-span="12" />
+      <!--      钉钉审批流表单-->
+      <!--      <el-row :gutter="20">-->
+
+      <!--      </el-row>-->
+    </el-form>
+    <template #footer>
+      <el-button @click="close">取 消</el-button>
+      <el-button v-if="!form.id" :loading="loading" type="primary" @click="save">确 定</el-button>
+    </template>
+
+    <!-- 选择支持人员弹窗 -->
+    <select-user ref="selectUser" @save="selectUser" />
+    <!-- 选择经销商弹窗 -->
+    <select-distributor ref="selectDistributor" :multiple="true" :query-params="queryParams" @save="saveDistributors" />
+  </el-dialog>
+</template>
+
+<script>
+  import workApi from '@/api/work/index'
+  import typeApi from '@/api/work/type'
+  import SelectUser from '@/components/select/SelectUser'
+  import DingTalkFromToVue from './DingTalkFromToVue.vue'
+  import { mapGetters } from 'vuex'
+  import SelectDistributor from '@/components/select/SelectDistributor'
+
+  export default {
+    name: 'WorkOrderEdit',
+    components: {
+      SelectUser,
+      DingTalkFromToVue,
+      SelectDistributor,
+    },
+    props: {
+      businessInfo: {
+        type: Object,
+        default: () => {},
+      },
+    },
+    data() {
+      return {
+        queryParams: {
+          distType: '',
+        },
+        loading: false,
+        form: {
+          nboId: undefined,
+          nboName: undefined,
+          nboCode: undefined,
+          custId: undefined,
+          custName: undefined,
+          name: undefined,
+          orderTypeId: undefined,
+          orderTypeName: undefined,
+          assignUserId: undefined,
+          assignUserName: undefined,
+          formData: undefined,
+          dingTalkFormData: undefined,
+          feedback: undefined,
+          // file: undefined,
+          remark: undefined,
+          endTime: undefined,
+          dingtalkForm: undefined,
+          trialTimeStart: undefined,
+          trialTimeEnd: undefined,
+          expectTime: undefined,
+          supportTime: undefined,
+          dealerNames: undefined,
+          agentNames: undefined,
+        },
+        rules: {
+          name: [{ required: true, message: '不能为空', trigger: ['blur', 'change'] }],
+          orderTypeId: [{ required: true, message: '不能为空', trigger: ['blur', 'change'] }],
+          assignUserName: [{ required: true, message: '不能为空', trigger: ['blur', 'change'] }],
+        },
+        title: '',
+        dialogFormVisible: false,
+        orderTypeList: [],
+        dingtalkForm: undefined,
+      }
+    },
+    computed: {
+      ...mapGetters({
+        userId: 'user/id',
+        nickName: 'user/nickName',
+      }),
+    },
+    mounted() {},
+    methods: {
+      async getOrderTypeList() {
+        this.orderTypeList.splice(0, this.orderTypeList.length)
+        const { data } = await typeApi.getList()
+        for (let item of data.list) {
+          this.orderTypeList.push(item)
+        }
+        this.changeOrderType()
+      },
+      changeOrderType() {
+        let item = this.orderTypeList.find((item) => {
+          return item.name === '经销商支持'
+        })
+        this.form.orderTypeId = item.id
+        this.form.orderTypeName = item.name
+        this.form.orderTypeCode = item.workflowCode
+        this.dingtalkForm = JSON.parse(item.formColumn)
+        for (let index in this.dingtalkForm.items) {
+          // if (this.dingtalkForm.items[index].props.label === '项目编码') {
+          //   this.dingtalkForm.items[index].props.value = this.form.nboCode
+          //   this.dingtalkForm.items[index].props.disabled = true
+          // }
+          // if (this.dingtalkForm.items[index].props.label === '项目名称') {
+          //   this.dingtalkForm.items[index].props.value = this.form.nboName
+          //   this.dingtalkForm.items[index].props.disabled = true
+          // }
+          // if (this.dingtalkForm.items[index].props.label === '客户名称') {
+          //   this.dingtalkForm.items[index].props.value = this.form.custName
+          //   this.dingtalkForm.items[index].props.disabled = true
+          // }
+          // if (this.dingtalkForm.items[index].props.label === '所在省') {
+          //   this.dingtalkForm.items[index].props.value = this.form.custProvince
+          //   this.dingtalkForm.items[index].props.disabled = true
+          // }
+          // if (this.dingtalkForm.items[index].props.label === '所在市') {
+          //   this.dingtalkForm.items[index].props.value = this.form.custCity
+          //   this.dingtalkForm.items[index].props.disabled = true
+          // }
+          if (this.dingtalkForm.items[index].props.label === '销售工程师') {
+            this.dingtalkForm.items[index].props.value = this.form.saleName
+            this.dingtalkForm.items[index].props.disabled = true
+          }
+          if (this.dingtalkForm.items[index].props.label === '工单名称') {
+            let name = ''
+            if (this.form.dealerNames) {
+              name += this.form.dealerNames
+            }
+            if (this.form.agentNames) {
+              if (name == '') {
+                name += this.form.agentNames
+              } else {
+                name += ',' + this.form.agentNames
+              }
+            }
+            this.dingtalkForm.items[index].props.value = name + this.form.orderTypeName
+          }
+        }
+        this.$refs.dingTalkFrom.setFormAndRules(this.dingtalkForm)
+      },
+      // handleUploadFile(file) {
+      //   this.form.file = file
+      // },
+      handleSelectUser() {
+        this.$refs.selectUser.open()
+      },
+      selectUser(val) {
+        if (val && val.length > 0) {
+          this.form.assignUserId = val[0].id
+          this.form.assignUserName = val.map((item) => item.nickName).join()
+        }
+      },
+      showEdit() {
+        this.getOrderTypeList()
+        this.loading = false
+        this.title = '添加'
+        this.form.saleId = this.userId
+        this.form.saleName = this.nickName
+        this.dialogFormVisible = true
+      },
+      close() {
+        this.$refs['dingTalkFrom'].resetForm()
+        this.$refs['form'].resetFields()
+        this.form = this.$options.data().form
+        this.dialogFormVisible = false
+      },
+      //
+      handleSelectDistributor(type) {
+        this.queryParams.distType = type
+        this.$refs.selectDistributor.open()
+      },
+      // 选中数据
+      saveDistributors(val) {
+        if (this.queryParams.distType == '10') {
+          if (val && val.length > 0) {
+            this.form.dealerIds = val.map((item) => item.id).join()
+            this.form.dealerNames = val.map((item) => item.distName).join()
+          } else {
+            this.form.dealerIds = ''
+            this.form.dealerNames = ''
+          }
+        } else {
+          if (val && val.length > 0) {
+            this.form.agentIds = val.map((item) => item.id).join()
+            this.form.agentNames = val.map((item) => item.distName).join()
+          } else {
+            this.form.agentIds = ''
+            this.form.agentNames = ''
+          }
+        }
+        let temp = this.$refs['dingTalkFrom'].getFormData()
+        for (let index in temp.items) {
+          if (temp.items[index].props.label === '工单名称') {
+            let name = ''
+            if (this.form.dealerNames) {
+              name += this.form.dealerNames
+            }
+            if (this.form.agentNames) {
+              if (name == '') {
+                name += this.form.agentNames
+              } else {
+                name += ',' + this.form.agentNames
+              }
+            }
+            temp.items[index].props.value = name + this.form.orderTypeName
+          }
+        }
+        this.$refs.dingTalkFrom.setFormAndRules(temp)
+      },
+      save() {
+        let dingValid = this.$refs['dingTalkFrom'].validateForm()
+        this.$refs['form'].validate(async (valid) => {
+          if (valid && dingValid) {
+            if (!this.form.dealerNames && !this.form.agentNames) {
+              this.$message.warning('经销商、代理商不能全部为空!')
+              return
+            }
+            let items = []
+            let dingtalkForm = this.$refs['dingTalkFrom'].getFormData()
+            for (let item of dingtalkForm.items) {
+              if (item.componentName === 'DDAttachment') {
+                if (!item.props && item.props.required) {
+                  this.$baseMessage('请上传' + item.props.label, 'error', 'vab-hey-message-error')
+                  return
+                }
+              }
+              if (item.props.label === '工单名称') {
+                this.form.name = item.props.value
+              }
+              if (item.props.label === '备注' && !item.props.value) {
+                item.props.value = ''
+              }
+              if (item.props.label === '调研表上传' && !item.props.value) {
+                item.props.value = ''
+              }
+
+              if (item.props.label === '试用开始时间') {
+                this.form.trialTimeStart = item.props.value
+              }
+              if (item.props.label === '试用结束时间') {
+                this.form.trialTimeEnd = item.props.value
+              }
+              if (item.props.label === '期望完成时间') {
+                this.form.expectTime = item.props.value
+              }
+              if (item.props.label === '支持时间') {
+                this.form.supportTime = item.props.value
+              }
+              if (item.props.label === '支持人员') {
+                item.props.value = this.form.assignUserName
+              }
+              items.push({
+                componentName: item.componentName,
+                id: item.props.id,
+                name: item.props.label,
+                value: item.props.value,
+                required: item.props.required,
+              })
+            }
+            this.form.formData = items
+            this.loading = true
+            const { msg } = await workApi.doAdd(this.form)
+            this.loading = false
+            this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+            this.$emit('fetch-data')
+            this.close()
+          }
+        })
+      },
+    },
+  }
+</script>

+ 13 - 14
src/views/work/order/components/DingTalkFromToVue.vue

@@ -33,10 +33,10 @@
                 v-else-if="item.componentName === 'DDSelectField'"
                 v-model="item.props.value"
                 clearable
-                @change="selectWorkOrderType"
                 :disabled="item.props.disabled || item.props.label == '工单类型'"
                 :placeholder="item.props.placeholder"
-                style="width: 100%">
+                style="width: 100%"
+                @change="selectWorkOrderType">
                 <el-option
                   v-for="option in selectDataToJson(item.props.options)"
                   :key="option.key"
@@ -67,16 +67,16 @@
                 :type="item.props.label == '支持时间' ? 'datetime' : 'date'"
                 :value-format="item.props.format" />
 
-                <el-date-picker
+              <el-date-picker
                 v-else-if="item.componentName === 'DDDateField' && item.props.label == '运维时间'"
                 v-model="item.props.value"
                 :disabled="item.props.disabled"
+                format="yyyy-MM-dd HH:mm"
                 :placeholder="item.props.placeholder"
-                value-format="yyyy-MM-dd HH:mm"
-                format="yyyy-MM-dd HH:mm" 
                 :type="item.props.label == '运维时间' ? 'datetime' : 'date'"
+                value-format="yyyy-MM-dd HH:mm"
                 :value-format="item.props.format" />
-  
+
               <!--时间范围选择器-->
               <el-date-picker
                 v-else-if="item.componentName === 'DDDateRangeField'"
@@ -184,7 +184,7 @@
   import asyncUploadFile from '@/utils/uploadajax'
   import axios from 'axios'
   import to from 'await-to-js'
-import { parseTime } from '@/utils/index'
+  import { parseTime } from '@/utils/index'
   export default {
     name: 'DingTalkFromToVue',
     components: {
@@ -216,8 +216,8 @@ import { parseTime } from '@/utils/index'
     },
     // 方法集合
     methods: {
-      selectWorkOrderType(val){
-          console.log("下拉选择的val是:", val)
+      selectWorkOrderType(val) {
+        console.log('下拉选择的val是:', val)
       },
       selectLabel(val, children, row) {
         const codeId = children.find((item) => item.props.label == '产品型号').props.id
@@ -342,7 +342,7 @@ import { parseTime } from '@/utils/index'
           })
       },
       selectDataToJson(data) {
-        console.log("select data is", data)
+        console.log('select data is', data)
         return data.map((item) => {
           return JSON.parse(item)
         })
@@ -359,13 +359,12 @@ import { parseTime } from '@/utils/index'
             dingtalkForm.items[index].props.value = JSON.parse(dingtalkForm.items[index].props.options[0]).value
           }
           if (dingtalkForm.items[index].props.label == '运维时间') {
-        
-            
-          this.$set(dingtalkForm.items[index].props, 'value', parseTime(new Date()).substring(0, 16))
-            dingtalkForm.items[index].props.format = "yyyy-MM-dd HH:mm"
+            this.$set(dingtalkForm.items[index].props, 'value', parseTime(new Date()).substring(0, 16))
+            dingtalkForm.items[index].props.format = 'yyyy-MM-dd HH:mm'
           }
         }
         this.dingtalkForm = dingtalkForm
+        this.$forceUpdate()
       },
       getFormData() {
         for (let index in this.dingtalkForm.items) {

+ 1 - 1
src/views/work/order/components/Edit.vue

@@ -121,7 +121,7 @@
         this.orderTypeList.splice(0, this.orderTypeList.length)
         const { data } = await typeApi.getList()
         for (let item of data.list) {
-          if (item.name !== '硬件交付工单') {
+          if (item.name !== '硬件交付工单' && item.name !== '经销商支持') {
             this.orderTypeList.push(item)
           }
         }

+ 13 - 1
src/views/work/order/components/FeedbackRecord.vue

@@ -49,9 +49,15 @@
         <el-descriptions-item label="下一步计划">
           <span v-html="detail.feedbackSaleNext.replace(/\n/g, '<br>')"></span>
         </el-descriptions-item>
+        <el-descriptions-item label="技术支持满意度">
+          {{ detail.satisfactionRating ? detail.satisfactionRating + '分' : '' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="技术支持提升建议">
+          <span v-html="detail.promotionProposal.replace(/\n/g, '<br>')"></span>
+        </el-descriptions-item>
       </el-descriptions>
       <el-descriptions
-        v-else-if="detail.orderTypeName == '售前讲解支持'"
+        v-else-if="detail.orderTypeName == '售前讲解支持' || detail.orderTypeName == '经销商支持'"
         border
         :column="1"
         :label-style="{ width: '130px' }">
@@ -67,6 +73,12 @@
         <el-descriptions-item label="下一步计划">
           <span v-html="detail.feedbackSaleNext.replace(/\n/g, '<br>')"></span>
         </el-descriptions-item>
+        <el-descriptions-item label="技术支持满意度">
+          {{ detail.satisfactionRating ? detail.satisfactionRating + '分' : '' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="技术支持提升建议">
+          <span v-html="detail.promotionProposal.replace(/\n/g, '<br>')"></span>
+        </el-descriptions-item>
       </el-descriptions>
       <el-descriptions
         v-else-if="detail.orderTypeName == '售后运维工单'"

+ 35 - 4
src/views/work/order/components/SaleFeedback.vue

@@ -1,6 +1,11 @@
 <template>
-  <el-dialog title="销售反馈" :visible.sync="dialogFormVisible" width="600px" @close="close">
-    <el-form ref="form" label-position="top" :model="form" :rules="rules">
+  <el-dialog title="销售反馈" :visible.sync="dialogFormVisible" width="500px" @close="close">
+    <el-form
+      ref="form"
+      label-position="top"
+      :model="form"
+      :rules="rules"
+      style="max-height: 550px; overflow-y: scroll; overflow-x: hidden">
       <el-row :gutter="20">
         <el-col :span="24">
           <el-form-item label="反馈时间" prop="feedbackSaleTime">
@@ -14,7 +19,7 @@
         </el-col>
       </el-row>
       <!-- 售前讲解 -->
-      <el-row v-if="workType == '售前讲解支持'">
+      <el-row v-if="workType == '售前讲解支持' || workType == '经销商支持'">
         <el-col :span="24">
           <el-form-item label="会议纪要" prop="feedbackSaleMeeting">
             <el-input
@@ -51,7 +56,7 @@
         </el-col>
       </el-row>
       <!-- END -->
-      <el-row v-if="workType == '售前讲解支持' || workType == '技术文件支持'">
+      <el-row v-if="workType == '售前讲解支持' || workType == '技术文件支持' || workType == '经销商支持'">
         <el-col :span="24">
           <el-form-item label="下一步计划" prop="feedbackSaleNext">
             <el-input
@@ -77,6 +82,29 @@
         </el-col>
       </el-row>
       <!-- END -->
+      <el-row v-if="workType == '售前讲解支持' || workType == '技术文件支持' || workType == '经销商支持'">
+        <el-col :span="24">
+          <el-form-item label="技术支持满意度" prop="satisfactionRating">
+            <el-radio-group v-model="form.satisfactionRating">
+              <el-radio label="1">1分</el-radio>
+              <el-radio label="2">2分</el-radio>
+              <el-radio label="3">3分</el-radio>
+              <el-radio label="4">4分</el-radio>
+              <el-radio label="5">5分</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="技术支持提升建议" prop="promotionProposal">
+            <el-input
+              v-model="form.promotionProposal"
+              placeholder="技术支持提升建议"
+              :rows="5"
+              show-word-limit
+              type="textarea" />
+          </el-form-item>
+        </el-col>
+      </el-row>
     </el-form>
     <template #footer>
       <el-button @click="close">取 消</el-button>
@@ -100,6 +128,8 @@
           feedbackSaleNext: '',
           feedbackSaleOrder: '',
           orderId: '',
+          satisfactionRating: '',
+          promotionProposal: '',
         },
         rules: {
           feedbackSaleTime: [{ required: true, message: '不能为空', trigger: ['blur', 'change'] }],
@@ -108,6 +138,7 @@
           feedbackSaleUser: [{ required: true, message: '不能为空', trigger: ['blur', 'change'] }],
           feedbackSaleNext: [{ required: true, message: '不能为空', trigger: ['blur', 'change'] }],
           feedbackSaleOrder: [{ required: true, message: '不能为空', trigger: ['blur', 'change'] }],
+          satisfactionRating: [{ required: true, message: '不能为空', trigger: ['blur', 'change'] }],
         },
         dialogFormVisible: false,
       }

+ 10 - 0
src/views/work/order/detail.vue

@@ -42,6 +42,7 @@
                     !detail.feedbackSupportBy &&
                     (detail.orderTypeName == '技术文件支持' ||
                       detail.orderTypeName == '售前讲解支持' ||
+                      detail.orderTypeName == '经销商支持' ||
                       detail.orderTypeName == '售后运维工单')
                   "
                   v-permissions="['work:workOrder:feedback:support']"
@@ -57,6 +58,7 @@
                     !detail.feedbackSaleBy &&
                     (detail.orderTypeName == '技术文件支持' ||
                       detail.orderTypeName == '售前讲解支持' ||
+                      detail.orderTypeName == '经销商支持' ||
                       detail.orderTypeName == '售后运维工单')
                   "
                   v-permissions="['work:workOrder:feedback:sale']"
@@ -125,6 +127,12 @@
               :content-style="{ width: '35%', 'word-break': 'break-all' }"
               :label-style="{ width: '15%' }"
               size="small">
+              <el-descriptions-item v-if="detail.orderTypeName == '经销商支持'" label="经销商">
+                <span>{{ detail.dealerNames }}</span>
+              </el-descriptions-item>
+              <el-descriptions-item v-if="detail.orderTypeName == '经销商支持'" label="代理商">
+                <span>{{ detail.agentNames }}</span>
+              </el-descriptions-item>
               <el-descriptions-item
                 v-for="(item, index) in dingFormData"
                 v-show="item.componentName !== 'TableField'"
@@ -182,6 +190,7 @@
             v-if="
               detail.orderTypeName == '技术文件支持' ||
               detail.orderTypeName == '售前讲解支持' ||
+              detail.orderTypeName == '经销商支持' ||
               detail.orderTypeName == '售后运维工单'
             "
             label="支持人员总结"
@@ -192,6 +201,7 @@
             v-if="
               detail.orderTypeName == '技术文件支持' ||
               detail.orderTypeName == '售前讲解支持' ||
+              detail.orderTypeName == '经销商支持' ||
               detail.orderTypeName == '售后运维工单'
             "
             label="销售反馈"

+ 17 - 1
src/views/work/order/index.vue

@@ -48,6 +48,15 @@
         </el-form>
       </vab-query-form-top-panel>
       <vab-query-form-left-panel :span="12">
+        <vab-query-form-left-panel :span="12">
+          <el-button
+            v-permissions="['proj:business:workOrder']"
+            icon="el-icon-plus"
+            type="primary"
+            @click="createOrder">
+            创建工单
+          </el-button>
+        </vab-query-form-left-panel>
         <!--        <el-button icon="el-icon-plus" size="mini" type="primary" @click="handleEdit">新建</el-button>-->
       </vab-query-form-left-panel>
       <vab-query-form-right-panel :span="12">
@@ -114,6 +123,8 @@
       @size-change="handleSizeChange" />
     <!--创建工单-->
     <edit ref="edit" @fetch-data="fetchData" />
+    <!-- 创建经销商支持工单 -->
+    <addDealerSupportWorkOrder ref="addDealerSupportWorkOrder" @fetch-data="fetchData" />
   </div>
 </template>
 
@@ -122,10 +133,11 @@
   import api from '@/api/work/index'
   import TableTool from '@/components/table/TableTool'
   import Edit from './components/Edit'
+  import addDealerSupportWorkOrder from './components/AddDealerSupportWorkOrder'
 
   export default {
     name: 'WorkOrder',
-    components: { TableTool, Edit },
+    components: { TableTool, Edit, addDealerSupportWorkOrder },
     data() {
       return {
         activeName: 'first',
@@ -217,6 +229,10 @@
     },
 
     methods: {
+      // 创建工单
+      createOrder() {
+        this.$refs['addDealerSupportWorkOrder'].showEdit()
+      },
       changeProductLine() {},
       getOptions() {
         Promise.all([this.getDicts('work_order_status'), this.getDicts('sys_product_line')])

+ 5 - 1
src/views/work/orderType/index.vue

@@ -59,7 +59,11 @@
       <el-table-column align="center" label="操作" width="120">
         <template #default="{ row }">
           <el-button v-permissions="['work:work:edit']" type="text" @click="handleEdit(row)">编辑</el-button>
-          <el-button v-permissions="['work:work:syncForm']" type="text" @click="handleSyncForm(row)">
+          <el-button
+            v-show="row.name !== '经销商支持'"
+            v-permissions="['work:work:syncForm']"
+            type="text"
+            @click="handleSyncForm(row)">
             同步表单
           </el-button>
         </template>