ソースを参照

提交线索管理相关代码

Lijy 11 ヶ月 前
コミット
15356596ec

+ 3 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/constant.ts

@@ -1,8 +1,10 @@
 export const MOD = '/thread'
+export const IMPORMOD = 'Thread'
 export const prefix = '/clue'
 export const GETSYSFILED = '/sys-dict/getListByCode'
 export const GETPERSONNEL = '/user/getSimpleActiveUserList'
 export const GETTEMPLATE = `/sys-form/getListByCode${MOD}`
+export const GETTEMPLATETWO = `/sys-form/getListByCode/business`
 export const GETTABLE = `${prefix}/listClue`
 export const GETDETAIL = `${prefix}/getDetail`
 export const UNDATECLAIM = `${prefix}/claim`
@@ -14,4 +16,4 @@ export const REFIENAME = `${prefix}/reFileName`
 export const UPLOADFILE = `${prefix}/uploadFile`
 export const DEYELWCLUE = `${prefix}/listDeleterClue`
 export const DETERDETELE = `${prefix}/deleterDelete`
-export const ROLLBACK = `${prefix}/rollback`
+export const ROLLBACK = `${prefix}/rollback`

+ 77 - 7
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/detail/components/information.vue

@@ -3,7 +3,7 @@
         <div class="flex justify-between">
             <div class="title">基本信息</div>
             <div>
-                <el-button type="primary">转为商机</el-button>
+                <el-button type="primary" @click="showVisible('newBusinessisible')">转为商机</el-button>
                 <el-button type="primary" @click="claimClues()" v-if="!information.inchargerName">认领</el-button>
                 <el-button type="primary" @click="showVisible('clueDialogVisible')" v-else>转移</el-button>
                 <el-button type="primary" @click="editClue(information)">编辑</el-button>
@@ -104,16 +104,39 @@
                 <div class="pl-3 text-[#e94a4a]">转移后,将看不到此线索</div>
             </div>
         </el-dialog>
+
+        <!-- 转成商机 -->
+        <el-dialog v-model="dialogVisible.newBusinessisible" width="1000" :show-close="false" top="10vh">
+            <template #header="{ close, titleId, titleClass }">
+                <div class="flex justify-between items-center border-b pb-3 dialog-header">
+                    <h4 :id="titleId">{{ allText.businessisText }}</h4>
+                    <div>
+                        <el-button type="primary" @click="transferBusiness()"
+                            :loading="allLoading.businessSaveLading">转为商机</el-button>
+                        <el-button @click="closeVisible('newBusinessisible')">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="h-[60vh] overflow-y-auto scroll-bar pt-3">
+                <GenerateForm ref="generateFormDataRef" :data="generateFormData" :value="generateFormVal" />
+                <div>相关产品</div>
+                <RelatedProducts ref="relatedProductsRef" :productTableList="productTableList" />
+            </div>
+        </el-dialog>
     </div>
 </template>
 <script lang="ts" setup>
 import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
 import { GenerateForm } from '@zmjs/form-design';
-import { formatDate, confirmAction } from '@/utils/tools'
-import { GETTEMPLATE, UNDATEFORM, GETPERSONNEL, UNDATECLAIM } from '../../constant'
+import { formatDate, confirmAction, backPath } from '@/utils/tools'
+import { GETTEMPLATE, UNDATEFORM, GETPERSONNEL, UNDATECLAIM, GETTEMPLATETWO } from '../../constant'
 import { get, post } from '@/utils/request'
 import { useStore } from '@/store/index'
 import { ElMessageBox } from 'element-plus';
