소스 검색

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper

Min 11 달 전
부모
커밋
0b2b8d76c4
18개의 변경된 파일509개의 추가작업 그리고 44개의 파일을 삭제
  1. 6 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/api.ts
  2. 156 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/component/deteleTables.vue
  3. 173 26
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/index.vue
  4. 30 8
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ContactsController.java
  5. 21 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ReportController.java
  6. 9 4
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/BusinessItemProduct.java
  7. 6 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/vo/UserVO.java
  8. 1 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/CustomMapper.java
  9. 5 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/UserMapper.java
  10. 1 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/ContactsService.java
  11. 4 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/CustomService.java
  12. 1 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/BusinessOpportunityServiceImpl.java
  13. 1 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ContactsDocumentServiceImpl.java
  14. 15 3
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ContactsServiceImpl.java
  15. 41 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CustomServiceImpl.java
  16. 2 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java
  17. 1 1
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/BusinessItemProductMapper.xml
  18. 36 0
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/UserMapper.xml

+ 6 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/api.ts

@@ -1,5 +1,5 @@
 export const MOD = '/order'
-export const IMPOERMOD = 'Order'
+export const IMPORTMOD = 'Order'
 
 export const GETSYSFILED = "/sys-dict/getListByCode";
 export const GETPERSONNEL = "/user/getSimpleActiveUserList";
@@ -9,6 +9,11 @@ export const GETTABLELISTPRODUCT = `/product/list`
 export const GETTABLELIST = `${MOD}/list`
 export const URL_OEDERUPDATE = `${MOD}/addOrUpdate`
 export const URL_PRODUTWITHORDER = `${MOD}/productWithOrder`
