Browse Source

crm-客户:公海抽离,完善跟进

puhui999 1 year ago
parent
commit
5151824110

+ 6 - 1
src/api/crm/business/index.ts

@@ -36,6 +36,11 @@ export const getBusiness = async (id: number) => {
   return await request.get({ url: `/crm/business/get?id=` + id })
   return await request.get({ url: `/crm/business/get?id=` + id })
 }
 }
 
 
+// 获得 CRM 商机列表(精简)
+export const getSimpleBusinessList = async () => {
+  return await request.get({ url: `/crm/business/simple-all-list` })
+}
+
 // 新增 CRM 商机
 // 新增 CRM 商机
 export const createBusiness = async (data: BusinessVO) => {
 export const createBusiness = async (data: BusinessVO) => {
   return await request.post({ url: `/crm/business/create`, data })
   return await request.post({ url: `/crm/business/create`, data })
@@ -63,5 +68,5 @@ export const getBusinessPageByContact = async (params) => {
 
 
 // 获得 CRM 商机列表
 // 获得 CRM 商机列表
 export const getBusinessListByIds = async (val: number[]) => {
 export const getBusinessListByIds = async (val: number[]) => {
-  return await request.get({ url: '/crm/business/list-by-ids', params: { ids: val } })
+  return await request.get({ url: '/crm/business/list-by-ids', params: { ids: val.join(',') } })
 }
 }

+ 1 - 1
src/api/crm/contact/index.ts

@@ -73,7 +73,7 @@ export const getSimpleContactList = async () => {
 
 
 // 获得 CRM 联系人列表
 // 获得 CRM 联系人列表
 export const getContactListByIds = async (val: number[]) => {
 export const getContactListByIds = async (val: number[]) => {
-  return await request.get({ url: '/crm/contact/list-by-ids', params: { ids: val } })
+  return await request.get({ url: '/crm/contact/list-by-ids', params: { ids: val.join(',') } })
 }
 }
 
 
 // 批量新增联系人商机关联
 // 批量新增联系人商机关联

+ 4 - 5
src/api/crm/customer/index.ts

@@ -64,8 +64,8 @@ export const exportCustomer = async (params: any) => {
 }
 }
 
 
 // 客户列表
 // 客户列表
-export const queryAllList = async () => {
-  return await request.get({ url: `/crm/customer/query-all-list` })
+export const getSimpleCustomerList = async () => {
+  return await request.get({ url: `/crm/customer/list-all-simple` })
 }
 }
 
 
 // 查询客户操作日志
 // 查询客户操作日志
@@ -80,13 +80,12 @@ export const lockCustomer = async (id: number, lockStatus: boolean) => {
   return await request.put({ url: `/crm/customer/lock`, data: { id, lockStatus } })
   return await request.put({ url: `/crm/customer/lock`, data: { id, lockStatus } })
 }
 }
 
 
-// TODO @puhui999:方法名,改成和后端一致哈
 // 领取公海客户
 // 领取公海客户
-export const receive = async (ids: any[]) => {
+export const receiveCustomer = async (ids: any[]) => {
   return await request.put({ url: '/crm/customer/receive', params: { ids: ids.join(',') } })
   return await request.put({ url: '/crm/customer/receive', params: { ids: ids.join(',') } })
 }
 }
 
 
 // 客户放入公海
 // 客户放入公海
-export const putPool = async (id: number) => {
+export const putCustomerPool = async (id: number) => {
   return await request.put({ url: `/crm/customer/put-pool?id=${id}` })
   return await request.put({ url: `/crm/customer/put-pool?id=${id}` })
 }
 }

+ 4 - 2
src/router/modules/remaining.ts

@@ -504,7 +504,8 @@ const remainingRouter: AppRouteRecordRaw[] = [
         meta: {
         meta: {
           title: '客户详情',
           title: '客户详情',
           noCache: true,
           noCache: true,
-          hidden: true
+          hidden: true,
+          activeMenu: '/crm/customer/index'
         },
         },
         component: () => import('@/views/crm/customer/detail/index.vue')
         component: () => import('@/views/crm/customer/detail/index.vue')
       },
       },
@@ -514,7 +515,8 @@ const remainingRouter: AppRouteRecordRaw[] = [
         meta: {
         meta: {
           title: '联系人详情',
           title: '联系人详情',
           noCache: true,
           noCache: true,
-          hidden: true
+          hidden: true,
+          activeMenu: '/crm/contact'
         },
         },
         component: () => import('@/views/crm/contact/detail/index.vue')
         component: () => import('@/views/crm/contact/detail/index.vue')
       }
       }