+import RelatedProducts from '@/pages/business/component/relatedProducts.vue'
+import { all } from 'axios';
+import { formatDateTime } from '@/utils/times';
+import { UPDATEINSET } from '@/pages/business/api';
 
 interface personnelInterface {
     id: string | number,
@@ -134,25 +157,59 @@ const generateFormKey = ref(1)
 const allLoading = reactive({
     generateFormLading: false,
     saveBtnLoading: false,
-    clueLoading: false
+    clueLoading: false,
+    businessSaveLading: false,
 })
 const dialogVisible = reactive({
     editClueDialogVisible: false,
-    clueDialogVisible: false
+    clueDialogVisible: false,
+    newBusinessisible: false
 })
 const allText = reactive({
     editClueText: '新建线索',
-    clueText: '认领线索'
+    clueText: '认领线索',
+    businessisText: '转为商机'
 })
 const generateForm: any = ref(null) // 模板
 const clueTemplate = ref({
     list: [],
     config: {}
 }) // 线索模板
+const generateFormData = ref({ // 商机模板
+    config: {},
+    list: []
+})
+const generateFormDataRef = ref<typeof GenerateForm>() // 商机模板dom
+const relatedProductsRef = ref<typeof RelatedProducts>()
+const productTableList = ref([])
+const generateFormVal = ref<any>({})
 const editForm = ref({}) // 编辑表单
 const transferValue = ref('') // 转移/认领 id
 const transferOptions = ref<personnelInterface[]>([]) // 转移人员列表
 
+// 转为商机
+function transferBusiness() {
+    generateFormDataRef.value?.getData().then((res: any) => {
+        let productTableListData = relatedProductsRef?.value?.returnData()
+        let newForm = {
+            ...res,
+            expectedTransactionDate: res.expectedTransactionDate ? formatDateTime(new Date(res.expectedTransactionDate)) : '',
+            businessItemProductList: productTableListData ? JSON.stringify(productTableListData) : []
+        }
+        allLoading.businessSaveLading = true
+        post(UPDATEINSET, { ...newForm }).then((_res) => {
+            dialogVisible.newBusinessisible = false
+            globalPopup?.showSuccess('操作成功')
+            backPath()
+        }).finally(() => {
+            allLoading.businessSaveLading = false
+        })
+    }).catch((_err: any) => {
+        console.log(_err)
+        globalPopup?.showError('请填写完整')
+    })
+}
+
 // 转移/认领 线索
 function transferClues() {
     const ids = information.value?.id
@@ -233,7 +290,17 @@ function showVisible(filed: keyof typeof dialogVisible) {
     } else {
         allText.clueText = '认领线索'
     }
-    dialogVisible[filed] = true
+
+    if (filed == 'newBusinessisible') {
+        generateFormVal.value.name = information.value.clueName
+    }
+    setTimeout(() => {
+        dialogVisible[filed] = true
+    }, 100)
+}
+
+function closeVisible(filed: keyof typeof dialogVisible) {
+    dialogVisible[filed] = false
 }
 
 async function getSystemField() {
@@ -255,6 +322,9 @@ onMounted(async () => {
     receiveAssignment(props)
     const res = await get(GETTEMPLATE)
     clueTemplate.value = JSON.parse(res.data[0].config)
+    const data = await get(GETTEMPLATETWO)
+    let newData = JSON.parse(data.data[0].config)
+    generateFormData.value = newData
     getSystemField()
 });
 </script>

+ 48 - 8
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue

@@ -56,7 +56,7 @@
           <el-button type="primary" @click="batchTransfer()">批量转移</el-button>
           <el-button type="primary" @click="batchDeletes()">批量删除</el-button>
           <el-button type="primary" @click="showDeteleClue(true)">回收站</el-button>
-          <el-button type="primary">导入</el-button>
+          <el-button type="primary" @click="dialogVisible.importVisible = true">导入</el-button>
           <el-button type="primary">导出</el-button>
         </div>
         <div class="flex-1 w-full overflow-hidden">
@@ -83,8 +83,7 @@
                 <el-button link type="primary" size="large" @click="editClue(scope.row)">编辑</el-button>
                 <!-- <el-button link type="primary" size="large"
                   @click="dialogVisible.taskModalVisible = true">新建任务</el-button> -->
-                <el-button link type="primary" size="large"
-                  @click="newTask(scope.row)">新建任务</el-button>
+                <el-button link type="primary" size="large" @click="newTask(scope.row)">新建任务</el-button>
                 <el-button link type="danger" size="large" @click.prevent="deleteRow(scope.row)">删除</el-button>
               </template>
             </el-table-column>
@@ -142,15 +141,38 @@
 
     <TaskModal :visible="dialogVisible.taskModalVisible" :edit-form="taskModalForm" :save-loading="taskLoading"
       @close="closeTaskModal" @submit="submitForm" :title="'新建任务'" :disabled-list="['taskType', 'clueId']" />
+
+    <!-- 导入线索 -->
+    <el-dialog v-model="dialogVisible.importVisible" width="680" :show-close="false" top="10vh">
+      <template #header="{ close, titleId, titleClass }">
+        <div class="flex justify-between items-center border-b pb-3 dialog-header">
+          <h4 :id="titleId">导入线索</h4>
+          <div class="flex">
+            <el-upload class="upload-demo mr-3" :limit="1" :show-file-list="false" accept=".xlsx"
+              :http-request="importProducts">
+              <el-button type="primary" :loading="allLoading.importLoading">导入</el-button>
+            </el-upload>
+            <el-button @click="dialogVisible.importVisible = false">取消</el-button>
+          </div>
+        </div>
+      </template>
+      <div class="p-8">
+        <div class="ml-4 mr-4">
+          <div class="flex items-center">1、点击下载 <el-link type="primary"
+              @click="downloadTemplate(IMPORMOD, '线索导入模板.xlsx')">线索导入模板.xlsx</el-link></div>
+          <div class="mt-4">2、填写excel文件、线索名称、线索来源必填</div>
+        </div>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script lang="ts" setup>
 import { ref, reactive, onMounted, inject } from "vue";
-import { GETSYSFILED, MOD, GETPERSONNEL, GETTABLE, GETTEMPLATE, GETDETAIL, UNDATECLAIM, UNDATEFORM, DELTEROW } from './constant'
-import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, createTaskFromType, confirmAction } from '@/utils/tools'
-import { FormInstance, FormRules, ElMessageBox, ElTable } from 'element-plus'
-import { post, get } from "@/utils/request";
+import { GETSYSFILED, MOD, IMPORMOD, GETPERSONNEL, GETTABLE, GETTEMPLATE, GETDETAIL, UNDATECLAIM, UNDATEFORM, DELTEROW } from './constant'
+import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, createTaskFromType, confirmAction, downloadTemplate } from '@/utils/tools'
+import { FormInstance, FormRules, ElMessageBox, ElTable, UploadRequestOptions } from 'element-plus'
+import { post, get, uploadFile } from "@/utils/request";
 import { useRouter, useRoute } from "vue-router";
 import { GenerateForm } from '@zmjs/form-design';
 import TaskModal from '@/components/TaskModal/index.vue'
@@ -196,12 +218,14 @@ const allLoading = reactive({
   clueTableLading: false,
   generateFormLading: false,
   clueLoading: false,
+  importLoading: false,
 })
 const dialogVisible = reactive({
   editClueDialogVisible: false,
   taskModalVisible: false,
   clueDialogVisible: false,
-  deteleClueDialogVisible: false
+  deteleClueDialogVisible: false,
+  importVisible: false
 })
 const allText = reactive({
   editClueText: '新建线索',
@@ -340,6 +364,22 @@ function deleteRow(row: any) {
   })
 }
 
+async function importProducts(param: UploadRequestOptions) {
+  allLoading.importLoading = true
+  const formData = new FormData();
+  formData.append('multipartFile', param.file)
+  const res = await uploadFile('导入接口', formData).finally(() => {
+    allLoading.importLoading = false
+  })
+  allLoading.importLoading = false
+  if (res.code == 'ok') {
+    globalPopup?.showSuccess('导入成功' || '')
+    
+    return
+  }
+  globalPopup?.showError(res.msg || '')
+}
+
 function batchTransfer() {
   const data = clueTableRef.value && clueTableRef.value.getSelectionRows()
   if (!data.length) {