+export const URL_DETELEITEM = `${MOD}/delete`
+export const EXPORTTIME = `${MOD}/exportData`
+export const IMPORITEM = `${MOD}/importData`
+export const URL_BATCHDELETE = `${MOD}/batchDeleteOrder`
+export const URL_RECOVER = `${MOD}/recover`
 
 export const tableColumns: TableColumn[] = [
     { prop: 'orderCode', label: '订单编号', event: 'toDetali', width: '150' },

+ 156 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/component/deteleTables.vue

@@ -0,0 +1,156 @@
+<template>
+    <el-dialog v-model="deteleBusinessDialogVisible" width="1000" :before-close="beForeCancel" :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>
+                    <el-button type="primary" v-loading="allLoading.batchRecoveryLoading" :disabled="batchTableData.length == 0"
+                        @click="batchOperation('恢复')">批量恢复</el-button>
+                    <el-button type="primary" v-loading="allLoading.batchDeteleLoading" :disabled="batchTableData.length == 0"
+                        @click="batchOperation('删除')">批量删除</el-button>
+                    <el-button @click="cancel()">取消</el-button>
+                </div>
+            </div>
+        </template>
+        <div class="h-[60vh] flex flex-col">
+            <div class="flex-1 w-full overflow-hidden">
+                <el-table ref="busiessTableRef" :data="deteleBusinessTable" border v-loading="allLoading.tableLoading"
+                    @selection-change="changeBatch" style="width: 100%;height: 100%;">
+                    <el-table-column type="selection" width="55" />
+                    <el-table-column v-for="(item, index) in tableColumns" :prop="item.prop" :label="item.label" :key="index"
+                        :width="item.width">
+                        <template #default="scope">
+                            <span>{{ scope.row[item.prop] }}</span>
+                        </template>
+                    </el-table-column>
+                    <el-table-column label="操作" fixed="right" width="120">
+                        <template #default="scope">
+                            <el-button link type="primary" size="large"
+                                @click="businessOperationItem(scope.row.id, scope.row.name, '恢复')">恢复</el-button>
+                            <el-button link type="danger" size="large"
+                                @click="businessOperationItem(scope.row.id, scope.row.name, '删除')">删除</el-button>
+                        </template>
+                    </el-table-column>
+                </el-table>
+            </div>
+            <div class="flex justify-end pt-3">
+                <el-pagination layout="total, prev, pager, next, sizes" :page-size="tableForm.pageSize"
+                    @size-change="handleSizeChange" @current-change="handleCurrentChange" :total="businessTotalTable"
+                    :hide-on-single-page="true" />
+            </div>
+        </div>
+    </el-dialog>
+</template>
+<script lang="ts" setup>
+import { post } from '@/utils/request';
+import { ref, reactive, onMounted, watchEffect, watch, inject } from 'vue'
+import { GETTABLELIST, tableColumns, URL_BATCHDELETE, URL_RECOVER } from '../api';
+import { ElTable } from 'element-plus';
+import { confirmAction } from '@/utils/tools';
+import { formatDate } from '@/utils/times';
+
+type operationType = '恢复' | '删除'
+
+const emits = defineEmits(['closeVisible']);
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const deteleBusinessTable = ref([])
+const deteleBusinessDialogVisible = ref(false)
+const businessTotalTable = ref(0)
+const batchTableData = ref([])
+const allLoading = reactive({
+    batchRecoveryLoading: false,
+    batchDeteleLoading: false,
+    tableLoading: false
+})
+
+const tableForm = reactive({
+    pageIndex: 1,
+    pageSize: 10
+})
+
+const busiessTableRef = ref<InstanceType<typeof ElTable>>() // 线索table dom
+
+const props = defineProps<{
+    visibles: boolean
+}>()
+
+watch(() => props.visibles, (newVal) => {
+    deteleBusinessDialogVisible.value = newVal
+    if (newVal) {
+        getTableList()
+    }
+})
+
+function batchOperation(type: operationType) {
+    const value = batchTableData.value.map((item: any) => item.id).join(',')
+    const label = batchTableData.value.map((item: any) => item.name).join(',')
+    businessOperationItem(value, label, type, true)
+}
+
+function businessOperationItem(value: string | number, label: string, type: operationType, batch: boolean = false) {
+    confirmAction(`确定${batch ? '批量' : ''}${type}【${label}】销售订单吗?`).then(() => {
+        let url = type == '恢复' ? URL_RECOVER : URL_BATCHDELETE
+        // let url = ''
+        post(url, { ids: value }).then(res => {
+            if (res.code != 'ok') {
+                globalPopup?.showError(res.msg)
+                return
+            }
+            globalPopup?.showSuccess(`${type}成功`)
+            getTableList()
+            changeBatch(false)
+        }).catch((err) => {
+            globalPopup?.showError(err.message)
+        })
+    })
+}
+
+function changeBatch(flag: boolean = true) {
+    if (flag) {
+        batchTableData.value = busiessTableRef.value && busiessTableRef.value.getSelectionRows()
+    } else {
+        batchTableData.value = []
+        busiessTableRef.value && busiessTableRef.value.clearSelection()
+    }
+}
+
+function getTableList() {
+    allLoading.tableLoading = true
+    post(GETTABLELIST, { ...tableForm, isDelete: 1 }).then((res) => {
+        if (res.code == 'ok') {
+            const { record, total } = res.data
+            deteleBusinessTable.value = record
+            businessTotalTable.value = total
+        }
+    }).finally(() => {
+        allLoading.tableLoading = false
+    })
+}
+
+function handleSizeChange(val: number) {
+    tableForm.pageIndex = 1
+    tableForm.pageSize = val
+    getTableList()
+}
+
+function handleCurrentChange(val: number) {
+    tableForm.pageIndex = val
+    getTableList()
+}
+
+function cancel() {
+    emits('closeVisible', 'deteleOrderVisible')
+}
+
+function beForeCancel(done: () => void) {
+    emits('closeVisible', 'deteleOrderVisible')
+    done()
+}
+
+onMounted(() => {
+
+})
+
+</script>
+<style lang="scss" scoped></style>

+ 173 - 26
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/index.vue

@@ -37,16 +37,17 @@
         <div class="flex justify-end pb-3">
           <!-- 操作按钮 -->
           <el-button type="primary" @click="editOrder(false)">新建订单</el-button>
-          <el-button type="primary">批量转移</el-button>
-          <el-button type="primary">批量删除</el-button>
-          <el-button type="primary">回收站</el-button>
-          <el-button type="primary">导入</el-button>
-          <el-button type="primary">导出</el-button>
+          <el-button type="primary" :disabled="batchTableData.length <= 0">批量转移</el-button>
+          <el-button type="primary" @click="batchDeteleItem()" :disabled="batchTableData.length <= 0">批量删除</el-button>
+          <el-button type="primary" @click="showVisible('deteleOrderVisible')">回收站</el-button>
+          <el-button type="primary" @click="showVisible('importVisible')">导入</el-button>
+          <el-button type="primary" @click="exportOrderTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
         </div>
         <div class="flex-1 w-full overflow-hidden">
           <!-- 表格 -->
           <el-table ref="otherTableRef" :data="formTable" border v-loading="allLoading.formTableLading"
-            style="width: 100%;height: 100%;">
+            style="width: 100%;height: 100%;" @selection-change="changeBatch">
+            <el-table-column type="selection" width="55" />
             <el-table-column v-for="(column, index) in tableColumns" :key="index" :prop="column.prop"
               :label="column.label" :width="column.width">
               <template #default="scope">
@@ -59,8 +60,9 @@
             <el-table-column :label="'操作'" :width="'200px'" fixed="right">
               <template #default="scope">
                 <el-button link type="primary" size="large" @click="editOrder(scope.row)">编辑</el-button>
-                <el-button link type="primary" size="large">新建任务</el-button>
-                <el-button link type="danger" size="large">删除</el-button>
+                <el-button link type="primary" size="large" @click="newTask(scope.row)">新建任务</el-button>
+                <el-button link type="danger" size="large"
+                  @click="orderDeteleItem(scope.row.id, scope.row.orderName)">删除</el-button>
               </template>
             </el-table-column>
           </el-table>
@@ -68,7 +70,7 @@
         <div class="flex justify-end pt-3">
           <!-- 分页 -->
           <el-pagination layout="total, prev, pager, next, sizes" :total="formTablePaging.total"
-            :hide-on-single-page="true" />
+            :hide-on-single-page="true" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
         </div>
       </div>
     </div>
@@ -88,7 +90,39 @@
       <div class="h-[60vh] overflow-y-auto scroll-bar pt-3" v-loading="allLoading.orderTemplateLoadinng">
         <GenerateForm ref="orderTemplateRef" :data="orderTemplate" :value="orderTemplateValue" />
         <div>相关产品</div>
-        <RelatedProducts ref="relatedProductsRef" :productTableList="productTableList" :productTableListValue="productTableListValue" />
+        <RelatedProducts ref="relatedProductsRef" :productTableList="productTableList"
+          :productTableListValue="productTableListValue" />
+      </div>
+    </el-dialog>
+
+    <!-- 新建任务 -->
+    <TaskModal :visible="allVisible.taskModalVisible" :edit-form="taskModalForm" :save-loading="taskLoading"
+      @close="allVisible.taskModalVisible = false" @submit="submitForm" :title="'新建任务'"
+      :disabled-list="['taskType', 'orderId']" />
+
+    <!-- 回收站 -->
+    <DeteleTables :visibles="allVisible.deteleOrderVisible" @closeVisible="closeVisible" />
+
+    <!-- 导入 -->
+    <el-dialog v-model="allVisible.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="importBusiness">
+              <el-button type="primary" :loading="allLoading.importLoading">导入</el-button>
+            </el-upload>
+            <el-button @click="allVisible.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(IMPORTMOD, allText.importText)">{{ allText.importText }}</el-link></div>
+          <div class="mt-4">2、填写excel文件、订单名称、客户名称、订单金额、负责人必填</div>
+        </div>
       </div>
     </el-dialog>
   </div>
@@ -96,16 +130,20 @@
 
 <script lang="ts" setup>
 import { ref, reactive, onMounted, inject, defineExpose } from "vue";
-import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, getTemplateKey } from '@/utils/tools'
-import { post, get } from "@/utils/request";
-import { tableColumns, GETSYSFILED, GETPERSONNEL, GETGENERATEFOEM, MOD, GETTABLELIST, GETALLPRODUCT, GETTABLELISTPRODUCT, URL_OEDERUPDATE, URL_PRODUTWITHORDER } from "./api";
+import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, getTemplateKey, createTaskFromType, confirmAction, downloadFile, downloadTemplate } from '@/utils/tools'
+import { post, get, uploadFile } from "@/utils/request";
+import { tableColumns, GETSYSFILED, GETPERSONNEL, GETGENERATEFOEM, MOD, GETTABLELIST, GETALLPRODUCT, GETTABLELISTPRODUCT, URL_OEDERUPDATE, URL_PRODUTWITHORDER, URL_DETELEITEM, EXPORTTIME, IMPORTMOD, IMPORITEM } from "./api";
 import { useRouter, useRoute } from "vue-router";
 import { GenerateForm } from '@zmjs/form-design';