+ 16 - 16
src/views/crm/contact/ContactForm.vue

@@ -1,25 +1,25 @@
 <template>
 <template>
-  <Dialog :title="dialogTitle" v-model="dialogVisible" :width="820">
+  <Dialog v-model="dialogVisible" :title="dialogTitle" :width="820">
     <el-form
     <el-form
       ref="formRef"
       ref="formRef"
+      v-loading="formLoading"
       :model="formData"
       :model="formData"
       :rules="formRules"
       :rules="formRules"
       label-width="110px"
       label-width="110px"
-      v-loading="formLoading"
     >
     >
       <el-row :gutter="20">
       <el-row :gutter="20">
         <el-col :span="12">
         <el-col :span="12">
           <el-form-item label="姓名" prop="name">
           <el-form-item label="姓名" prop="name">
-            <el-input input-style="width:190px;" v-model="formData.name" placeholder="请输入姓名" />
+            <el-input v-model="formData.name" input-style="width:190px;" placeholder="请输入姓名" />
           </el-form-item>
           </el-form-item>
         </el-col>
         </el-col>
         <el-col :span="12">
         <el-col :span="12">
           <el-form-item label="负责人" prop="ownerUserId">
           <el-form-item label="负责人" prop="ownerUserId">
             <el-select
             <el-select
               v-model="formData.ownerUserId"
               v-model="formData.ownerUserId"
+              lable-key="nickname"
               placeholder="请选择负责人"
               placeholder="请选择负责人"
               value-key="id"
               value-key="id"
-              lable-key="nickname"
             >
             >
               <el-option
               <el-option
                 v-for="item in userList"
                 v-for="item in userList"
@@ -36,9 +36,9 @@
           <el-form-item label="客户名称" prop="customerName">
           <el-form-item label="客户名称" prop="customerName">
             <el-select
             <el-select
               v-model="formData.customerId"
               v-model="formData.customerId"
+              lable-key="name"
               placeholder="请选择客户"
               placeholder="请选择客户"
               value-key="id"
               value-key="id"
-              lable-key="name"
             >
             >
               <el-option
               <el-option
                 v-for="item in customerList"
                 v-for="item in customerList"
@@ -66,8 +66,8 @@
         <el-col :span="12">
         <el-col :span="12">
           <el-form-item label="手机号" prop="mobile">
           <el-form-item label="手机号" prop="mobile">
             <el-input
             <el-input
-              input-style="width:190px;"
               v-model="formData.mobile"
               v-model="formData.mobile"
+              input-style="width:190px;"
               placeholder="请输入手机号"
               placeholder="请输入手机号"
             />
             />
           </el-form-item>
           </el-form-item>
@@ -82,8 +82,8 @@
         <el-col :span="12">
         <el-col :span="12">
           <el-form-item label="邮箱" prop="email">
           <el-form-item label="邮箱" prop="email">
             <el-input
             <el-input
-              input-style="width:190px;"
               v-model="formData.email"
               v-model="formData.email"
+              input-style="width:190px;"
               placeholder="请输入邮箱"
               placeholder="请输入邮箱"
             />
             />
           </el-form-item>
           </el-form-item>
@@ -98,8 +98,8 @@
         <el-col :span="12">
         <el-col :span="12">
           <el-form-item label="微信" prop="wechat">
           <el-form-item label="微信" prop="wechat">
             <el-input
             <el-input
-              input-style="width:190px;"
               v-model="formData.wechat"
               v-model="formData.wechat"
+              input-style="width:190px;"
               placeholder="请输入微信"
               placeholder="请输入微信"
             />
             />
           </el-form-item>
           </el-form-item>
@@ -108,9 +108,9 @@
           <el-form-item label="下次联系时间" prop="contactNextTime">
           <el-form-item label="下次联系时间" prop="contactNextTime">
             <el-date-picker
             <el-date-picker
               v-model="formData.contactNextTime"
               v-model="formData.contactNextTime"
+              placeholder="选择下次联系时间"
               type="datetime"
               type="datetime"
               value-format="x"
               value-format="x"
-              placeholder="选择下次联系时间"
             />
             />
           </el-form-item>
           </el-form-item>
         </el-col>
         </el-col>
@@ -129,8 +129,8 @@
         <el-col :span="12">
         <el-col :span="12">
           <el-form-item label="地址" prop="detailAddress">
           <el-form-item label="地址" prop="detailAddress">
             <el-input
             <el-input
-              input-style="width:190px;"
               v-model="formData.detailAddress"
               v-model="formData.detailAddress"
+              input-style="width:190px;"
               placeholder="请输入地址"
               placeholder="请输入地址"
             />
             />
           </el-form-item>
           </el-form-item>