+import { formatDateTime } from "@/utils/times";
+import { ElTable, UploadRequestOptions } from "element-plus";
+import { createTask } from "@/components/TaskModal/taskFunction";
 import { URL_FETALL } from "../customer/api";
 
 import RelatedProducts from '@/components/relatedProducts/relatedProducts.vue'
+import DeteleTables from './component/deteleTables.vue'
 import TaskModal from '@/components/TaskModal/index.vue'
-import { formatDateTime } from "@/utils/times";
+
 
 const router = useRouter()
 const globalPopup = inject<GlobalPopup>('globalPopup')
@@ -127,41 +165,129 @@ const selectData = reactive({ // 下拉数据
   AllProduct: [] as any[] // 所有产品
 })
 const formTablePaging = reactive({ // 分页条件
-  currentPage: 1,
+  pageIndex: 1,
   pageSize: 10,
   total: 0,
 })
 const allLoading = reactive({ // 按钮加载 Loading
   formTableLading: false,
   editSaveLading: false,
-  orderTemplateLoadinng: false
+  orderTemplateLoadinng: false,
+  exoprtLoading: false,
+  importLoading: false
 })
 const allVisible = reactive({
-  editOrderVisible: false
+  editOrderVisible: false,
+  taskModalVisible: false,
+  deteleOrderVisible: false,
+  importVisible: false
 })
 const allText = reactive({
-  orderEditText: '新建订单'
+  orderEditText: '新建订单',
+  importText: '销售订单表导出.xlsx'
 })
 const orderTemplate = ref({
   list: [],
   config: {}
 })
+const filterItems = ref<FilterItem[]>([
+  { label: '订单编号', key: 'orderCode', type: 'input' },
+  { label: '订单名称', key: 'orderName', type: 'input' },
+  { label: '客户名称', key: 'customId', type: 'select', options: selectData.Customer },
+  { label: '商机名称', key: 'businessOpportunityId', type: 'input' },
+  { label: '订单类型', key: 'ordertype', type: 'select', options: selectData.OrderType },
+  { label: '回款状态', key: 'receivedStatus', type: 'select', options: selectData.RemittanceStatus },
+  { label: '负责人', key: 'inchargerId', type: 'select', options: selectData.Personnel },
+  { label: '下单时间', key: '', type: 'date' },
+]) // 渲染筛选条件
 const orderTemplateValue = ref({})
 const orderTemplateKey = ref(1)
 const orderTemplateRef = ref<typeof GenerateForm>()
 const relatedProductsRef = ref<typeof RelatedProducts>()
-const filterItems = ref<FilterItem[]>([]) // 渲染筛选条件
+const otherTableRef = ref<InstanceType<typeof ElTable>>()
+const taskLoading = ref<saveLoadingType>('1')
+const batchTableData = ref([])
 const formTable = ref([]) // 表格数据
 const productTableList = ref([])
 const productTableListValue = ref([])