@@ -143,16 +143,16 @@
               <el-option
               <el-option
                 v-for="item in allContactList"
                 v-for="item in allContactList"
                 :key="item.id"
                 :key="item.id"
+                :disabled="item.id == formData.id"
                 :label="item.name"
                 :label="item.name"
                 :value="item.id"
                 :value="item.id"
-                :disabled="item.id == formData.id"
               />
               />
             </el-select>
             </el-select>
           </el-form-item>
           </el-form-item>
         </el-col>
         </el-col>
         <el-col :span="12">
         <el-col :span="12">
           <el-form-item label="职位" prop="post">
           <el-form-item label="职位" prop="post">
-            <el-input input-style="width:190px;" v-model="formData.post" placeholder="请输入职位" />
+            <el-input v-model="formData.post" input-style="width:190px;" placeholder="请输入职位" />
           </el-form-item>
           </el-form-item>
         </el-col>
         </el-col>
       </el-row>
       </el-row>
@@ -180,14 +180,14 @@
       </el-row>
       </el-row>
     </el-form>
     </el-form>
     <template #footer>
     <template #footer>
-      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
       <el-button @click="dialogVisible = false">取 消</el-button>
       <el-button @click="dialogVisible = false">取 消</el-button>
     </template>
     </template>
   </Dialog>
   </Dialog>
 </template>
 </template>
-<script setup lang="ts">
+<script lang="ts" setup>
 import * as ContactApi from '@/api/crm/contact'
 import * as ContactApi from '@/api/crm/contact'
-import { DICT_TYPE, getIntDictOptions, getBoolDictOptions } from '@/utils/dict'
+import { DICT_TYPE, getBoolDictOptions, getIntDictOptions } from '@/utils/dict'
 import * as UserApi from '@/api/system/user'
 import * as UserApi from '@/api/system/user'
 import * as CustomerApi from '@/api/crm/customer'
 import * as CustomerApi from '@/api/crm/customer'
 import * as AreaApi from '@/api/system/area'
 import * as AreaApi from '@/api/system/area'