+const taskModalForm = ref({})
+
+async function importBusiness(param: UploadRequestOptions) {
+  allLoading.importLoading = true
+  const formData = new FormData();
+  formData.append('multipartFile', param.file)
+  const res = await uploadFile(IMPORITEM, formData).finally(() => {
+    allLoading.importLoading = false
+  })
+  if (res.code == 'ok') {
+    globalPopup?.showSuccess('导入成功' || '')
+    getTableList()
+    return
+  }
+  globalPopup?.showError(res.msg || '')
+}
+
+function exportOrderTableList() {
+  allLoading.exoprtLoading = true
+  let valueForm = getFromValue(filterForm)
+  post(EXPORTTIME, {...valueForm}).then((res) => {
+    downloadFile(res.data, allText.importText)
+  }).finally(() => {
+    allLoading.exoprtLoading = false
+  })
+}
+
+function batchDeteleItem() {
+  const value = batchTableData.value.map((item: any) => item.id).join(',')
+  const label = batchTableData.value.map((item: any) => item.orderName).join(',')
+  orderDeteleItem(value, label, true)
+}
+
+function orderDeteleItem(value: string | number, label: string, batch: boolean = false) {
+  confirmAction(`确定${batch ? '批量' : ''}删除【${label}】客户吗?`).then(() => {
+    post(URL_DETELEITEM, { ids: value }).then(res => {
+      if (res.code != 'ok') {
+        globalPopup?.showError(res.msg)
+        return
+      }
+      globalPopup?.showSuccess('删除成功')
+      changeBatch(false)
+      getTableList()
+    }).catch((err) => {
+      globalPopup?.showError(err.message)
+    })
+  })
+}
+
+function submitForm(submitData: any, isClose: boolean) {
+  taskLoading.value = '2'
+  createTask(submitData, isClose).then((res) => {
+    const { saveLoading, isClose } = res
+    taskLoading.value = saveLoading
+    allVisible.taskModalVisible = isClose
+    globalPopup?.showSuccess('新增成功')
+  }).catch((err) => {
+    const { saveLoading, isClose, message } = err
+    taskLoading.value = saveLoading
+    allVisible.taskModalVisible = isClose
+    globalPopup?.showError(message)
+  })
+}
+
+function newTask(item: any) {
+  const { id } = item
+  taskModalForm.value = { ...createTaskFromType(2), orderId: id, }
+  console.log(taskModalForm.value)
+  allVisible.taskModalVisible = true
+}
 
 function saveOrder(flag: boolean) {
   orderTemplateRef.value?.getData().then((res: any) => {
     let productTableListData = relatedProductsRef?.value?.returnData()
-    for(var i in productTableListData) {
+    for (var i in productTableListData) {
       productTableListData[i].sealPrice = productTableListData[i].sellingPrice,
-      productTableListData[i].discount = productTableListData[i].discount,
-      productTableListData[i].num = productTableListData[i].quantity
+        productTableListData[i].discount = productTableListData[i].discount,
+        productTableListData[i].num = productTableListData[i].quantity
     }
     const produt = productTableListData ? JSON.stringify(productTableListData) : []
     allLoading.editSaveLading = true
@@ -221,7 +347,7 @@ function toDetali(row: any) {
 
 function getTableList() {
   const formValue = getFromValue(filterForm)
-  const formPaging = { pageIndex: formTablePaging.currentPage, pageSize: formTablePaging.pageSize }
+  const formPaging = { pageIndex: formTablePaging.pageIndex, pageSize: formTablePaging.pageSize }
   allLoading.formTableLading = true
   post(GETTABLELIST, { ...formValue, ...formPaging }).then(res => {
     const { total, record } = res.data
@@ -273,6 +399,15 @@ async function getSystemField() {
   setFilterItems()
 }
 
+function changeBatch(flag: boolean = true) {
+  if (flag) {
+    batchTableData.value = otherTableRef.value && otherTableRef.value.getSelectionRows()
+  } else {
+    batchTableData.value = []
+    otherTableRef.value && otherTableRef.value.clearSelection()
+  }
+}
+
 function showVisible(type: keyof typeof allVisible) { // 显示弹窗
   allVisible[type] = true
 }
@@ -298,9 +433,10 @@ function editProduct(row: any) {
   post(URL_PRODUTWITHORDER, { id: row.id }).then(({ data }) => {
     const list = data.map((item: any) => {
       const { id, productName, productCode, unit, unitName, typeName, type, price, inventory, orderProductDetail } = item
-      return { id, productId: id, productName, productCode, unit, unitName, typeName, type, price, inventory, 
-        quantity: +orderProductDetail?.num, 
-        discount: +orderProductDetail?.discount, 
+      return {
+        id, productId: id, productName, productCode, unit, unitName, typeName, type, price, inventory,
+        quantity: +orderProductDetail?.num,
+        discount: +orderProductDetail?.discount,
         sellingPrice: +orderProductDetail?.sealPrice,
         totalPrice: +orderProductDetail?.totalPrice
       }
@@ -336,6 +472,17 @@ function getProductTableList() {
   })
 }
 
+function handleSizeChange(val: number) {
+  formTablePaging.pageIndex = 1
+  formTablePaging.pageSize = val
+  getTableList()
+}
+
+function handleCurrentChange(val: number) {
+  formTablePaging.pageIndex = val
+  getTableList()
+}
+
 onMounted(() => {
   getSystemField()
   getAllProduct()

+ 30 - 8
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ContactsController.java

@@ -1,6 +1,7 @@
 package com.management.platform.controller;
 
 
+import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.Contacts;
 import com.management.platform.entity.Custom;
@@ -56,8 +57,8 @@ public class ContactsController {
         return contactsService.addContacts(contacts, request);
     }
     @RequestMapping("/getAllContacts")
-    public HttpRespMsg getAllContacts(HttpServletRequest request){
-        return contactsService.getAllContacts(request);
+    public HttpRespMsg getAllContacts(Integer customerId,HttpServletRequest request){
+        return contactsService.getAllContacts(customerId,request);
     }
 
     /**
@@ -101,8 +102,15 @@ public class ContactsController {
      * @return
      */
     @RequestMapping("deleteContacts")
-    public HttpRespMsg deleteContacts( List<Integer> ids){
-        return contactsService.deleteContacts(ids,request);
+    public HttpRespMsg deleteContacts( String ids){
+        if (!StringUtils.isEmpty(ids)) {
+            ids="["+ids+"]";
+            List<Integer> array = JSONArray.parseArray(ids, Integer.class);
+            return contactsService.deleteContacts(array,request);
+        }
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.setError("参数不能为空");
+        return msg;
     }
 
     /**
@@ -120,8 +128,15 @@ public class ContactsController {
      * 批量删除回收站中的联系人
      */
     @RequestMapping("confirmDeleteContacts")
-    public HttpRespMsg confirmDeleteContacts(List<Integer> ids){
-        return contactsService.confirmDeleteContacts(ids);
+    public HttpRespMsg confirmDeleteContacts(String ids){
+        if (!StringUtils.isEmpty(ids)) {
+            ids="["+ids+"]";
+            List<Integer> array = JSONArray.parseArray(ids, Integer.class);
+            return contactsService.confirmDeleteContacts(array);
+        }
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.setError("参数不能为空");
+        return msg;
     }
 
     /**
@@ -130,8 +145,15 @@ public class ContactsController {
      * @return
      */
     @RequestMapping("returnContacts")
-    public HttpRespMsg returnContacts(List<Integer> ids){
-        return contactsService.returnContacts(ids);
+    public HttpRespMsg returnContacts(String ids){
+        if (!StringUtils.isEmpty(ids)) {
+            ids="["+ids+"]";
+            List<Integer> array = JSONArray.parseArray(ids, Integer.class);
+            return contactsService.returnContacts(array);
+        }
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.setError("参数不能为空");
+        return msg;
     }
 
     @RequestMapping("getContactsDetail")

+ 21 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ReportController.java

@@ -15,6 +15,7 @@ import com.management.platform.entity.vo.WorktimeItem;
 import com.management.platform.mapper.*;
 import com.management.platform.service.*;
 import com.management.platform.util.*;
+import me.chanjar.weixin.mp.constant.WxMpEventConstants;
 import okhttp3.OkHttpClient;
 import okhttp3.Request;
 import okhttp3.WebSocket;
@@ -106,6 +107,9 @@ public class ReportController {
     @Resource
     private EstimateTimeSettingMapper estimateTimeSettingMapper;
 
+    @Autowired
+    private CustomService customService;
+
     //获取任务相关的日报列表
     @RequestMapping("/getTaskReportList")
     public HttpRespMsg getTaskReportList(Integer taskId) {
@@ -214,6 +218,23 @@ public class ReportController {
         return reportService.getReportFillStatus(startDate, endDate, userId, request);
     }
 
+    /**
+     * 客户总量分析
+     * @param startDate
+     * @param endDate
+     * @param userId
+     * @return
+     */
+    @RequestMapping("/getCustomerTotalCount")
+    public HttpRespMsg getCustomerTotalCount(String startDate, String endDate, String userId) {
+        return  customService.getCustomerTotalCount(startDate, endDate, userId, request);
+    }
+
+    @RequestMapping("/getCustomerTransferRate")
+    public HttpRespMsg getCustomerTransferRate(String startDate, String endDate, String userId) {
+        return  customService.getCustomerTransferRate(startDate, endDate, userId, request);
+    }
+
     @RequestMapping("/getReportList")
     public HttpRespMsg getReportList(@RequestParam String date, @RequestParam(required = false) Integer deptId, @RequestParam(required = false) String userId) {
         return reportService.getReportList(date, deptId, userId, request);

+ 9 - 4
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/BusinessItemProduct.java

@@ -28,21 +28,26 @@ public class BusinessItemProduct extends Model<BusinessItemProduct> {
      *  
      */
     @TableId("id")
-    private Integer id;
+    private Long id;
 
     /**
      * 产品id
      */
     @TableField("product_id")
     private Integer productId;
+    /**
+     * 产品id
+     */
+    @TableField("inventory")
+    private Integer inventory;
     @TableField(exist = false)
     private String productName;
     @TableField(exist = false)
     private String unit;
-    @TableField(exist = false)
+    @TableField("price")
     private BigDecimal price;
-    @TableField(exist = false)
-    private String inventory;
+//    @TableField(exist = false)
+//    private String inventory;
     @TableField(exist = false)
     private String productType;
 

+ 6 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/vo/UserVO.java

@@ -26,4 +26,10 @@ public class UserVO extends User {
 
     private boolean hasAuditDept;
 
+    private Integer customertotal;//客户总量
+    private Integer customerDeal;//客户成交量
+    private Double dealRate;//客户成交量率
+    private Integer num;//客户数量
+    private Integer saleNum;//交易客户数量
+
 }

+ 1 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/CustomMapper.java

@@ -3,6 +3,7 @@ package com.management.platform.mapper;
 import com.management.platform.entity.Clue;
 import com.management.platform.entity.Custom;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.util.HttpRespMsg;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;

+ 5 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/UserMapper.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.management.platform.entity.User;
+import com.management.platform.entity.vo.UserVO;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Update;
 
@@ -57,4 +58,8 @@ public interface UserMapper extends BaseMapper<User> {
     List<User> getInActiveBewttenStartAndEndList(ArrayList<Integer> deptIds, String startDate, String endDate);
 
     void updateActiveByIds(List<String> array, int isActive);
+
+    List<UserVO> getCustomerTotalCount(String startDate, String endDate, String userId, Integer companyId);
+
+    List<UserVO> getCustomerTransferRate(String startDate, String endDate, String userId, Integer companyId);
 }

+ 1 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/ContactsService.java

@@ -42,7 +42,7 @@ public interface ContactsService extends IService<Contacts> {
 
     HttpRespMsg exportData(String customName, String name, String email, String creatorName, String phone, String ownerName, HttpServletRequest request) throws Exception;
 
-    HttpRespMsg getAllContacts(HttpServletRequest request);
+    HttpRespMsg getAllContacts(Integer customerId, HttpServletRequest request);
 
     int transferContacts(Contacts contactsGet, User user);
 }

+ 4 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/CustomService.java

@@ -54,4 +54,8 @@ public interface CustomService extends IService<Custom> {
     Map<String, Object> getDataSummary(Integer companyId,String startDate, String endDate, String userId,@Param("list") List<String> targetUserIds);
 
     void deleterDelete(List<Integer> ids);
+
+    HttpRespMsg getCustomerTotalCount(String startDate, String endDate, String userId, HttpServletRequest request);
+
+    HttpRespMsg getCustomerTransferRate(String startDate, String endDate, String userId, HttpServletRequest request);
 }

+ 1 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/BusinessOpportunityServiceImpl.java

@@ -144,6 +144,7 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
         List<BusinessItemProduct> businessItemProducts = JSONArray.parseArray(bo.getBusinessItemProductList(), BusinessItemProduct.class);
         for (BusinessItemProduct businessItemProduct : businessItemProducts) {
             businessItemProduct.setBusinessId(bo.getId());
+//            businessItemProduct.setId(null);
             bipMapper.insert(businessItemProduct);
         }
         ActionLog actionLog = new ActionLog();

+ 1 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ContactsDocumentServiceImpl.java

@@ -155,6 +155,7 @@ public class ContactsDocumentServiceImpl extends ServiceImpl<ContactsDocumentMap
         ContactsDocument contactsDocument = contactsDocumentMapper.selectById(fileId);
         if (contactsDocument==null){
             msg.setError("文件不存在");
+            return msg;
         }
         LambdaUpdateWrapper<ContactsDocument> ulw = new LambdaUpdateWrapper<>();
         ulw.set(ContactsDocument::getDocumentName,newName).eq(ContactsDocument::getId,fileId);

+ 15 - 3
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ContactsServiceImpl.java

@@ -88,15 +88,19 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
         Integer companyId = user.getCompanyId();
         if (StringUtils.isEmpty(contacts.getName())){
             httpRespMsg.setError("请输入联系人姓名");
+            return httpRespMsg;
         }
         if (contacts.getCustomId()==null){
             httpRespMsg.setError("客户信息为空");
+            return httpRespMsg;
         }
         if (StringUtils.isEmpty(contacts.getPhone())){
             httpRespMsg.setError("联系人电话号码为空");
+            return httpRespMsg;
         }
         if (contacts.getOwnerId() == null) {
             httpRespMsg.setError("负责人信息为空!");
+            return httpRespMsg;
         }
 
         LambdaQueryWrapper<Contacts> lqw_contacts = new LambdaQueryWrapper<>();
@@ -107,6 +111,7 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
         Contacts selectedOne = contactsMapper.selectOne(lqw_contacts);
         if (selectedOne != null) {
             httpRespMsg.setError("已存在该联系人!");
+            return httpRespMsg;
         }
         contacts.setCompanyId(companyId)
                 //todo:联系人的所有人是可选择的
@@ -203,6 +208,7 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
                     oName+=businessOpportunity.getName()+" ";
                 }
                 msg.setError(oName+"等商机正在进行且跟联系人有关");
+                return msg;
             }
         }
         List<Task> taskList = taskMapper.selectList(new QueryWrapper<Task>().in("contacts_id", ids));
@@ -210,6 +216,7 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
             List<Task> collect = taskList.stream().filter(t ->t.getStatus()!=null&&t.getStatus() != 2).collect(Collectors.toList());
             if (!collect.isEmpty()){
                 msg.setError("存在任务未完成且跟联系人有关");
+                return msg;
             }
         }
         contactsUpdateWrapper.in("id", ids);
@@ -305,7 +312,7 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
 
             //附件信息查询
             LambdaQueryWrapper<ContactsDocument> cDLqw = new LambdaQueryWrapper<>();
-            cDLqw.eq(ContactsDocument::getContactsId,contactsSelect.getId());
+            cDLqw.eq(ContactsDocument::getContactsId,contactsSelect.getId()).ne(ContactsDocument::getIsDeleted,1);
             List<ContactsDocument> contactsDocuments = contactsDocumentMapper.selectList(cDLqw);
 
             //返回数据
@@ -579,10 +586,15 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
     }
 
     @Override
-    public HttpRespMsg getAllContacts(HttpServletRequest request) {
+    public HttpRespMsg getAllContacts(Integer customerId, HttpServletRequest request) {
         User user = userMapper.selectById(request.getHeader("token"));
         HttpRespMsg mgs = new HttpRespMsg();
-        mgs.setData(contactsMapper.selectList(new QueryWrapper<Contacts>().eq("company_id",user.getCompanyId())));
+        if (customerId!=null){
+            mgs.setData(contactsMapper.selectList(new QueryWrapper<Contacts>()
+                    .eq("company_id",user.getCompanyId())
+                    .eq("custom_id",customerId)));
+        }else
+            mgs.setData(contactsMapper.selectList(new QueryWrapper<Contacts>().eq("company_id",user.getCompanyId())));
         return mgs;
     }
 

+ 41 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CustomServiceImpl.java

@@ -3,6 +3,7 @@ package com.management.platform.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.management.platform.entity.*;
+import com.management.platform.entity.vo.UserVO;
 import com.management.platform.mapper.*;
 import com.management.platform.service.CustomService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -391,6 +392,46 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
         customMapper.deleteBatchIds(ids);
     }
 
+    @Override
+    public HttpRespMsg getCustomerTotalCount(String startDate, String endDate, String userId, HttpServletRequest request) {
+        User user = userMapper.selectById(request.getHeader("token"));
+        Integer companyId = user.getCompanyId();
+        List<UserVO> userVoList=userMapper.getCustomerTotalCount(startDate,endDate,userId,companyId);
+        if (userVoList!=null&&!userVoList.isEmpty()){
+            for (UserVO userVO : userVoList) {
+                if (userVO.getCustomertotal()==0){
+                    userVO.setDealRate((double) 0);
+                }else {
+                    userVO.setDealRate((double) (userVO.getCustomerDeal()/userVO.getCustomertotal()));
+                }
+            }
+        }
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.setData(userVoList);
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg getCustomerTransferRate(String startDate, String endDate, String userId, HttpServletRequest request) {
+        User user = userMapper.selectById(request.getHeader("token"));
+        Integer companyId = user.getCompanyId();
+        List<UserVO> userVoList=userMapper.getCustomerTransferRate(startDate,endDate,userId,companyId);
+        if (userVoList!=null&&!userVoList.isEmpty()){
+            for (UserVO userVO : userVoList) {
+                if (userVO.getNum()==0){
+                    userVO.setDealRate((double) 0);
+                }else {
+                    double v = (double) userVO.getSaleNum() / userVO.getNum();
+                    userVO.setDealRate(v);
+                }
+            }
+        }
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.setData(userVoList);
+        return msg;
+
+    }
+
 
     private Custom setNull(Custom clue) {
         if (clue.getPlate1() == "") {

+ 2 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java

@@ -272,6 +272,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
             List<Task> collect = taskList.stream().filter(task ->task.getStatus()!=0&& task.getStatus() != 2).collect(Collectors.toList());
             if (collect.size()>0){
                 msg.setError("存在任务未完成,不能删除");
+                return msg;
             }
             LambdaUpdateWrapper<Task> tUlw = new LambdaUpdateWrapper<>();
             tUlw.set(Task::getIsDelete,1).in(Task::getId,taskIds);
@@ -860,6 +861,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         HttpRespMsg msg = new HttpRespMsg();
         if (taskDto==null||taskDto.getId()==null){
             msg.setError("缺少用户的关键信息");
+            return msg;
         }
         LambdaUpdateWrapper<Task> luw = new LambdaUpdateWrapper<>();
         luw.set(Task::getStatus,taskDto.getStatus()).eq(Task::getId,taskDto.getId());

+ 1 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/BusinessItemProductMapper.xml

@@ -4,7 +4,7 @@
 
     <!-- 通用查询映射结果 -->
     <resultMap id="BaseResultMap" type="com.management.platform.entity.BusinessItemProduct">
-        <id column="id" property="id" />
+        <id column="id" property="id" javaType="java.lang.Long" />
         <result column="product_id" property="productId" />
         <result column="quantity" property="quantity" />
         <result column="discount" property="discount" />

+ 36 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/UserMapper.xml

@@ -277,6 +277,42 @@
         AND (induction_date &lt;= #{startDate} OR induction_date is NULL)
         AND id not IN (SELECT * from user_exclude)
     </select>
+    <select id="getCustomerTotalCount" resultType="com.management.platform.entity.vo.UserVO">
+
+        select count(*) as customertotal ,
+               sum(case when c.close_deal=1 then 1 else 0 end) as customerDeal ,
+               u.name,u.id
+            from custom c
+            left join user u on c.incharger_id=u.id
+        <where>
+            1=1 and c.company_id=#{companyId}
+
+            <if test="startDate !=null and startDate !='' and endDate !=null and endDate !=''">
+                AND  c.create_time BETWEEN #{startDate} AND #{endDate}
+            </if>
+            <if test="userId !=null and userId!=''">
+                AND  c.incharger_id=#{userId}
+            </if>
+        </where>
+            group by c.incharger_id
+
+    </select>
+    <select id="getCustomerTransferRate" resultType="com.management.platform.entity.vo.UserVO">
+        select count(distinct c.id) as num, count(distinct s.custom_id) as saleNum, c.incharger_id as id  ,u.name
+        from  custom c
+                  left join sales_order s on c.id=s.custom_id
+                  INNER JOIN user u on u.id=c.incharger_id
+        <where>
+            1=1 and c.company_id=#{companyId}
+            <if test="startDate !=null and startDate !='' and endDate !=null and endDate !=''">
+                AND  c.create_time BETWEEN #{startDate} AND #{endDate}
+            </if>
+            <if test="userId !=null and userId!=''">
+                AND  c.incharger_id=#{userId}
+            </if>
+        </where>
+        group by  c.incharger_id
+    </select>
 
     <update id="updateActiveByIds">
         update user set is_active=1 WHERE id IN