@@ -242,7 +242,7 @@ const open = async (type: string, id?: number) => {
   resetForm()
   resetForm()
   allContactList.value = await ContactApi.getSimpleContactList()
   allContactList.value = await ContactApi.getSimpleContactList()
   userList.value = await UserApi.getSimpleUserList()
   userList.value = await UserApi.getSimpleUserList()
-  customerList.value = await CustomerApi.queryAllList()
+  customerList.value = await CustomerApi.getSimpleCustomerList()
   areaList.value = await AreaApi.getAreaTree()
   areaList.value = await AreaApi.getAreaTree()
   // 修改时,设置数据
   // 修改时,设置数据
   if (id) {
   if (id) {

+ 56 - 47
src/views/crm/contact/index.vue

@@ -2,21 +2,21 @@
   <ContentWrap>
   <ContentWrap>
     <!-- 搜索工作栏 -->
     <!-- 搜索工作栏 -->
     <el-form
     <el-form
-      class="-mb-15px"
-      :model="queryParams"
       ref="queryFormRef"
       ref="queryFormRef"
       :inline="true"
       :inline="true"
+      :model="queryParams"
+      class="-mb-15px"
       label-width="68px"
       label-width="68px"
     >
     >
       <el-form-item label="客户" prop="customerId">
       <el-form-item label="客户" prop="customerId">
         <el-select
         <el-select
           v-model="queryParams.customerId"
           v-model="queryParams.customerId"
           class="!w-240px"
           class="!w-240px"
+          clearable
+          lable-key="name"
           placeholder="请选择客户"
           placeholder="请选择客户"
           value-key="id"
           value-key="id"
-          lable-key="name"
           @keyup.enter="handleQuery"
           @keyup.enter="handleQuery"
-          clearable
         >
         >
           <el-option
           <el-option
             v-for="item in customerList"
             v-for="item in customerList"
@@ -30,8 +30,8 @@
         <el-input
         <el-input
           v-model="queryParams.name"
           v-model="queryParams.name"
           class="!w-240px"
           class="!w-240px"
-          placeholder="请输入姓名"
           clearable
           clearable
+          placeholder="请输入姓名"
           @keyup.enter="handleQuery"
           @keyup.enter="handleQuery"
         />
         />
       </el-form-item>
       </el-form-item>
@@ -39,8 +39,8 @@
         <el-input
         <el-input
           v-model="queryParams.mobile"
           v-model="queryParams.mobile"
           class="!w-240px"
           class="!w-240px"
-          placeholder="请输入手机号"
           clearable
           clearable
+          placeholder="请输入手机号"
           @keyup.enter="handleQuery"
           @keyup.enter="handleQuery"
         />
         />
       </el-form-item>
       </el-form-item>
@@ -48,8 +48,8 @@
         <el-input
         <el-input
           v-model="queryParams.telephone"
           v-model="queryParams.telephone"
           class="!w-240px"
           class="!w-240px"
-          placeholder="请输入电话"
           clearable
           clearable
+          placeholder="请输入电话"
           @keyup.enter="handleQuery"
           @keyup.enter="handleQuery"
         />
         />
       </el-form-item>
       </el-form-item>
@@ -57,8 +57,8 @@
         <el-input
         <el-input
           v-model="queryParams.qq"
           v-model="queryParams.qq"
           class="!w-240px"
           class="!w-240px"
-          placeholder="请输入QQ"
           clearable
           clearable
+          placeholder="请输入QQ"
           @keyup.enter="handleQuery"
           @keyup.enter="handleQuery"
         />
         />
       </el-form-item>
       </el-form-item>
@@ -66,8 +66,8 @@
         <el-input
         <el-input
           v-model="queryParams.wechat"
           v-model="queryParams.wechat"
           class="!w-240px"
           class="!w-240px"
-          placeholder="请输入微信"
           clearable
           clearable
+          placeholder="请输入微信"
           @keyup.enter="handleQuery"
           @keyup.enter="handleQuery"
         />
         />
       </el-form-item>
       </el-form-item>
@@ -75,25 +75,33 @@
         <el-input
         <el-input
           v-model="queryParams.email"
           v-model="queryParams.email"
           class="!w-240px"
           class="!w-240px"
-          placeholder="请输入电子邮箱"
           clearable
           clearable
+          placeholder="请输入电子邮箱"
           @keyup.enter="handleQuery"
           @keyup.enter="handleQuery"
         />
         />
       </el-form-item>
       </el-form-item>
       <el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"> <Icon icon="ep:search" class="mr-5px" /> 搜索 </el-button>
-        <el-button @click="resetQuery"> <Icon icon="ep:refresh" class="mr-5px" /> 重置 </el-button>
-        <el-button type="primary" @click="openForm('create')" v-hasPermi="['crm:contact:create']">
-          <Icon icon="ep:plus" class="mr-5px" /> 新增
+        <el-button @click="handleQuery">
+          <Icon class="mr-5px" icon="ep:search" />
+          搜索
+        </el-button>
+        <el-button @click="resetQuery">
+          <Icon class="mr-5px" icon="ep:refresh" />
+          重置
+        </el-button>
+        <el-button v-hasPermi="['crm:contact:create']" type="primary" @click="openForm('create')">
+          <Icon class="mr-5px" icon="ep:plus" />
+          新增
         </el-button>
         </el-button>
         <el-button
         <el-button
-          type="success"
+          v-hasPermi="['crm:contact:export']"
+          :loading="exportLoading"
           plain
           plain
+          type="success"
           @click="handleExport"
           @click="handleExport"
-          :loading="exportLoading"
-          v-hasPermi="['crm:contact:export']"
         >
         >
-          <Icon icon="ep:download" class="mr-5px" /> 导出
+          <Icon class="mr-5px" icon="ep:download" />
+          导出
         </el-button>
         </el-button>
       </el-form-item>
       </el-form-item>
     </el-form>
     </el-form>
@@ -101,30 +109,30 @@
 
 
   <!-- 列表 -->
   <!-- 列表 -->
   <ContentWrap>
   <ContentWrap>
-    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
-      <el-table-column label="姓名" fixed="left" align="center" prop="name" width="140">
+    <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
+      <el-table-column align="center" fixed="left" label="姓名" prop="name" width="140">
         <template #default="scope">
         <template #default="scope">
-          <el-link type="primary" :underline="false" @click="openDetail(scope.row.id)">
+          <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
             {{ scope.row.name }}
             {{ scope.row.name }}
           </el-link>
           </el-link>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-      <el-table-column label="客户名称" fixed="left" align="center" prop="customerName" width="120">
+      <el-table-column align="center" fixed="left" label="客户名称" prop="customerName" width="120">
         <template #default="scope">
         <template #default="scope">
           <el-link
           <el-link
-            type="primary"
             :underline="false"
             :underline="false"
+            type="primary"
             @click="openCustomerDetail(scope.row.customerId)"
             @click="openCustomerDetail(scope.row.customerId)"
           >
           >
             {{ scope.row.customerName }}
             {{ scope.row.customerName }}
           </el-link>
           </el-link>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-      <el-table-column label="手机" align="center" prop="mobile" width="120" />
-      <el-table-column label="电话" align="center" prop="telephone" width="120" />
-      <el-table-column label="邮箱" align="center" prop="email" width="120" />
-      <el-table-column label="职位" align="center" prop="post" width="120" />
-      <el-table-column label="地址" align="center" prop="detailAddress" width="120" />
+      <el-table-column align="center" label="手机" prop="mobile" width="120" />
+      <el-table-column align="center" label="电话" prop="telephone" width="120" />
+      <el-table-column align="center" label="邮箱" prop="email" width="120" />
+      <el-table-column align="center" label="职位" prop="post" width="120" />
+      <el-table-column align="center" label="地址" prop="detailAddress" width="120" />
       <el-table-column
       <el-table-column
         :formatter="dateFormatter"
         :formatter="dateFormatter"
         align="center"
         align="center"
@@ -132,56 +140,56 @@
         prop="contactNextTime"
         prop="contactNextTime"
         width="180px"
         width="180px"
       />
       />
-      <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="关键决策人" align="center" prop="master" width="100">
+      <el-table-column align="center" label="备注" prop="remark" />
+      <el-table-column align="center" label="关键决策人" prop="master" width="100">
         <template #default="scope">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.master" />
           <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.master" />
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-      <el-table-column label="直属上级" align="center" prop="parentName" width="140" />
+      <el-table-column align="center" label="直属上级" prop="parentName" width="140" />
       <el-table-column
       <el-table-column
-        label="最后跟进时间"
+        :formatter="dateFormatter"
         align="center"
         align="center"
+        label="最后跟进时间"
         prop="contactLastTime"
         prop="contactLastTime"
-        :formatter="dateFormatter"
         width="180px"
         width="180px"
       />
       />
-      <el-table-column label="性别" align="center" prop="sex">
+      <el-table-column align="center" label="性别" prop="sex">
         <template #default="scope">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
           <dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-      <el-table-column label="负责人" align="center" prop="ownerUserName" width="120" />
-      <el-table-column label="创建人" align="center" prop="creatorName" width="120" />
+      <el-table-column align="center" label="负责人" prop="ownerUserName" width="120" />
+      <el-table-column align="center" label="创建人" prop="creatorName" width="120" />
       <el-table-column
       <el-table-column
-        label="更新时间"
+        :formatter="dateFormatter"
         align="center"
         align="center"
+        label="更新时间"
         prop="updateTime"
         prop="updateTime"
-        :formatter="dateFormatter"
         width="180px"
         width="180px"
       />
       />
       <el-table-column
       <el-table-column
-        label="创建时间"
+        :formatter="dateFormatter"
         align="center"
         align="center"
+        label="创建时间"
         prop="createTime"
         prop="createTime"
-        :formatter="dateFormatter"
         width="180px"
         width="180px"
       />
       />
-      <el-table-column label="操作" align="center" fixed="right" width="200">
+      <el-table-column align="center" fixed="right" label="操作" width="200">
         <template #default="scope">
         <template #default="scope">
           <el-button
           <el-button
+            v-hasPermi="['crm:contact:update']"
             link
             link
             type="primary"
             type="primary"
             @click="openForm('update', scope.row.id)"
             @click="openForm('update', scope.row.id)"
-            v-hasPermi="['crm:contact:update']"
           >
           >
             编辑
             编辑
           </el-button>
           </el-button>
           <el-button
           <el-button
+            v-hasPermi="['crm:contact:delete']"
             link
             link
             type="danger"
             type="danger"
             @click="handleDelete(scope.row.id)"
             @click="handleDelete(scope.row.id)"
-            v-hasPermi="['crm:contact:delete']"
           >
           >
             删除
             删除
           </el-button>
           </el-button>
@@ -190,9 +198,9 @@
     </el-table>
     </el-table>
     <!-- 分页 -->
     <!-- 分页 -->
     <Pagination
     <Pagination
-      :total="total"
-      v-model:page="queryParams.pageNo"
       v-model:limit="queryParams.pageSize"
       v-model:limit="queryParams.pageSize"
+      v-model:page="queryParams.pageNo"
+      :total="total"
       @pagination="getList"
       @pagination="getList"
     />
     />
   </ContentWrap>
   </ContentWrap>
@@ -201,7 +209,7 @@
   <ContactForm ref="formRef" @success="getList" />
   <ContactForm ref="formRef" @success="getList" />
 </template>
 </template>
 
 
-<script setup lang="ts">
+<script lang="ts" setup>
 import { dateFormatter } from '@/utils/formatTime'
 import { dateFormatter } from '@/utils/formatTime'
 import download from '@/utils/download'
 import download from '@/utils/download'
 import * as ContactApi from '@/api/crm/contact'
 import * as ContactApi from '@/api/crm/contact'
@@ -295,6 +303,7 @@ const { push } = useRouter()
 const openDetail = (id: number) => {
 const openDetail = (id: number) => {
   push({ name: 'CrmContactDetail', params: { id } })
   push({ name: 'CrmContactDetail', params: { id } })
 }
 }
+
 /** 打开客户详情 */
 /** 打开客户详情 */
 const openCustomerDetail = (id: number) => {
 const openCustomerDetail = (id: number) => {
   push({ name: 'CrmCustomerDetail', params: { id } })
   push({ name: 'CrmCustomerDetail', params: { id } })
@@ -303,6 +312,6 @@ const openCustomerDetail = (id: number) => {
 /** 初始化 **/
 /** 初始化 **/
 onMounted(async () => {
 onMounted(async () => {
   await getList()
   await getList()
-  customerList.value = await CustomerApi.queryAllList()
+  customerList.value = await CustomerApi.getSimpleCustomerList()
 })
 })
 </script>
 </script>

+ 2 - 2
src/views/crm/customer/detail/index.vue

@@ -113,7 +113,7 @@ const handleUnlock = async () => {
 /** 领取客户 */
 /** 领取客户 */
 const handleReceive = async () => {
 const handleReceive = async () => {
   await message.confirm(`确定领取客户【${customer.value.name}】 吗?`)
   await message.confirm(`确定领取客户【${customer.value.name}】 吗?`)
-  await CustomerApi.receive([unref(customerId.value)])
+  await CustomerApi.receiveCustomer([unref(customerId.value)])
   message.success(`领取客户【${customer.value.name}】成功`)
   message.success(`领取客户【${customer.value.name}】成功`)
   await getCustomer()
   await getCustomer()
 }
 }
@@ -121,7 +121,7 @@ const handleReceive = async () => {
 /** 客户放入公海 */
 /** 客户放入公海 */
 const handlePutPool = async () => {
 const handlePutPool = async () => {
   await message.confirm(`确定将客户【${customer.value.name}】放入公海吗?`)
   await message.confirm(`确定将客户【${customer.value.name}】放入公海吗?`)
-  await CustomerApi.putPool(unref(customerId.value))
+  await CustomerApi.putCustomerPool(unref(customerId.value))
   message.success(`客户【${customer.value.name}】放入公海成功`)
   message.success(`客户【${customer.value.name}】放入公海成功`)
   close()
   close()
 }
 }

+ 279 - 0
src/views/crm/customer/pool/index.vue

@@ -0,0 +1,279 @@
+<template>
+  <ContentWrap>
+    <!-- 搜索工作栏 -->
+    <el-form
+      ref="queryFormRef"
+      :inline="true"
+      :model="queryParams"
+      class="-mb-15px"
+      label-width="68px"
+    >
+      <el-form-item label="客户名称" prop="name">
+        <el-input
+          v-model="queryParams.name"
+          class="!w-240px"
+          clearable
+          placeholder="请输入客户名称"
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="手机" prop="mobile">
+        <el-input
+          v-model="queryParams.mobile"
+          class="!w-240px"
+          clearable
+          placeholder="请输入手机"
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="所属行业" prop="industryId">
+        <el-select
+          v-model="queryParams.industryId"
+          class="!w-240px"
+          clearable
+          placeholder="请选择所属行业"
+        >
+          <el-option
+            v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="客户等级" prop="level">
+        <el-select
+          v-model="queryParams.level"
+          class="!w-240px"
+          clearable
+          placeholder="请选择客户等级"
+        >
+          <el-option
+            v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="客户来源" prop="source">
+        <el-select
+          v-model="queryParams.source"
+          class="!w-240px"
+          clearable
+          placeholder="请选择客户来源"
+        >
+          <el-option
+            v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button @click="handleQuery">
+          <Icon class="mr-5px" icon="ep:search" />
+          搜索
+        </el-button>
+        <el-button @click="resetQuery(undefined)">
+          <Icon class="mr-5px" icon="ep:refresh" />
+          重置
+        </el-button>
+        <el-button
+          v-hasPermi="['crm:customer:export']"
+          :loading="exportLoading"
+          plain
+          type="success"
+          @click="handleExport"
+        >
+          <Icon class="mr-5px" icon="ep:download" />
+          导出
+        </el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
+      <el-table-column align="center" label="编号" prop="id" />
+      <el-table-column align="center" label="客户名称" prop="name" width="160">
+        <template #default="scope">
+          <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
+            {{ scope.row.name }}
+          </el-link>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="手机" prop="mobile" width="120" />
+      <el-table-column align="center" label="电话" prop="telephone" width="120" />
+      <el-table-column align="center" label="客户来源" prop="source" width="100">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="scope.row.source" />
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="所属行业" prop="industryId" width="120">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="客户等级" prop="level" width="120">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="网址" prop="website" width="200" />
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="下次联系时间"
+        prop="contactNextTime"
+        width="180px"
+      />
+      <el-table-column align="center" label="备注" prop="remark" width="200" />
+      <el-table-column align="center" label="成交状态" prop="dealStatus">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.dealStatus" />
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="距离进入公海" prop="poolDay">
+        <template #default="scope"> {{ scope.row.poolDay }}天</template>
+      </el-table-column>
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="最后跟进时间"
+        prop="contactLastTime"
+        width="180px"
+      />
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="创建时间"
+        prop="updateTime"
+        width="180px"
+      />
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="创建时间"
+        prop="createTime"
+        width="180px"
+      />
+      <el-table-column align="center" label="负责人" prop="ownerUserName" width="100px" />
+      <el-table-column align="center" label="所属部门" prop="ownerUserDeptName" width="100px" />
+      <el-table-column align="center" label="创建人" prop="creatorName" width="100px" />
+      <el-table-column align="center" fixed="right" label="操作" min-width="150">
+        <template #default="scope">
+          <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
+            详情
+          </el-link>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      v-model:limit="queryParams.pageSize"
+      v-model:page="queryParams.pageNo"
+      :total="total"
+      @pagination="getList"
+    />
+  </ContentWrap>
+</template>
+
+<script lang="ts" setup>
+import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
+import { dateFormatter } from '@/utils/formatTime'
+import download from '@/utils/download'
+import * as CustomerApi from '@/api/crm/customer'
+
+defineOptions({ name: 'CrmCustomer' })
+
+const message = useMessage() // 消息弹窗
+
+const loading = ref(true) // 列表的加载中
+const total = ref(0) // 列表的总页数
+const list = ref([]) // 列表的数据
+const queryParams = ref({
+  pageNo: 1,
+  pageSize: 10,
+  name: '',
+  mobile: '',
+  industryId: undefined,
+  level: undefined,
+  source: undefined,
+  sceneType: undefined,
+  pool: true
+})
+const queryFormRef = ref() // 搜索的表单
+const exportLoading = ref(false) // 导出的加载中
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await CustomerApi.getCustomerPage(queryParams.value)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  queryParams.value = {
+    pageNo: 1,
+    pageSize: 10,
+    name: '',
+    mobile: '',
+    industryId: undefined,
+    level: undefined,
+    source: undefined,
+    sceneType: undefined,
+    pool: true
+  }
+  handleQuery()
+}
+
+/** 打开客户详情 */
+const { currentRoute, push } = useRouter()
+const openDetail = (id: number) => {
+  push({ name: 'CrmCustomerDetail', params: { id } })
+}
+
+/** 导出按钮操作 */
+const handleExport = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    // 发起导出
+    exportLoading.value = true
+    const data = await CustomerApi.exportCustomer(queryParams.value)
+    download.excel(data, '客户.xls')
+  } catch {
+  } finally {
+    exportLoading.value = false
+  }
+}
+
+/** 监听路由变化更新列表 */
+watch(
+  () => currentRoute.value,
+  () => {
+    getList()
+  }
+)
+
+/** 初始化 **/
+onMounted(() => {
+  getList()
+})
+</script>

+ 37 - 8
src/views/crm/followup/FollowUpRecordForm.vue

@@ -37,21 +37,43 @@
         </el-col>
         </el-col>
         <el-col :span="24">
         <el-col :span="24">
           <el-form-item label="关联联系人" prop="contactIds">
           <el-form-item label="关联联系人" prop="contactIds">
-            <el-button @click="submitForm">
-              <Icon class="mr-5px" icon="ep:plus" />
-              选择添加联系人
-            </el-button>
+            <el-select v-model="formData.contactIds" multiple placeholder="请选择">
+              <el-option
+                v-for="item in allContactList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              />
+            </el-select>
             <contact-list v-model:contactIds="formData.contactIds" />
             <contact-list v-model:contactIds="formData.contactIds" />
           </el-form-item>
           </el-form-item>
+          <!--          <el-form-item label="关联联系人" prop="contactIds">-->
+          <!--            <el-button @click="handleAddContact">-->
+          <!--              <Icon class="mr-5px" icon="ep:plus" />-->
+          <!--              选择添加联系人-->
+          <!--            </el-button>-->
+          <!--            <contact-list v-model:contactIds="formData.contactIds" />-->
+          <!--          </el-form-item>-->
         </el-col>
         </el-col>
         <el-col :span="24">
         <el-col :span="24">
           <el-form-item label="关联商机" prop="businessIds">
           <el-form-item label="关联商机" prop="businessIds">
-            <el-button @click="submitForm">
-              <Icon class="mr-5px" icon="ep:plus" />
-              选择添加商机
-            </el-button>
+            <el-select v-model="formData.businessIds" multiple placeholder="请选择">
+              <el-option
+                v-for="item in allBusinessList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              />
+            </el-select>
             <business-list v-model:businessIds="formData.businessIds" />
             <business-list v-model:businessIds="formData.businessIds" />
           </el-form-item>
           </el-form-item>
+          <!--          <el-form-item label="关联商机" prop="businessIds">-->
+          <!--            <el-button @click="handleAddBusiness">-->
+          <!--              <Icon class="mr-5px" icon="ep:plus" />-->
+          <!--              选择添加商机-->
+          <!--            </el-button>-->
+          <!--            <business-list v-model:businessIds="formData.businessIds" />-->
+          <!--          </el-form-item>-->
         </el-col>
         </el-col>
       </el-row>
       </el-row>
     </el-form>
     </el-form>
@@ -65,6 +87,8 @@
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { FollowUpRecordApi, FollowUpRecordVO } from '@/api/crm/followup'
 import { FollowUpRecordApi, FollowUpRecordVO } from '@/api/crm/followup'
 import { BusinessList, ContactList } from './components'
 import { BusinessList, ContactList } from './components'
+import * as ContactApi from '@/api/crm/contact'
+import * as BusinessApi from '@/api/crm/business'
 
 
 /** 跟进记录 表单 */
 /** 跟进记录 表单 */
 defineOptions({ name: 'FollowUpRecordForm' })
 defineOptions({ name: 'FollowUpRecordForm' })
@@ -82,7 +106,10 @@ const formRules = reactive({
   content: [{ required: true, message: '跟进内容不能为空', trigger: 'blur' }],
   content: [{ required: true, message: '跟进内容不能为空', trigger: 'blur' }],
   nextTime: [{ required: true, message: '下次联系时间不能为空', trigger: 'blur' }]
   nextTime: [{ required: true, message: '下次联系时间不能为空', trigger: 'blur' }]
 })
 })
+
 const formRef = ref() // 表单 Ref
 const formRef = ref() // 表单 Ref
+const allContactList = ref<ContactApi.ContactVO[]>([]) // 所有联系人列表
+const allBusinessList = ref<BusinessApi.BusinessVO[]>([]) // 所有商家列表
 
 
 /** 打开弹窗 */
 /** 打开弹窗 */
 const open = async (bizType: number, bizId: number, type: string, id?: number) => {
 const open = async (bizType: number, bizId: number, type: string, id?: number) => {
@@ -92,6 +119,8 @@ const open = async (bizType: number, bizId: number, type: string, id?: number) =
   resetForm()
   resetForm()
   formData.value.bizType = bizType
   formData.value.bizType = bizType
   formData.value.bizId = bizId
   formData.value.bizId = bizId
+  allContactList.value = await ContactApi.getSimpleContactList()
+  allBusinessList.value = await BusinessApi.getSimpleBusinessList()
   // 修改时,设置数据
   // 修改时,设置数据
   if (id) {
   if (id) {
     formLoading.value = true
     formLoading.value = true

+ 6 - 1
src/views/crm/followup/components/ContactList.vue

@@ -67,13 +67,18 @@ const props = withDefaults(defineProps<{ contactIds: number[] }>(), {
   contactIds: () => []
   contactIds: () => []
 })
 })
 const list = ref<ContactApi.ContactVO[]>([] as ContactApi.ContactVO[])
 const list = ref<ContactApi.ContactVO[]>([] as ContactApi.ContactVO[])
+const getContactList = async () => {
+  list.value = (await ContactApi.getContactListByIds(
+    props.contactIds
+  )) as unknown as ContactApi.ContactVO[]
+}
 watch(
 watch(
   () => props.contactIds,
   () => props.contactIds,
   (val) => {
   (val) => {
     if (!val || val.length === 0) {
     if (!val || val.length === 0) {
       return
       return
     }
     }
-    list.value = ContactApi.getContactListByIds(val) as unknown as ContactApi.ContactVO[]
+    getContactList()
   }
   }
 )
 )
 const emits = defineEmits<{
 const emits = defineEmits<{