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

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

Min пре 11 месеци
родитељ
комит
157a527d71
35 измењених фајлова са 1578 додато и 458 уклоњено
  1. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/package.json
  2. 3 5
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/attachment.vue
  3. 16 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/information.vue
  4. 1 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/products.vue
  5. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/detail/index.vue
  6. 6 6
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue
  7. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/information.vue
  8. 6 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/api.ts
  9. 104 45
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/attachment.vue
  10. 188 17
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/information.vue
  11. 17 33
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/operationRecord.vue
  12. 142 45
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedBusiness.vue
  13. 104 46
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedContacts.vue
  14. 152 46
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedOrders.vue
  15. 21 14
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/detail/index.vue
  16. 3 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue
  17. 17 13
      fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/customInstructions.ts
  18. 26 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/tools.ts
  19. 26 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ContactsController.java
  20. 104 4
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/CustomController.java
  21. 14 4
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ReportController.java
  22. 3 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/ContactsLog.java
  23. 6 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Custom.java
  24. 4 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/ContactsService.java
  25. 5 2
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/CustomService.java
  26. 4 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/ReportService.java
  27. 3 2
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/BusinessOpportunityServiceImpl.java
  28. 200 73
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ContactsServiceImpl.java
  29. 222 13
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CustomServiceImpl.java
  30. 57 6
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  31. 24 16
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java
  32. 4 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  33. 42 10
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  34. 42 42
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  35. 9 1
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

+ 1 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/package.json

@@ -7,6 +7,7 @@
     "dev": "vite",
     "dev": "vite",
     "start": "vite",
     "start": "vite",
     "build": "vue-tsc && vite build",
     "build": "vue-tsc && vite build",
+    "buildNoTs": "vite build",
     "preview": "vite preview"
     "preview": "vite preview"
   },
   },
   "dependencies": {
   "dependencies": {

+ 3 - 5
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/attachment.vue

@@ -87,11 +87,9 @@ function saveEditClue() {
     }
     }
     const bussinessId = information.value.id
     const bussinessId = information.value.id
     post(REFIENAMEFILE, { name: renameVal.value, id: bussinessId }).then((res) => {
     post(REFIENAMEFILE, { name: renameVal.value, id: bussinessId }).then((res) => {
-        if (res.code == 'ok') {
-            renameDialogVisible.value = false
-            globalPopup?.showSuccess(res.msg || '')
-            emits('refreshData')
-        }
+        renameDialogVisible.value = false
+        globalPopup?.showSuccess(res.msg || '')
+        emits('refreshData')
     }).catch((_err) => { })
     }).catch((_err) => { })
 }
 }
 
 

+ 16 - 3
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/information.vue

@@ -132,6 +132,7 @@ const transferValue = ref('')
 const transferOptions = ref<personnelInterface[]>([])
 const transferOptions = ref<personnelInterface[]>([])
 const generateFormValue = ref({})
 const generateFormValue = ref({})
 const generateForm = ref<typeof GenerateForm>() // 自定义表单dom
 const generateForm = ref<typeof GenerateForm>() // 自定义表单dom
+const productTableListValue = ref<any[]>([])
 const contactsId = ref('')
 const contactsId = ref('')
 const contactsList = ref<optionType[]>([])
 const contactsList = ref<optionType[]>([])
 const allVisible = reactive({
 const allVisible = reactive({
@@ -196,17 +197,16 @@ function transferBusiness() {
 
 
 function claimBusiness() {
 function claimBusiness() {
     confirmAction(`确定认领【${information.value.name}】商机吗?`).then(() => {
     confirmAction(`确定认领【${information.value.name}】商机吗?`).then(() => {
-        console.log('执行认领')
+        transferBusiness()
     })
     })
 }
 }
 
 
 function editBusiness() {
 function editBusiness() {
-    console.log('点击了保存')
-    return
     generateForm.value?.getData().then((res: any) => {
     generateForm.value?.getData().then((res: any) => {
         let formVal = {
         let formVal = {
             ...res,
             ...res,
             expectedTransactionDate: res.expectedTransactionDate ? formatDateTime(new Date(res.expectedTransactionDate)) : '',
             expectedTransactionDate: res.expectedTransactionDate ? formatDateTime(new Date(res.expectedTransactionDate)) : '',
+            businessItemProductList: JSON.stringify(productTableListValue.value)
         }
         }
         allLoading.businessSaveLading = true
         allLoading.businessSaveLading = true
         post(UPDATEINSET, { ...formVal }).then((_res) => {
         post(UPDATEINSET, { ...formVal }).then((_res) => {
@@ -222,10 +222,23 @@ function editBusiness() {
     })
     })
 }
 }
 
 
+function editProductShow() {
+    const productList = information.value.businessItemProducts || []
+    const list = productList.map((item: any) => {
+        const { id, productName, productId, productCode, unit, unitName, typeName, type, price, inventory, orderProductDetail, num, discount, sealPrice, totalPrice, quantity } = item
+        return {
+            id, productId: productId, productName, productCode, unit, unitName, typeName, type, price, inventory,
+            num, discount, sealPrice, totalPrice, quantity
+        }
+    })
+    productTableListValue.value = list
+}
+
 function showVisible(type: keyof typeof allVisible) {
 function showVisible(type: keyof typeof allVisible) {
     if (type == 'editBusinessVisible') {
     if (type == 'editBusinessVisible') {
         const { name, customerId, contactsId, amountOfMoney, expectedTransactionDate, stageId, inchargerId, remark } = information.value
         const { name, customerId, contactsId, amountOfMoney, expectedTransactionDate, stageId, inchargerId, remark } = information.value
         generateFormValue.value = { name, customerId, contactsId, amountOfMoney, expectedTransactionDate, stageId, inchargerId, remark }
         generateFormValue.value = { name, customerId, contactsId, amountOfMoney, expectedTransactionDate, stageId, inchargerId, remark }
+        editProductShow()
     }
     }
     allVisible[type] = true
     allVisible[type] = true
 }
 }

+ 1 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/products.vue

@@ -83,9 +83,8 @@ function editProduct() {
     })
     })
     const { id, name, customerId, contactsId, amountOfMoney, expectedTransactionDate, stageId, inchargerId, remark } = information.value
     const { id, name, customerId, contactsId, amountOfMoney, expectedTransactionDate, stageId, inchargerId, remark } = information.value
     const formData = { id, name, customerId, contactsId, amountOfMoney, expectedTransactionDate, stageId, inchargerId, remark }
     const formData = { id, name, customerId, contactsId, amountOfMoney, expectedTransactionDate, stageId, inchargerId, remark }
-    console.log(productTableListData, '<===== 将要提交的数据', formData)
     allLoading.editProductLoading = true
     allLoading.editProductLoading = true
-    post(UPDATEINSET, { ...formData }).then((_res) => {
+    post(UPDATEINSET, { ...formData, businessItemProductList: JSON.stringify(productTableListData) }).then((_res) => {
         allVisible.editProductVisible = false
         allVisible.editProductVisible = false
         globalPopup?.showSuccess('操作成功')
         globalPopup?.showSuccess('操作成功')
         emits('refreshData')
         emits('refreshData')

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/detail/index.vue

@@ -68,7 +68,7 @@
 
 
       <div class="w-full h-auto flex justify-between mt-2">
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md w-full">
         <div class="bg-white shadow-md rounded-md w-full">
-          <Products :information="businessInfo" />
+          <Products :information="businessInfo" @refreshData="getDetail" />
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>

+ 6 - 6
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue

@@ -47,14 +47,14 @@
     <div class="flex-1 p-5 overflow-auto">
     <div class="flex-1 p-5 overflow-auto">
       <div class="bg-white w-full h-full p-3 shadow-md rounded-md flex flex-col">
       <div class="bg-white w-full h-full p-3 shadow-md rounded-md flex flex-col">
         <div class="flex justify-end pb-3">
         <div class="flex justify-end pb-3">
-          <el-button type="primary" @click="editNewBusiness(false)">新建商机</el-button>
+          <el-button v-permission="['businessAddAnEdit']" type="primary" @click="editNewBusiness(false)">新建商机</el-button>
           <el-button type="primary" @click="showVisible('batchTransferVisible')"
           <el-button type="primary" @click="showVisible('batchTransferVisible')"
             :disabled="batchTableData.length <= 0">批量转移</el-button>
             :disabled="batchTableData.length <= 0">批量转移</el-button>
           <el-button type="primary" @click="batchDeteleItem()" :disabled="batchTableData.length <= 0">批量删除</el-button>
           <el-button type="primary" @click="batchDeteleItem()" :disabled="batchTableData.length <= 0">批量删除</el-button>
           <el-button type="primary" @click="showVisible('stageSetVisible')">阶段设置</el-button>
           <el-button type="primary" @click="showVisible('stageSetVisible')">阶段设置</el-button>
           <el-button type="primary" @click="showVisible('deteleBusinessVisible')">回收站</el-button>
           <el-button type="primary" @click="showVisible('deteleBusinessVisible')">回收站</el-button>
-          <el-button type="primary" @click="showVisible('importVisible')">导入</el-button>
-          <el-button type="primary" @click="exportBusinessTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
+          <el-button v-permission="['businessImport']" type="primary" @click="showVisible('importVisible')">导入</el-button>
+          <el-button v-permission="['businessExport']" type="primary" @click="exportBusinessTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
         </div>
         </div>
         <div class="flex-1 w-full overflow-hidden">
         <div class="flex-1 w-full overflow-hidden">
           <el-table ref="businessTableRef" :data="businessTable" border v-loading="allLoading.businessTableLading"
           <el-table ref="businessTableRef" :data="businessTable" border v-loading="allLoading.businessTableLading"
@@ -70,10 +70,10 @@
             </el-table-column>
             </el-table-column>
             <el-table-column label="操作" fixed="right" width="200">
             <el-table-column label="操作" fixed="right" width="200">
               <template #default="scope">
               <template #default="scope">
-                <el-button link type="primary" size="large" @click="editNewBusiness(scope.row)">编辑</el-button>
-                <el-button link type="primary" size="large" @click="newTask(scope.row)">新建任务</el-button>
+                <el-button link type="primary" size="large" @click="editNewBusiness(scope.row)" v-permission="['businessAddAnEdit']">编辑</el-button>
+                <el-button link type="primary" size="large" @click="newTask(scope.row)" v-permission="['tasksAdd']">新建任务</el-button>
                 <el-button link type="danger" size="large"
                 <el-button link type="danger" size="large"
-                  @click="businessDeteleItem(scope.row.id, scope.row.name)">删除</el-button>
+                  @click="businessDeteleItem(scope.row.id, scope.row.name)" v-permission="['businessAddAnEdit']">删除</el-button>
               </template>
               </template>
             </el-table-column>
             </el-table-column>
           </el-table>
           </el-table>

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/information.vue

@@ -159,7 +159,7 @@ function closeVisible(type: keyof typeof allVisible) {
 }
 }
 
 
 const formItems = reactive([
 const formItems = reactive([
-    { label: '联系人', key: 'name', value: '', labelClass: 'w-20 text-right text-gray-500', width: '48%' },
+    { label: '联系人', key: 'contactsName', value: '', labelClass: 'w-20 text-right text-gray-500', width: '48%' },
     { label: '客户', key: 'productName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
     { label: '客户', key: 'productName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
     { label: '电话', key: 'phone', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
     { label: '电话', key: 'phone', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
     { label: '邮箱', key: 'email', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
     { label: '邮箱', key: 'email', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },

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

@@ -13,4 +13,9 @@ export const URL_ROWBACK = `${PREFIX}/rollback`
 export const URL_THOROUGHLYDETELE = `${PREFIX}/reallyDelete`
 export const URL_THOROUGHLYDETELE = `${PREFIX}/reallyDelete`
 export const URL_CLAIM = `${PREFIX}/claim`
 export const URL_CLAIM = `${PREFIX}/claim`
 export const URL_FETALL = `${PREFIX}/getAll`
 export const URL_FETALL = `${PREFIX}/getAll`
-export const URL_GETDETAIL = `${PREFIX}/getInfo`
+export const URL_GETDETAIL = `${PREFIX}/getInfo`
+export const URL_IMPORTEXELS = `${PREFIX}/importData`
+export const URL_EXPORTEXELS = `${PREFIX}/exportData`
+export const URL_UPLOADFILE = `${PREFIX}/uploadFile`
+export const URL_DETELEFILE = `${PREFIX}/deleteFile`
+export const URL_REFFILENAME = `${PREFIX}/reFileName`

+ 104 - 45
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/attachment.vue

@@ -3,65 +3,124 @@
         <div class="flex justify-between">
         <div class="flex justify-between">
             <div class="title">附件</div>
             <div class="title">附件</div>
             <div>
             <div>
-                <el-button type="primary">上传</el-button>
+                <el-upload ref="uploadRef" :http-request="httpUploadFile" :limit="1" :show-file-list="false"
+                    element-loading-text="正在上传">
+                    <template #trigger>
+                        <el-button type="primary">上传</el-button>
+                    </template>
+                </el-upload>
             </div>
             </div>
         </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
         <div class="flex-1 overflow-auto pt-3">
             <el-table :data="attachmenttable" border style="width: 100%;height: 200px;">
             <el-table :data="attachmenttable" border style="width: 100%;height: 200px;">
-                <el-table-column prop="fileName" label="附件名称" width="180" />
-                <el-table-column prop="fileSize" label="附件大小" width="120" />
-                <el-table-column prop="uploader" label="上传人" width="120" />
-                <el-table-column prop="uploadTime" label="上传时间" width="180" />
+                <el-table-column prop="name" label="附件名称" width="180" />
+                <el-table-column prop="size" label="附件大小" width="120" />
+                <el-table-column prop="userName" label="上传人" width="120" />
+                <el-table-column prop="createTime" label="上传时间" width="180" />
                 <el-table-column label="操作" width="180" fixed="right">
                 <el-table-column label="操作" width="180" fixed="right">
                     <template #default="scope">
                     <template #default="scope">
-                        <el-button link type="primary" size="large">下载</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="fileDownload(scope.row)">下载</el-button>
+                        <el-button link type="primary" size="large" @click="showVisible(scope.row)">重命名</el-button>
+                        <el-button link type="danger" size="large" @click="deteleFile(scope.row)">删除</el-button>
                     </template>
                     </template>
                 </el-table-column>
                 </el-table-column>
             </el-table>
             </el-table>
         </div>
         </div>
+
+        <!-- 弹窗 -->
+        <el-dialog v-model="renameDialogVisible" width="800" :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" @click="saveEditClue()">保存</el-button>
+                        <el-button @click="renameDialogVisible = false">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="pt-3">
+                <el-input v-model.trim="renameVal" style="width: 100%" class="pb-3" clearable />
+            </div>
+        </el-dialog>
     </div>
     </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { post, uploadFile } from '@/utils/request';
+import { UploadRequestOptions } from 'element-plus';
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+import { URL_DETELEFILE, URL_REFFILENAME, URL_UPLOADFILE } from '../api';
+import { confirmAction, downloadFile } from '@/utils/tools';
+
+const emits = defineEmits(['refreshData']);
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const props = defineProps<{
+    data: any
+}>()
+const attachmenttable = ref([])
+const information = ref<any>({})
+const uploadRef = <any>ref()
+const renameDialogVisible = ref(false)
+const renameVal = ref('')
+
+// 下载文件
+function fileDownload(item: any) {
+    downloadFile(`${item.path}`, item.name)
+}
+
+// 删除文件
+function deteleFile(item: any) {
+    const id = item.id
+    confirmAction(`确定删除【${item.name}】文件吗?`).then(() => {
+        post(URL_DETELEFILE, { id }).then((_res) => {
+            globalPopup?.showSuccess('删除成功')
+            emits('refreshData')
+        })
+    })
+}
+
+// 保存重命名
+function saveEditClue() {
+    if (!renameVal.value) {
+        globalPopup?.showWarning('请输入文件名称')
+        return
+    }
+    const id = information.value.id
+    post(URL_REFFILENAME, { name: renameVal.value, id: id }).then((res) => {
+        renameDialogVisible.value = false
+        globalPopup?.showSuccess(res.msg || '')
+        emits('refreshData')
+    }).catch((_err) => { })
+}
+
+// 上传文件
+async function httpUploadFile(param: UploadRequestOptions) {
+    const id = information.value.id
+    const formData = new FormData();
+    formData.append('file', param.file)
+    formData.append('id', id)
+    const res = await uploadFile(URL_UPLOADFILE, formData).finally(() => {
+        uploadRef.value.clearFiles()
+    })
+    if (res.code == 'ok') {
+        globalPopup?.showSuccess(res.msg || '')
+        emits('refreshData');
+        return
+    }
+    globalPopup?.showError(res.msg || '')
+    return res
+}
+
+// 显示弹窗
+function showVisible(item: any) {
+    renameVal.value = JSON.parse(JSON.stringify(item.name))
+    renameDialogVisible.value = true
+}
+
+watchEffect(() => {
+    information.value = props.data
+    attachmenttable.value = (props.data.files || [])
+});
 
 
-const attachmenttable = ref([{
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}])
 // 生命周期钩子
 // 生命周期钩子
 onMounted(() => {
 onMounted(() => {
 });
 });

Разлика између датотеке није приказан због своје велике величине
+ 188 - 17
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/information.vue


+ 17 - 33
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/operationRecord.vue

@@ -5,45 +5,29 @@
         </div>
         </div>
         <div class="flex-1 overflow-auto pt-5">
         <div class="flex-1 overflow-auto pt-5">
             <el-table :data="operationRecordtable" border style="width: 100%;height: 278px;">
             <el-table :data="operationRecordtable" border style="width: 100%;height: 278px;">
-                <el-table-column prop="operatingTime" label="操作时间" width="140" />
-                <el-table-column prop="operator" label="操作人" width="120" />
-                <el-table-column prop="operationContent" label="操作内容" />
+                <el-table-column prop="creaTime" label="操作时间" width="140" />
+                <el-table-column prop="username" label="操作人" width="120" />
+                <el-table-column prop="name" label="操作内容" />
             </el-table>
             </el-table>
         </div>
         </div>
     </div>
     </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+
+const operationRecordtable = ref([])
+const information = ref({})
+
+const props = defineProps<{
+    data: any
+}>()
+
+watchEffect(() => {
+    const { data } = props
+    information.value = data
+    operationRecordtable.value = data.actionLogs || []
+})
 
 
-const operationRecordtable = ref([{
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-},])
 // 生命周期钩子
 // 生命周期钩子
 onMounted(() => {
 onMounted(() => {
 });
 });

+ 142 - 45
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedBusiness.vue

@@ -3,7 +3,7 @@
         <div class="flex justify-between">
         <div class="flex justify-between">
             <div class="title">相关商机</div>
             <div class="title">相关商机</div>
             <div>
             <div>
-                <el-button type="primary">新建商机</el-button>
+                <el-button type="primary" @click="editNewBusiness()">新建商机</el-button>
             </div>
             </div>
         </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
         <div class="flex-1 overflow-auto pt-3">
@@ -25,56 +25,153 @@
                 <el-table-column prop="endTime" label="修改时间" width="130" />
                 <el-table-column prop="endTime" label="修改时间" width="130" />
             </el-table>
             </el-table>
         </div>
         </div>
+
+        <el-dialog v-model="allVisible.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">{{ '新建商机' }}</h4>
+                    <div>
+                        <el-button type="primary" @click="editBusiness(false)" :loading="allLoading.businessSaveLading"
+                            :disabled="allLoading.newBusinessSaveLading">保存</el-button>
+                        <el-button @click="closeVisible('newBusinessisible')">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="h-[60vh] overflow-y-auto scroll-bar pt-3" v-loading="allLoading.generateFormLading">
+                <GenerateForm ref="businessTemplateRef" :data="businessTemplate" :value="businessTemplateValue"
+                    :key="businessTemplateKey" />
+                <div>相关产品</div>
+                <RelatedProducts ref="relatedProductsRef" :productTableList="productTableList"
+                    :productTableListValue="productTableListValue" />
+            </div>
+        </el-dialog>
     </div>
     </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { get, post } from '@/utils/request';
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+import { GenerateForm } from '@zmjs/form-design';
+import RelatedProducts from '@/components/relatedProducts/relatedProducts.vue'
+import { GETTABLELIST } from '@/pages/product/api';
+import { GETGENERATEFOEM, UPDATEINSET } from '@/pages/business/api';
+import { setTemplateDataDisable } from '@/utils/tools';
+import { formatDateTime } from '@/utils/times';
+
+const emits = defineEmits(['refreshData']);
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const props = defineProps<{
+    data: any
+}>()
+
+const information = ref<any>({})
+const relatedTaskstable = ref([])
+const relatedProductsRef = ref<typeof RelatedProducts>()
+const businessTemplateRef = ref<typeof GenerateForm>() // 自定义表单dom
+const businessTemplateValue = ref({})
+const businessTemplateKey = ref(1)
+const productTableList = ref([])
+const productTableListValue = ref([])
+const businessTemplate = ref({
+    config: {},
+    list: []
+}) // 自定义表单数据
+const allVisible = reactive({
+    newBusinessisible: false
+})
+const allLoading = reactive({
+    generateFormLading: false,
+    newBusinessSaveLading: false,
+    businessSaveLading: false
+})
+
+function editBusiness(visibles: boolean) {
+    businessTemplateRef.value?.getData().then((res: any) => {
+        let productTableListData = relatedProductsRef?.value?.returnData() || []
+        productTableListData.forEach((item: any) => {
+            delete item.id
+        })
+        let newForm = {
+            ...res,
+            expectedTransactionDate: res.expectedTransactionDate ? formatDateTime(new Date(res.expectedTransactionDate)) : '',
+            businessItemProductList: productTableListData ? JSON.stringify(productTableListData) : []
+        }
+        allLoading.businessSaveLading = true
+        post(UPDATEINSET, { ...businessTemplateValue.value, ...newForm }).then((_res) => {
+            allVisible.newBusinessisible = visibles
+            globalPopup?.showSuccess('保存成功')
+            emits('refreshData')
+        }).finally(() => {
+            allLoading.businessSaveLading = false
+        })
+    }).catch((_err: any) => {
+        console.log(_err)
+        globalPopup?.showError('请填写完整')
+    })
+}
+
+function editNewBusiness() {
+    showVisible('newBusinessisible')
+    allLoading.generateFormLading = true
+    businessTemplateValue.value = { customerId: information.value.id }
+    productTableListValue.value = []
+    setTimeout(() => {
+        businessTemplateRef.value && businessTemplateRef.value.reset()
+        businessTemplateKey.value++
+        allLoading.generateFormLading = false
+    }, 500)
+}
+
+async function getSystemField() {
+    const datas = await get(GETGENERATEFOEM)
+    let newConfig = JSON.parse(datas.data[0].config)
+    newConfig.list = setTemplateDataDisable(newConfig.list, ['customerId'])
+    businessTemplate.value = newConfig
+}
+
+function showVisible(type: keyof typeof allVisible) {
+    allVisible[type] = true
+}
+
+function closeVisible(type: keyof typeof allVisible) {
+    allVisible[type] = false
+}
+
+function getProductTableList() {
+    post(GETTABLELIST, { pageIndex: -1, pageSize: -1 }).then((res) => {
+        if (res.code == 'ok') {
+            const { record, total } = res.data
+            productTableList.value = record.map((item: any) => {
+                const { id, productName, productCode, unit, unitName, typeName, type, price, inventory } = item
+                return {
+                    id,
+                    productId: id,
+                    productName,
+                    productCode,
+                    unit,
+                    unitName,
+                    price,
+                    type,
+                    typeName,
+                    inventory,
+                    quantity: '',
+                    discount: '',
+                    totalPrice: ''
+                }
+            })
+        }
+    })
+}
+
+watchEffect(() => {
+    const { data } = props
+    information.value = data
+    relatedTaskstable.value = []
+})
 
 
-const relatedTaskstable = ref([{
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}])
 // 生命周期钩子
 // 生命周期钩子
 onMounted(() => {
 onMounted(() => {
+    getProductTableList()
+    getSystemField()
 });
 });
 </script>
 </script>
 <style scoped lang="scss">
 <style scoped lang="scss">

+ 104 - 46
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedContacts.vue

@@ -3,11 +3,11 @@
         <div class="flex justify-between">
         <div class="flex justify-between">
             <div class="title">相关联系人</div>
             <div class="title">相关联系人</div>
             <div>
             <div>
-                <el-button type="primary">新建联系人</el-button>
+                <el-button type="primary" @click="editContacts(information)">新建联系人</el-button>
             </div>
             </div>
         </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
         <div class="flex-1 overflow-auto pt-3">
-            <el-table :data="relatedTaskstable" border style="width: 100%;height: 300px;">
+            <el-table :data="relatedCustomertable" border style="width: 100%;height: 300px;">
                 <el-table-column label="序号" width="80">
                 <el-table-column label="序号" width="80">
                     <template #default="scope">
                     <template #default="scope">
                         {{ scope.$index + 1 }}
                         {{ scope.$index + 1 }}
@@ -29,56 +29,114 @@
                 <el-table-column prop="endTime" label="创建时间" width="130" />
                 <el-table-column prop="endTime" label="创建时间" width="130" />
             </el-table>
             </el-table>
         </div>
         </div>
+
+        <!-- 弹窗 -->
+        <el-dialog v-model="allVisible.editContactsVisible" 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">{{ '新建联系人' }}</h4>
+                    <div>
+                        <el-button type="primary" :loading="allLoading.editContactsSaveLoading"
+                            @click="editContactsSave(false)">新建</el-button>
+                        <el-button @click="closeVisible('editContactsVisible')">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="h-[60vh] overflow-y-auto scroll-bar pt-3">
+                <div class="ml-4 mr-4">
+                    <GenerateForm ref="contactsTemplateRef" :data="contactsTemplate" :value="contactsTemplateValue"
+                        :key="contactsTemplateRefKey" v-loading="allLoading.contactsTemplateRefLoading" />
+                </div>
+            </div>
+        </el-dialog>
     </div>
     </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { GETGENERATEFOEM, URL_ADD } from '@/pages/contacts/api';
+import { get, post } from '@/utils/request';
+import { setTemplateDataDisable } from '@/utils/tools';
+import { GenerateForm } from '@zmjs/form-design';
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+
+const emits = defineEmits(['refreshData']);
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const props = defineProps<{
+    data: any
+}>()
+
+const information = ref({})
+const relatedCustomertable = ref([])
+const contactsTemplateValue = ref({})
+const contactsTemplateRefKey = ref(1)
+const contactsTemplateRef = ref<typeof GenerateForm>()
+const contactsTemplate = ref({
+    list: [],
+    config: {}
+})
+
+function editContactsSave(flag: boolean) {
+    contactsTemplateRef.value?.getData().then((res: any) => {
+        allLoading.editContactsSaveLoading = true
+        post(URL_ADD, { ...contactsTemplateValue.value, ...res }).then((_res) => {
+            allVisible.editContactsVisible = flag
+            globalPopup?.showSuccess('操作成功')
+            if (flag) {
+                contactsTemplateRef.value?.reset()
+            }
+            emits('refreshData')
+        }).finally(() => {
+            allLoading.editContactsSaveLoading = false
+        })
+    }).catch((_err: any) => {
+        console.log(_err)
+        globalPopup?.showError('请填写完整')
+    })
+}
+
+function editContacts(data: any) {
+    showVisible('editContactsVisible')
+    const { id, telPhone } = data
+    contactsTemplateValue.value = { customId: id, phone: telPhone }
+    allLoading.contactsTemplateRefLoading = true
+    setTimeout(() => {
+        contactsTemplateRefKey.value++
+        allLoading.contactsTemplateRefLoading = false
+    }, 1000);
+}
+
+const allLoading = reactive({
+    contactsTemplateRefLoading: false,
+    editContactsSaveLoading: false
+})
+
+const allVisible = reactive({
+    editContactsVisible: false,
+})
+
+watchEffect(() => {
+    const { data } = props
+    information.value = data
+    relatedCustomertable.value = []
+})
+
+async function getSystemField() {
+    const datas = await get(GETGENERATEFOEM)
+    let newConfig = JSON.parse(datas.data[0].config)
+    newConfig.list = setTemplateDataDisable(newConfig.list, ['customId'])
+    contactsTemplate.value = newConfig
+}
+
+function showVisible(type: keyof typeof allVisible) {
+    allVisible[type] = true
+}
+
+function closeVisible(type: keyof typeof allVisible) {
+    allVisible[type] = false
+}
 
 
-const relatedTaskstable = ref([{
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}])
 // 生命周期钩子
 // 生命周期钩子
 onMounted(() => {
 onMounted(() => {
+    getSystemField()
 });
 });
 </script>
 </script>
 <style scoped lang="scss">
 <style scoped lang="scss">

+ 152 - 46
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedOrders.vue

@@ -3,11 +3,11 @@
         <div class="flex justify-between">
         <div class="flex justify-between">
             <div class="title">相关销售订单</div>
             <div class="title">相关销售订单</div>
             <div>
             <div>
-                <el-button type="primary">新建销售订单</el-button>
+                <el-button type="primary" @click="editOrder()">新建销售订单</el-button>
             </div>
             </div>
         </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
         <div class="flex-1 overflow-auto pt-3">
-            <el-table :data="relatedTaskstable" border style="width: 100%;height: 300px;">
+            <el-table :data="relatedOrders" border style="width: 100%;height: 300px;">
                 <el-table-column prop="priority" label="订单编号" width="130" />
                 <el-table-column prop="priority" label="订单编号" width="130" />
                 <el-table-column prop="taskName" label="订单名称">
                 <el-table-column prop="taskName" label="订单名称">
                     <template #default="scope">
                     <template #default="scope">
@@ -27,56 +27,162 @@
                 <el-table-column prop="endTime" label="创建时间" width="130" />
                 <el-table-column prop="endTime" label="创建时间" width="130" />
             </el-table>
             </el-table>
         </div>
         </div>
+
+        <!-- 弹窗 -->
+        <el-dialog v-model="allVisible.editOrderVisible" 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">{{ '新建销售订单' }}</h4>
+                    <div>
+                        <el-button type="primary" :loading="allLoading.editSaveLading"
+                            @click="saveOrder(false)">保存</el-button>
+                        <el-button @click="closeVisible('editOrderVisible')">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="h-[60vh] overflow-y-auto scroll-bar pt-3" v-loading="allLoading.orderTemplateLoadinng">
+                <GenerateForm ref="orderTemplateRef" :data="orderTemplate" :key="orderTemplateKey"
+                    :value="orderTemplateValue" />
+                <div>相关产品</div>
+                <RelatedProducts ref="relatedProductsRef" :productTableList="productTableList"
+                    :productTableListValue="productTableListValue" />
+            </div>
+        </el-dialog>
     </div>
     </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+import { setTemplateDataDisable } from '@/utils/tools';
+import { GenerateForm } from '@zmjs/form-design';
+import { get, post } from '@/utils/request';
+
+import RelatedProducts from '@/components/relatedProducts/relatedProducts.vue'
+import { GETGENERATEFOEM, GETTABLELIST, URL_OEDERUPDATE } from '@/pages/order/api';
+import { formatDate } from '@/utils/times';
+
+const emits = defineEmits(['refreshData']);
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const props = defineProps<{
+    data: any
+}>()
+
+const information = ref<any>({})
+const relatedOrders = ref([])
+const productTableList = ref([])
+const productTableListValue = ref([])
+const orderTemplateValue = ref({})
+const orderTemplateKey = ref(1)
+const orderTemplateRef = ref<typeof GenerateForm>()
+const relatedProductsRef = ref<typeof RelatedProducts>()
+const orderTemplate = ref({
+    list: [],
+    config: {}
+})
+const allVisible = reactive({
+    editOrderVisible: false,
+})
+const allLoading = reactive({
+    editSaveLading: false,
+    orderTemplateLoadinng: false,
+})
+
+
+
+function saveOrder(flag: boolean) {
+    orderTemplateRef.value?.getData().then((res: any) => {
+        let productTableListData = relatedProductsRef?.value?.returnData()
+        for (var i in productTableListData) {
+            productTableListData[i].sealPrice = productTableListData[i].sellingPrice,
+                productTableListData[i].discount = productTableListData[i].discount,
+                productTableListData[i].num = productTableListData[i].quantity
+        }
+        const produt = productTableListData ? JSON.stringify(productTableListData) : []
+        allLoading.editSaveLading = true
+        post(URL_OEDERUPDATE, {
+            ...orderTemplateValue.value,
+            ...res,
+            orderEndDate: res.orderEndDate ? formatDate(res.orderEndDate) : '',
+            orderStartDate: res.orderStartDate ? formatDate(res.orderStartDate) : '',
+            orderProductDetailString: produt
+        }).then((_res) => {
+            allVisible.editOrderVisible = flag
+            globalPopup?.showSuccess('操作成功')
+            if (flag) {
+                orderTemplateRef.value?.reset()
+            }
+            emits('refreshData')
+        }).finally(() => {
+            allLoading.editSaveLading = false
+        })
+    }).catch((_err: any) => {
+        globalPopup?.showError('请填写完整')
+    })
+}
+
+function editOrder() {
+    showVisible('editOrderVisible')
+    allLoading.orderTemplateLoadinng = true
+    
+    orderTemplateValue.value = { customId: information.value.id }
+    productTableListValue.value = []
+    setTimeout(() => {
+        orderTemplateRef.value && orderTemplateRef.value.reset()
+        orderTemplateKey.value++
+        allLoading.orderTemplateLoadinng = false
+    }, 1000)
+}
+
+async function getSystemField() {
+    const datas = await get(GETGENERATEFOEM)
+    let newConfig = JSON.parse(datas.data[0].config)
+    newConfig.list = setTemplateDataDisable(newConfig.list, ['customId'])
+    orderTemplate.value = newConfig
+}
+
+function showVisible(type: keyof typeof allVisible) {
+    allVisible[type] = true
+}
+
+function closeVisible(type: keyof typeof allVisible) {
+    allVisible[type] = false
+}
+
+function getProductTableList() {
+    post(GETTABLELIST, { pageIndex: -1, pageSize: -1 }).then((res) => {
+        if (res.code == 'ok') {
+            const { record, total } = res.data
+            productTableList.value = record.map((item: any) => {
+                const { id, productName, productCode, unit, unitName, typeName, type, price, inventory } = item
+                return {
+                    id,
+                    productId: id,
+                    productName,
+                    productCode,
+                    unit,
+                    unitName,
+                    price,
+                    type,
+                    typeName,
+                    inventory,
+                    quantity: '',
+                    discount: '',
+                    totalPrice: ''
+                }
+            })
+        }
+    })
+}
+
+watchEffect(() => {
+    const { data } = props
+    information.value = data
+    relatedOrders.value = []
+})
 
 
-const relatedTaskstable = ref([{
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}])
 // 生命周期钩子
 // 生命周期钩子
 onMounted(() => {
 onMounted(() => {
+    getProductTableList()
+    getSystemField()
 });
 });
 </script>
 </script>
 <style scoped lang="scss">
 <style scoped lang="scss">

+ 21 - 14
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/detail/index.vue

@@ -13,40 +13,43 @@
       </div>
       </div>
     </div>
     </div>
     <!-- 内容 -->
     <!-- 内容 -->
-    <div class="flex-1 flex flex-col overflow-y-auto overflow-x-hidden scroll-bar" v-loading="allLoading.customerDetailLoading">
+    <div class="flex-1 flex flex-col overflow-y-auto overflow-x-hidden scroll-bar"
+      v-loading="allLoading.customerDetailLoading">
       <div class="w-full h-auto flex justify-between">
       <div class="w-full h-auto flex justify-between">
         <div class="bg-white shadow-md rounded-md" style="width: 46%;">
         <div class="bg-white shadow-md rounded-md" style="width: 46%;">
-          <Information />
+          <Information :data="information" @refreshData="getDetail" />
         </div>
         </div>
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
-          <Attachment />
+          <Attachment :data="information" @refreshData="getDetail" />
         </div>
         </div>
       </div>
       </div>
 
 
       <div class="w-full h-auto flex justify-between mt-2">
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md" style="width: 65%;">
         <div class="bg-white shadow-md rounded-md" style="width: 65%;">
-          <RelatedTasks />
+          <DetailCompinents :data="detailCompinentsData" :information="information" :formTaskType="0"
+            :filed="'customId'" :disabledList="['taskType', 'customId']"
+            @refreshData="getDetail" />
         </div>
         </div>
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
-          <OperationRecord />
+          <OperationRecord :data="information" />
         </div>
         </div>
       </div>
       </div>
 
 
       <div class="w-full h-auto flex justify-between mt-2">
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md w-full">
         <div class="bg-white shadow-md rounded-md w-full">
-          <RelatedContacts />
+          <RelatedContacts :data="information" @refreshData="getDetail" />
         </div>
         </div>
       </div>
       </div>
 
 
       <div class="w-full h-auto flex justify-between mt-2">
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md w-full">
         <div class="bg-white shadow-md rounded-md w-full">
-          <RelatedBusiness />
+          <RelatedBusiness :data="information" @refreshData="getDetail" />
         </div>
         </div>
       </div>
       </div>
 
 
       <div class="w-full h-auto flex justify-between mt-2">
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md w-full">
         <div class="bg-white shadow-md rounded-md w-full">
-          <RelatedOrders />
+          <RelatedOrders :data="information" @refreshData="getDetail" />
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
@@ -69,7 +72,8 @@ import OperationRecord from '../component/operationRecord.vue';
 import RelatedBusiness from '../component/relatedBusiness.vue';
 import RelatedBusiness from '../component/relatedBusiness.vue';
 import RelatedContacts from "../component/relatedContacts.vue";
 import RelatedContacts from "../component/relatedContacts.vue";
 import RelatedOrders from "../component/relatedOrders.vue"
 import RelatedOrders from "../component/relatedOrders.vue"
-import { number } from "echarts";
+import DetailCompinents from '@/components/detailcompinents/relatedTasks.vue'
+import { formatDate } from "@/utils/times";
 
 
 const route = useRoute()
 const route = useRoute()
 const globalPopup = inject<GlobalPopup>('globalPopup')
 const globalPopup = inject<GlobalPopup>('globalPopup')
@@ -77,6 +81,7 @@ const rowId = ref(+(route.query.id || ''))
 const values = ref<any>('')
 const values = ref<any>('')
 const options = ref<optionType[]>([])
 const options = ref<optionType[]>([])
 const information = ref<any>({})
 const information = ref<any>({})
+const detailCompinentsData = ref([])
 const allLoading = reactive({
 const allLoading = reactive({
   customerDetailLoading: false
   customerDetailLoading: false
 })
 })
@@ -84,7 +89,9 @@ const allLoading = reactive({
 function getDetail() {
 function getDetail() {
   allLoading.customerDetailLoading = true
   allLoading.customerDetailLoading = true
   post(URL_GETDETAIL, { id: values.value }).then((res) => {
   post(URL_GETDETAIL, { id: values.value }).then((res) => {
-    information.value = res.data
+    res.data.newCreateTime = formatDate(new Date(res.data.createTime)),
+      information.value = res.data
+      detailCompinentsData.value = res.data.taskList || []
   }).finally(() => {
   }).finally(() => {
     allLoading.customerDetailLoading = false
     allLoading.customerDetailLoading = false
   })
   })
@@ -92,10 +99,10 @@ function getDetail() {
 
 
 function getAllCustomer() {
 function getAllCustomer() {
   get(URL_FETALL).then(({ data }) => {
   get(URL_FETALL).then(({ data }) => {
-      options.value = data.map((item: any) => ({
-          value: item.id,
-          label: item.customName
-      }))
+    options.value = data.map((item: any) => ({
+      value: item.id,
+      label: item.customName
+    }))
   })
   })
 }
 }
 
 

+ 3 - 3
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue

@@ -174,7 +174,7 @@
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
 import { ref, reactive, onMounted, inject } from "vue";
 import { ref, reactive, onMounted, inject } from "vue";
-import { MOD, GETSYSFILED, GETPERSONNEL, URL_TABLELIST, URL_TEMPLALE, URL_EDITSAVE, URL_DETELER, URL_CLAIM, IMPORTMOD, GETALLCLUE } from './api.ts'
+import { MOD, GETSYSFILED, GETPERSONNEL, URL_TABLELIST, URL_TEMPLALE, URL_EDITSAVE, URL_DETELER, URL_CLAIM, IMPORTMOD, GETALLCLUE, URL_IMPORTEXELS, URL_EXPORTEXELS } from './api.ts'
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, getTemplateKey, createTaskFromType, confirmAction, downloadFile, downloadTemplate } from '@/utils/tools'
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, getTemplateKey, createTaskFromType, confirmAction, downloadFile, downloadTemplate } from '@/utils/tools'
 import { post, get, uploadFile } from "@/utils/request";
 import { post, get, uploadFile } from "@/utils/request";
 import { useRouter, useRoute } from "vue-router";
 import { useRouter, useRoute } from "vue-router";
@@ -280,7 +280,7 @@ async function importBusiness(param: UploadRequestOptions) {
   allLoading.importLoading = true
   allLoading.importLoading = true
   const formData = new FormData();
   const formData = new FormData();
   formData.append('multipartFile', param.file)
   formData.append('multipartFile', param.file)
-  const res = await uploadFile('接口名称', formData).finally(() => {
+  const res = await uploadFile(URL_IMPORTEXELS, formData).finally(() => {
     allLoading.importLoading = false
     allLoading.importLoading = false
   })
   })
   if (res.code == 'ok') {
   if (res.code == 'ok') {
@@ -294,7 +294,7 @@ async function importBusiness(param: UploadRequestOptions) {
 function exportCustomerTableList() {
 function exportCustomerTableList() {
   allLoading.exoprtLoading = true
   allLoading.exoprtLoading = true
   let valueForm = getFromValue(customerCriteriaForm)
   let valueForm = getFromValue(customerCriteriaForm)
-  post('接口名称', { ...valueForm }).then((res) => {
+  post(URL_EXPORTEXELS, { ...valueForm }).then((res) => {
     downloadFile(res.data, allText.exportText)
     downloadFile(res.data, allText.exportText)
   }).finally(() => {
   }).finally(() => {
     allLoading.exoprtLoading = false
     allLoading.exoprtLoading = false

+ 17 - 13
fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/customInstructions.ts

@@ -3,22 +3,26 @@ import { Directive, ObjectDirective } from 'vue';
 // 权限控制
 // 权限控制
 const PermissionDirective: Directive = {
 const PermissionDirective: Directive = {
     mounted(el: HTMLElement, binding: { value: string[] }, vnode: any) {
     mounted(el: HTMLElement, binding: { value: string[] }, vnode: any) {
-        const routePath = vnode.ctx.appContext.config.globalProperties.$route.path;
-        console.log(extractPath(routePath))
-        // const currentRoute = getCurrentInstance()?.appContext.config.globalProperties.$route;
-        // console.log('Current Route:', currentRoute);
-
-        // const permissions = binding.value;
-        // if (!Array.isArray(permissions)) {
-        //     console.error('Permissions must be provided as an array.');
-        //     return;
-        // }
-        // if (!permissions.some((permission: string) => permission === 'admin')) {
-        //     el.parentNode && el.parentNode.removeChild(el)
-        // }
+        const routePath: string = vnode.ctx.appContext.config.globalProperties.$route.path;
+        const userInfo: { userInfo: { functionList: { code: string }[] } } | null = JSON.parse(localStorage.getItem('storeInfo') || '');
+        const authorityCodes: string[] = (userInfo?.userInfo?.functionList || []).map(({ code }) => code);
+        const permissions: string[] = binding.value;
+
+        if (!Array.isArray(permissions)) {
+            console.error('权限必须以数组形式提供');
+            return;
+        }
+
+        if (!permissions.every(permission => authorityCodes.includes(permission))) {
+            el.parentNode && el.parentNode.removeChild(el);
+        }
+
+        console.log(extractPath(routePath), authorityCodes);
+        console.log(permissions, !permissions.every(permission => authorityCodes.includes(permission)))
     }
     }
 };
 };
 
 
+// input 字符串数字
 const PositiveIntegerDirective: ObjectDirective = {
 const PositiveIntegerDirective: ObjectDirective = {
     mounted(el: HTMLElement) {
     mounted(el: HTMLElement) {
         el.addEventListener('input', handleInput);
         el.addEventListener('input', handleInput);

+ 26 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/tools.ts

@@ -237,3 +237,29 @@ export function getTemplateKey(list: Array<any>) {
   });
   });
   return models;
   return models;
 }
 }
+
+/**
+ * 设置模板数据禁用
+ * @param list 模板数据
+ * @param fieldList 需要禁用的字段
+ * @returns 
+ */
+export function setTemplateDataDisable(list: Array<any>, fieldList: Array<any>) {
+  let result = list;
+  result.forEach((item: any) => {
+    if (item.type === 'grid') {
+      item.columns.forEach((column: any) => {
+        column.list.forEach((subItem: any) => {
+          if (fieldList.includes(subItem.model)) {
+            subItem.options.disabled = true
+          }
+        });
+      });
+    } else {
+      if (fieldList.includes(item.model)) {
+        item.options.disabled = true;
+      }
+    }
+  })
+  return result;
+} 

+ 26 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ContactsController.java

@@ -208,5 +208,31 @@ public class ContactsController {
             return msg;
             return msg;
         }
         }
     }
     }
+
+
+    //认领联系人 conctacts 里面要有要转移的负责人的 owner_id,id
+    @RequestMapping("claimContacts")
+    public HttpRespMsg claimContacts(Contacts contacts,HttpServletRequest request){
+        User user = userMapper.selectById(request.getHeader("Token"));//当前登陆的用户
+        HttpRespMsg msg = new HttpRespMsg();
+        if (contacts.getOwnerId()==null|| StringUtils.isEmpty(contacts.getOwnerId())){
+            msg.setError("请选择要认领的负责人");
+            return msg;
+        }
+        Contacts contactsGet=contactsService.getById(contacts.getId());
+        if (contactsGet.getOwnerId()!=null){
+            msg.setError("该联系人已有负责人");
+            return msg;
+        }
+        contactsGet.setOwnerId(contacts.getOwnerId());
+        int count= contactsService.claimContacts(contactsGet, user);
+        if (count>0){
+            msg.setMsg("操作成功");
+            return msg;
+        }else {
+            msg.setError("操作失败");
+            return msg;
+        }
+    }
 }
 }
 
 

+ 104 - 4
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/CustomController.java

@@ -1,15 +1,20 @@
 package com.management.platform.controller;
 package com.management.platform.controller;
 
 
 
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.management.platform.entity.Clue;
-import com.management.platform.entity.Custom;
-import com.management.platform.entity.UploadFile;
-import com.management.platform.entity.User;
+import com.management.platform.entity.*;
 import com.management.platform.mapper.ClueMapper;
 import com.management.platform.mapper.ClueMapper;
 import com.management.platform.mapper.CustomMapper;
 import com.management.platform.mapper.CustomMapper;
+import com.management.platform.mapper.SysFormMapper;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.ContactsService;
 import com.management.platform.service.CustomService;
 import com.management.platform.service.CustomService;
+import com.management.platform.service.WxCorpInfoService;
+import com.management.platform.service.impl.ExcelExportServiceImpl;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.HttpRespMsg;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
@@ -18,10 +23,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartFile;
 
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponse;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
+import java.util.Map;
 
 
 /**
 /**
  * <p>
  * <p>
@@ -45,16 +52,32 @@ public class CustomController {
     @Autowired
     @Autowired
     private UserMapper userMapper;
     private UserMapper userMapper;
 
 
+    @Resource
+    private ExcelExportServiceImpl excelExportService;
+    @Resource
+    private SysFormMapper sysFormMapper;
+    @Autowired
+    private WxCorpInfoService wxCorpInfoService;
+    @Autowired
+    private ContactsService contactsService;
+
+
     @RequestMapping("list")
     @RequestMapping("list")
     public HttpRespMsg list(Custom custom, HttpServletRequest request) {
     public HttpRespMsg list(Custom custom, HttpServletRequest request) {
         return customService.getList(custom, request);
         return customService.getList(custom, request);
     }
     }
 
 
+
     @RequestMapping("getAllCustom")
     @RequestMapping("getAllCustom")
     public HttpRespMsg getAllCustom(HttpServletRequest request) {
     public HttpRespMsg getAllCustom(HttpServletRequest request) {
         return customService.getAllCustom(request);
         return customService.getAllCustom(request);
     }
     }
 
 
+    @RequestMapping("getAllContacts")
+    public HttpRespMsg getAllContacts(HttpServletRequest request) {
+        return contactsService.getAll(request);
+    }
+
     @RequestMapping("deleteList")
     @RequestMapping("deleteList")
     public HttpRespMsg deleteList(Custom custom, HttpServletRequest request) {
     public HttpRespMsg deleteList(Custom custom, HttpServletRequest request) {
         return customService.getDeleteList(custom, request);
         return customService.getDeleteList(custom, request);
@@ -76,6 +99,83 @@ public class CustomController {
         return customService.getInfo(custom, request);
         return customService.getInfo(custom, request);
     }
     }
 
 
+    @RequestMapping("/importData")
+    public HttpRespMsg importData(MultipartFile multipartFile){
+        return customService.importData(multipartFile);
+    }
+
+    @Value(value = "${upload.path}")
+    private String path;
+    @RequestMapping("/exportData")
+    public HttpRespMsg exportData(Custom custom , HttpServletRequest request) throws Exception {
+        User user = userMapper.selectById(request.getHeader("token"));
+        SysForm sysForm = sysFormMapper.selectOne(new LambdaQueryWrapper<SysForm>().eq(SysForm::getCompanyId, user.getCompanyId()).eq(SysForm::getCode, "Thread").eq(SysForm::getIsCurrent, 1));
+        WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, user.getCompanyId()));
+        String config = sysForm.getConfig();
+        JSONObject configOb = JSON.parseObject(config);
+        JSONArray configObJSONArray = configOb.getJSONArray("list");
+        List<List<String>> dataList=new ArrayList<>();
+        List<String> titleList=new ArrayList<>();
+        for (int i = 0; i < configObJSONArray.size(); i++) {
+            JSONObject item = configObJSONArray.getJSONObject(i);
+            titleList.add(item.getString("label"));
+        }
+        dataList.add(titleList);
+        HttpRespMsg msg = list(custom, request);
+        Map<String, Object> msgData = (Map<String, Object>) msg.getData();
+        List<BusinessOpportunity> bos = (List<BusinessOpportunity>) msgData.get("record");
+        for (BusinessOpportunity bo1 : bos) {
+            List<String> item=new ArrayList<>();
+            for (int i = 0; i < configObJSONArray.size(); i++) {
+                JSONObject target = configObJSONArray.getJSONObject(i);
+                if(target.getString("type").equals("grid")){
+                    JSONArray columns = target.getJSONArray("columns");
+                    for (int i1 = 0; i1 < columns.size(); i1++) {
+                        JSONObject columnsJSONObject = columns.getJSONObject(i1);
+                        JSONArray list = columnsJSONObject.getJSONArray("list");
+                        for (int i2 = 0; i2 < list.size(); i2++) {
+                            JSONObject object = list.getJSONObject(i2);
+                            String model = object.getString("model");
+                            String targetName = model.substring(0, 1).toUpperCase() + model.substring(1);
+                            Class<? extends BusinessOpportunity> aClass = bo1.getClass();
+                            String value = String.valueOf(aClass.getMethod("get" + targetName).invoke(bo1)==null?"":aClass.getMethod("get" + targetName).invoke(bo1));
+                            if(model.equals("inchargerId")){
+                                if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                                    value = "$userName"+String.valueOf(aClass.getMethod("getInchargerName").invoke(bo1))+"$";
+                                }else {
+                                    value = String.valueOf(aClass.getMethod("getInchargerName").invoke(bo1));
+                                }
+                            }
+                            item.add(value);
+                        }
+                    }
+                }else {
+                    String model = target.getString("model");
+                    String targetName = model.substring(0, 1).toUpperCase() + model.substring(1);
+                    Class<? extends BusinessOpportunity> aClass = bo1.getClass();
+                    String value = String.valueOf(aClass.getMethod("get" + targetName).invoke(bo1)==null?"":aClass.getMethod("get" + targetName).invoke(bo1));
+                    if(model.equals("inchargerId")){
+                        if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                            value = "$userName"+String.valueOf(aClass.getMethod("getInchargerName").invoke(bo1))+"$";
+                        }else {
+                            value = String.valueOf(aClass.getMethod("getInchargerName").invoke(bo1));
+                        }
+                    }
+                    if(model.equals("contactsId")){
+                        if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                            value = "$userName"+String.valueOf(aClass.getMethod("getContactsName").invoke(bo1))+"$";
+                        }else {
+                            value = String.valueOf(aClass.getMethod("getContactsName").invoke(bo1));
+                        }
+                    }
+                    item.add(value);
+                }
+            }
+            dataList.add(item);
+        }
+        String fileName="商机表导出_"+ System.currentTimeMillis();
+        return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,fileName,dataList,path);
+    }
 
 
     // 批量放入回收站
     // 批量放入回收站
     @RequestMapping("deleter")
     @RequestMapping("deleter")

+ 14 - 4
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ReportController.java

@@ -226,13 +226,23 @@ public class ReportController {
      * @return
      * @return
      */
      */
     @RequestMapping("/getCustomerTotalCount")
     @RequestMapping("/getCustomerTotalCount")
-    public HttpRespMsg getCustomerTotalCount(String startDate, String endDate, String userId) {
-        return  customService.getCustomerTotalCount(startDate, endDate, userId, request);
+    public HttpRespMsg getCustomerTotalCount(String startDate, String endDate, String userId,Integer departmentId,Integer exportType) {
+        return  customService.getCustomerTotalCount(startDate, endDate, userId,departmentId,exportType, request);
     }
     }
+    @RequestMapping("/exportCustomerTotalCount")
+    public HttpRespMsg exportCustomerTotalCount(String startDate, String endDate,String userId,Integer departmentId,Integer exportType) throws Exception {
+        return reportService.exportCustomerTotalCount(startDate, endDate,userId, departmentId,exportType, request);
+    }
+
 
 
     @RequestMapping("/getCustomerTransferRate")
     @RequestMapping("/getCustomerTransferRate")
-    public HttpRespMsg getCustomerTransferRate(String startDate, String endDate, String userId) {
-        return  customService.getCustomerTransferRate(startDate, endDate, userId, request);
+    public HttpRespMsg getCustomerTransferRate(String startDate, String endDate, String userId,Integer departmentId,Integer exportType) {
+        return  customService.getCustomerTransferRate(startDate, endDate, userId,departmentId,exportType, request);
+    }
+
+    @RequestMapping("/exportCustomerTransferRate")
+    public HttpRespMsg exportCustomerTransferRate(String startDate, String endDate,String userId,Integer departmentId,Integer exportType) throws Exception {
+        return reportService.exportCustomerTransferRate(startDate, endDate,userId, departmentId,exportType, request);
     }
     }
 
 
     @RequestMapping("/getReportList")
     @RequestMapping("/getReportList")

+ 3 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/ContactsLog.java

@@ -63,6 +63,9 @@ public class ContactsLog extends Model<ContactsLog> {
     @TableField("company_id")
     @TableField("company_id")
     private Integer companyId;
     private Integer companyId;
 
 
+    @TableField(exist = false)
+    private String operateName;
+
 
 
     @Override
     @Override
     protected Serializable pkVal() {
     protected Serializable pkVal() {

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

@@ -110,6 +110,8 @@ public class Custom extends Model<Custom> {
      */
      */
     @TableField("tel_phone")
     @TableField("tel_phone")
     private String telPhone;
     private String telPhone;
+    @TableField("contacts_name")
+    private String contactsName;
 
 
     /**
     /**
      * 传真
      * 传真
@@ -124,6 +126,10 @@ public class Custom extends Model<Custom> {
     private String countryBilling;
     private String countryBilling;
     @TableField(exist = false)
     @TableField(exist = false)
     private String userId;
     private String userId;
+    @TableField(exist = false)
+    private List<Contacts> contacts;
+    @TableField(exist = false)
+    private List<SalesOrder> salesOrders;
 
 
     /**
     /**
      * 开单地址-省/市
      * 开单地址-省/市

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

@@ -45,4 +45,8 @@ public interface ContactsService extends IService<Contacts> {
     HttpRespMsg getAllContacts(Integer customerId, HttpServletRequest request);
     HttpRespMsg getAllContacts(Integer customerId, HttpServletRequest request);
 
 
     int transferContacts(Contacts contactsGet, User user);
     int transferContacts(Contacts contactsGet, User user);
+
+    int claimContacts(Contacts contactsGet, User user);
+
+    HttpRespMsg getAll(HttpServletRequest request);
 }
 }

+ 5 - 2
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/CustomService.java

@@ -55,7 +55,10 @@ public interface CustomService extends IService<Custom> {
 
 
     void deleterDelete(List<Integer> ids);
     void deleterDelete(List<Integer> ids);
 
 
-    HttpRespMsg getCustomerTotalCount(String startDate, String endDate, String userId, HttpServletRequest request);
+    HttpRespMsg getCustomerTotalCount(String startDate, String endDate, String userId, Integer departmentId, Integer exportType, HttpServletRequest request);
+
+    HttpRespMsg getCustomerTransferRate(String startDate, String endDate, String userId, Integer departmentId, Integer exportType, HttpServletRequest request);
+
+    HttpRespMsg importData(MultipartFile multipartFile);
 
 
-    HttpRespMsg getCustomerTransferRate(String startDate, String endDate, String userId, HttpServletRequest request);
 }
 }

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

@@ -149,4 +149,8 @@ public interface ReportService extends IService<Report> {
     HttpRespMsg getHasPushForSap(String startDate, String endDate, String employeeID);
     HttpRespMsg getHasPushForSap(String startDate, String endDate, String employeeID);
 
 
     HttpRespMsg getCustomDataWithDate(String startDate, String endDate, HttpServletRequest request);
     HttpRespMsg getCustomDataWithDate(String startDate, String endDate, HttpServletRequest request);
+
+    HttpRespMsg exportCustomerTotalCount(String startDate, String endDate, String userId, Integer departmentId, Integer exportType, HttpServletRequest request) throws Exception;
+
+    HttpRespMsg exportCustomerTransferRate(String startDate, String endDate, String userId, Integer departmentId, Integer exportType, HttpServletRequest request) throws Exception;
 }
 }

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

@@ -66,12 +66,13 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
     private BusinessItemProductMapper bipMapper;
     private BusinessItemProductMapper bipMapper;
     @Resource
     @Resource
     private UserMapper userMapper;
     private UserMapper userMapper;
+    @Autowired
+    private UploadFileMapper uploadFileMapper;
     @Resource
     @Resource
     private BusinessItemProductMapper biMapper;
     private BusinessItemProductMapper biMapper;
     @Autowired
     @Autowired
     private SysFormMapper sysFormMapper;
     private SysFormMapper sysFormMapper;
-    @Autowired
-    private UploadFileMapper uploadFileMapper;
+
     @Resource
     @Resource
     private HttpServletRequest request;
     private HttpServletRequest request;
 
 

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

@@ -3,6 +3,7 @@ package com.management.platform.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -21,6 +22,10 @@ import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.usermodel.CellType;
 import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -75,6 +80,9 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
     @Resource
     @Resource
     private ExcelExportServiceImpl excelExportService;
     private ExcelExportServiceImpl excelExportService;
 
 
+    @Resource
+    private StageMapper stageMapper;
+
     @Value(value = "${upload.path}")
     @Value(value = "${upload.path}")
     private String path;
     private String path;
 
 
@@ -270,11 +278,24 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
 
 
         ContactsVo contactsVo = new ContactsVo();
         ContactsVo contactsVo = new ContactsVo();
         Contacts contactsSelect = contactsMapper.selectById(contacts.getId());
         Contacts contactsSelect = contactsMapper.selectById(contacts.getId());
+
+        String token = String.valueOf(request.getHeader("Token"));
+        User user = userMapper.selectById(token);
+
+        List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", user.getCompanyId()).eq("is_active", 1));
         if (contactsSelect != null) {
         if (contactsSelect != null) {
             //操作记录
             //操作记录
             LambdaQueryWrapper<ContactsLog> cLoglqw = new LambdaQueryWrapper<>();
             LambdaQueryWrapper<ContactsLog> cLoglqw = new LambdaQueryWrapper<>();
             cLoglqw.eq(ContactsLog::getContactsId, contactsSelect.getId());
             cLoglqw.eq(ContactsLog::getContactsId, contactsSelect.getId());
             List<ContactsLog> contactsLogs = contactsLogMapper.selectList(cLoglqw);
             List<ContactsLog> contactsLogs = contactsLogMapper.selectList(cLoglqw);
+            if (contactsLogs!=null&&!contactsLogs.isEmpty()){
+                for (ContactsLog contactsLog : contactsLogs) {
+                    if (contactsLog.getOperateId()!=null&&StringUtils.isNotEmpty(contactsLog.getOperateId())){
+                        Optional<User> first = userList.stream().filter(u -> u.getId().equals(contactsLog.getOperateId())).findFirst();
+                        first.ifPresent(value -> contactsLog.setOperateName(value.getName()));
+                    }
+                }
+            }
 
 
             //相关任务
             //相关任务
             LambdaQueryWrapper<Task> tLqw = new LambdaQueryWrapper<>();
             LambdaQueryWrapper<Task> tLqw = new LambdaQueryWrapper<>();
@@ -297,6 +318,9 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
             LambdaQueryWrapper<BusinessOpportunity> bLqw = new LambdaQueryWrapper<>();
             LambdaQueryWrapper<BusinessOpportunity> bLqw = new LambdaQueryWrapper<>();
             bLqw.eq(BusinessOpportunity::getContactsId,contactsSelect.getId());
             bLqw.eq(BusinessOpportunity::getContactsId,contactsSelect.getId());
             List<BusinessOpportunity> opportunityList = businessOpportunityMapper.selectList(bLqw);
             List<BusinessOpportunity> opportunityList = businessOpportunityMapper.selectList(bLqw);
+            LambdaQueryWrapper<Stage> stageLQW = new LambdaQueryWrapper<>();
+            List<Stage> stages = stageMapper.selectList(stageLQW);
+
             opportunityList.forEach(businessOpportunity -> {
             opportunityList.forEach(businessOpportunity -> {
                 Custom custom = customMapper.selectById(businessOpportunity.getCustomerId());
                 Custom custom = customMapper.selectById(businessOpportunity.getCustomerId());
                 businessOpportunity.setCustomerName(custom.getCustomName());
                 businessOpportunity.setCustomerName(custom.getCustomName());
@@ -308,6 +332,10 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
                     User creatorUser = userMapper.selectById(businessOpportunity.getCreatorId());
                     User creatorUser = userMapper.selectById(businessOpportunity.getCreatorId());
                     businessOpportunity.setCreatorName(creatorUser.getName());
                     businessOpportunity.setCreatorName(creatorUser.getName());
                 }
                 }
+                if (businessOpportunity.getStageId()!=null){
+                    Optional<Stage> first = stages.stream().filter(s -> s.getId().equals(businessOpportunity.getStageId())).findFirst();
+                    first.ifPresent(stage -> businessOpportunity.setStageValue(stage.getName()));
+                }
             });
             });
 
 
             //附件信息查询
             //附件信息查询
@@ -321,6 +349,22 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
             contactsVo.setTaskList(taskList);
             contactsVo.setTaskList(taskList);
             contactsVo.setBusinessOpportunityList(opportunityList);
             contactsVo.setBusinessOpportunityList(opportunityList);
             contactsVo.setContactsDocumentList(contactsDocuments);
             contactsVo.setContactsDocumentList(contactsDocuments);
+            if (contactsVo.getCustomId()!=null){
+                Custom custom = customMapper.selectById(contactsVo.getCustomId());
+                contactsVo.setCustomName(custom.getCustomName());
+            }
+            if (StringUtils.isNotEmpty(contactsVo.getOwnerId())){
+//                User user = userMapper.selectById(contactsVo.getOwnerId());
+//                contactsVo.setOwnerName(user.getName());
+                Optional<User> first = userList.stream().filter(u -> u.getId().equals(contactsVo.getOwnerId())).findFirst();
+                first.ifPresent(value -> contactsVo.setOwnerName(value.getName()));
+            }
+            if (StringUtils.isNotEmpty(contactsVo.getCreatorId())){
+//                User user = userMapper.selectById(contactsVo.getCreatorId());
+//                contactsVo.setCreatorName(user.getName());
+                Optional<User> first = userList.stream().filter(u -> u.getId().equals(contactsVo.getCreatorId())).findFirst();
+                first.ifPresent(value -> contactsVo.setCreatorName(value.getName()));
+            }
         }
         }
         msg.setData(contactsVo);
         msg.setData(contactsVo);
         return msg;
         return msg;
@@ -334,7 +378,6 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
         User user = userMapper.selectById(request.getHeader("token"));
         User user = userMapper.selectById(request.getHeader("token"));
         Integer companyId = user.getCompanyId();
         Integer companyId = user.getCompanyId();
         WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, companyId));
         WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, companyId));
-        List<Contacts> contactsList = contactsMapper.selectList(new LambdaQueryWrapper<Contacts>().eq(Contacts::getCompanyId, companyId));
         List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
         List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
         InputStream inputStream = null;
         InputStream inputStream = null;
         OutputStream outputStream = null;
         OutputStream outputStream = null;
@@ -351,9 +394,9 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
             outputStream.close();
             outputStream.close();
 
 
             //解析表格
             //解析表格
-            HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(file));
+            XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(file));
             //我们只需要第一个sheet
             //我们只需要第一个sheet
-            HSSFSheet sheet = workbook.getSheetAt(0);
+            XSSFSheet sheet = workbook.getSheetAt(0);
             //由于第一行需要指明列对应的标题
             //由于第一行需要指明列对应的标题
             int rowNum = sheet.getLastRowNum();
             int rowNum = sheet.getLastRowNum();
             //获取当前表单模板 校验规则
             //获取当前表单模板 校验规则
@@ -367,12 +410,43 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
             JSONObject configOb = JSON.parseObject(config);
             JSONObject configOb = JSON.parseObject(config);
             JSONArray configObJSONArray = configOb.getJSONArray("list");
             JSONArray configObJSONArray = configOb.getJSONArray("list");
 
 
+            //可能存在栅格布局的情况需要特殊处理
+            List<String> modelNameList=new ArrayList<>();
+            List<String> typeList=new ArrayList<>();
+            List<String> labelList=new ArrayList<>();
+            List<Boolean> requiredList=new ArrayList<>();
+
+            for (int i = 0; i < configObJSONArray.size(); i++) {
+                JSONObject jsonObject = configObJSONArray.getJSONObject(i);
+                if(jsonObject.getString("type").equals("grid")){
+                    JSONArray columns = jsonObject.getJSONArray("columns");
+                    for (int i1 = 0; i1 < columns.size(); i1++) {
+                        JSONObject columnsJSONObject = columns.getJSONObject(i1);
+                        JSONArray list = columnsJSONObject.getJSONArray("list");
+                        for (int i2 = 0; i2 < list.size(); i2++) {
+                            JSONObject object = list.getJSONObject(i2);
+                            modelNameList.add(object.getString("model"));
+                            typeList.add(object.getString("type"));
+                            labelList.add(object.getString("label"));
+                            Boolean required = object.getJSONObject("options").getJSONObject("rules").getBoolean("required");
+                            requiredList.add(required);
+                        }
+                    }
+                }else {
+                    modelNameList.add(jsonObject.getString("model"));
+                    typeList.add(jsonObject.getString("type"));
+                    labelList.add(jsonObject.getString("label"));
+                    Boolean required = jsonObject.getJSONObject("options").getJSONObject("rules").getBoolean("required");
+                    requiredList.add(required);
+                }
+            }
+
             List<Contacts>  importContactsList=new ArrayList<>();
             List<Contacts>  importContactsList=new ArrayList<>();
             List<String> userNameList=new ArrayList<>();
             List<String> userNameList=new ArrayList<>();
             HttpRespMsg respMsg=new HttpRespMsg();
             HttpRespMsg respMsg=new HttpRespMsg();
 
 
             for (int rowIndex = 1; rowIndex <= rowNum; rowIndex++) {
             for (int rowIndex = 1; rowIndex <= rowNum; rowIndex++) {
-                HSSFRow row = sheet.getRow(rowIndex);
+                XSSFRow row = sheet.getRow(rowIndex);
                 if (row == null) {
                 if (row == null) {
                     continue;
                     continue;
                 }
                 }
@@ -384,19 +458,24 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
                 int cellNum = row.getLastCellNum();
                 int cellNum = row.getLastCellNum();
 
 
                 for (int i = 0; i < cellNum; i++) {
                 for (int i = 0; i < cellNum; i++) {
-                    JSONObject item = configObJSONArray.getJSONObject(i);
-                    String modelName = item.getString("model");
-                    HSSFCell cell = row.getCell(i);
-                    if(cell!=null){
-                        switch (item.getString("type")){
-                            case "time":cell.setCellType(CellType.NUMERIC);
-                                break;
-                            case "int":cell.setCellType(CellType.NUMERIC);
-                                break;
-                            default:cell.setCellType(CellType.STRING);
+                    String modelName = modelNameList.get(i);
+                    XSSFCell cell = row.getCell(i);
+                    if(modelName.equals("inchargerId")){
+                        if(!org.springframework.util.StringUtils.isEmpty(cell.getStringCellValue())){
+                            userNameList.add(cell.getStringCellValue());
                         }
                         }
                     }
                     }
-                    if(modelName.equals("inchargerId")){
+                    if(modelName.equals("ownerId")){
+                        if(!org.springframework.util.StringUtils.isEmpty(cell.getStringCellValue())){
+                            userNameList.add(cell.getStringCellValue());
+                        }
+                    }
+                    if(modelName.equals("customSigner")){
+                        if(!org.springframework.util.StringUtils.isEmpty(cell.getStringCellValue())){
+                            userNameList.add(cell.getStringCellValue());
+                        }
+                    }
+                    if(modelName.equals("companySigner")){
                         if(!org.springframework.util.StringUtils.isEmpty(cell.getStringCellValue())){
                         if(!org.springframework.util.StringUtils.isEmpty(cell.getStringCellValue())){
                             userNameList.add(cell.getStringCellValue());
                             userNameList.add(cell.getStringCellValue());
                         }
                         }
@@ -416,7 +495,7 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
             List<User> targetUserList= (List<User>) respMsg.data;
             List<User> targetUserList= (List<User>) respMsg.data;
 
 
             for (int rowIndex = 1; rowIndex <= rowNum; rowIndex++) {
             for (int rowIndex = 1; rowIndex <= rowNum; rowIndex++) {
-                HSSFRow row = sheet.getRow(rowIndex);
+                XSSFRow row = sheet.getRow(rowIndex);
                 if (row == null) {
                 if (row == null) {
                     continue;
                     continue;
                 }
                 }
@@ -430,18 +509,13 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
                 contacts.setCompanyId(companyId);
                 contacts.setCompanyId(companyId);
                 contacts.setCreatorId(user.getId());
                 contacts.setCreatorId(user.getId());
                 for (int i = 0; i < cellNum; i++) {
                 for (int i = 0; i < cellNum; i++) {
-                    JSONObject item = configObJSONArray.getJSONObject(i);
-                    String modelName = item.getString("model");
+                    String modelName = modelNameList.get(i);
                     String className = modelName.substring(0, 1).toUpperCase() + modelName.substring(1);
                     String className = modelName.substring(0, 1).toUpperCase() + modelName.substring(1);
                     String getter="get"+className;
                     String getter="get"+className;
                     String setter="set"+className;
                     String setter="set"+className;
-                    HSSFCell cell = row.getCell(i);
+                    XSSFCell cell = row.getCell(i);
                     if(cell!=null){
                     if(cell!=null){
-                        switch (item.getString("type")){
-                            case "time":cell.setCellType(CellType.NUMERIC);
-                                break;
-                            case "int":cell.setCellType(CellType.NUMERIC);
-                                break;
+                        switch (typeList.get(i)){
                             default:cell.setCellType(CellType.STRING);
                             default:cell.setCellType(CellType.STRING);
                         }
                         }
                     }
                     }
@@ -450,25 +524,36 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
                     Class<?> type = field.getType();
                     Class<?> type = field.getType();
                     Method method = contactsClass.getMethod(setter, type);
                     Method method = contactsClass.getMethod(setter, type);
                     //校验当前列是否为必填
                     //校验当前列是否为必填
-                    JSONObject options = item.getJSONObject("options");
-                    JSONObject rules = options.getJSONObject("rules");
-                    Boolean required = rules.getBoolean("required");
-                    if(required){
+                    if(requiredList.get(i)){
                         if(StringUtils.isEmpty(cell.getStringCellValue())){
                         if(StringUtils.isEmpty(cell.getStringCellValue())){
-                            msg.setError(item.getString("label")+"值不能为空值");
+                            msg.setError(labelList.get(i)+"值不能为空值");
                             return msg;
                             return msg;
                         }
                         }
                     }
                     }
-                    /*if(modelName.equals("contactsCode")){
-                        if(!org.springframework.util.StringUtils.isEmpty(cell.getStringCellValue())){
-                            //系统中同公司已存在的产品编码 更新
-                            Optional<Contacts> first = contactsList.stream().filter(p ->p.getContactsCode()!=null&& p.getContactsCode().equals(cell.getStringCellValue())).findFirst();
-                            if(first.isPresent()){
-                                contacts.setId(first.get().getId());
+                    if(modelName.equals("customId")){
+                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                            String customerName = cell.getStringCellValue();
+                            List<Custom> customList = customMapper.selectList(new QueryWrapper<Custom>().eq("custom_name", customerName));
+                            if (customList!=null&&!customList.isEmpty()){
+                                Custom custom = customList.get(0);
+                                contacts.setCustomId(custom.getId());
+                            }
+                             else {
+                                msg.setError("负责人["+customerName+"]在系统中不存在");
+                                return msg;
                             }
                             }
                         }
                         }
-                    }*/
-                    if(modelName.equals("inchargerId")){
+                    }else if(modelName.equals("sex")){
+                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                            String stringCellValue = cell.getStringCellValue();
+                            if (stringCellValue.equals("男")){
+                                contacts.setSex(1);
+                            } else if (stringCellValue.equals("女")) {
+                                contacts.setSex(0);
+                            }
+                        }
+                    }
+                    else if(modelName.equals("ownerId")){
                         if(!StringUtils.isEmpty(cell.getStringCellValue())){
                         if(!StringUtils.isEmpty(cell.getStringCellValue())){
                             String userName = cell.getStringCellValue();
                             String userName = cell.getStringCellValue();
                             Optional<User> first;
                             Optional<User> first;
@@ -484,30 +569,12 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
                                 throw new Exception("["+userName+"]在系统中不存在");
                                 throw new Exception("["+userName+"]在系统中不存在");
                             }
                             }
                         }
                         }
-                    }
-                    /*if(cell.getCellType()==CellType.STRING.getCode()&&!StringUtils.isEmpty(cell.getStringCellValue())){
-                        method.invoke(contacts,cell.getStringCellValue());
-                    } else if (cell.getCellType()==CellType.NUMERIC.getCode()) {
-
-
-                    }*/
-                    if (cell != null && cell.getCellTypeEnum() != CellType.BLANK) {
-                        if (cell.getCellTypeEnum() == CellType.STRING && cell.getStringCellValue() != null && !cell.getStringCellValue().isEmpty()) {
-                            // 字符串类型不为空
+                    }else{
+                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                            System.out.println(cell.getStringCellValue());
                             method.invoke(contacts,cell.getStringCellValue());
                             method.invoke(contacts,cell.getStringCellValue());
-                        } else if (cell.getCellTypeEnum() == CellType.NUMERIC) {
-                            // 数值类型不为空
-                            double numericCellValue = cell.getNumericCellValue();
-                            if (type.getSimpleName().equals("Integer")){
-                                int intValue = (int) numericCellValue;
-                                method.invoke(contacts,intValue);
-                            }
-                            else {
-                                method.invoke(contacts, numericCellValue);
-                            }
                         }
                         }
                     }
                     }
-
                 }
                 }
                 importContactsList.add(contacts);
                 importContactsList.add(contacts);
             }
             }
@@ -539,9 +606,26 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
         JSONArray configObJSONArray = configOb.getJSONArray("list");
         JSONArray configObJSONArray = configOb.getJSONArray("list");
         List<List<String>> dataList=new ArrayList<>();
         List<List<String>> dataList=new ArrayList<>();
         List<String> titleList=new ArrayList<>();
         List<String> titleList=new ArrayList<>();
+        List<String> modelList=new ArrayList<>();
         for (int i = 0; i < configObJSONArray.size(); i++) {
         for (int i = 0; i < configObJSONArray.size(); i++) {
             JSONObject item = configObJSONArray.getJSONObject(i);
             JSONObject item = configObJSONArray.getJSONObject(i);
-            titleList.add(item.getString("label"));
+            String type = item.getString("type");
+            if (type.equals("grid")){
+                JSONArray columns = item.getJSONArray("columns");
+                for (int j = 0; j < columns.size(); j++) {
+                    JSONObject columnsJSONObject = columns.getJSONObject(j);
+                    JSONArray listJsonArray = columnsJSONObject.getJSONArray("list");
+                    for (int k = 0; k < listJsonArray.size(); k++) {
+                        JSONObject listJsonArrayJSONObject = listJsonArray.getJSONObject(k);
+                        titleList.add(listJsonArrayJSONObject.getString("label"));
+                        modelList.add(listJsonArrayJSONObject.getString("model"));
+                    }
+                }
+            }
+            else {
+                titleList.add(item.getString("label"));
+                modelList.add(item.getString("model"));
+            }
         }
         }
         dataList.add(titleList);
         dataList.add(titleList);
 
 
@@ -557,26 +641,40 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
 
 
         for (ContactsVo contactsVo : records) {
         for (ContactsVo contactsVo : records) {
             List<String> item=new ArrayList<>();
             List<String> item=new ArrayList<>();
-            for (int i = 0; i < configObJSONArray.size(); i++) {
-                JSONObject target = configObJSONArray.getJSONObject(i);
-                String model = target.getString("model");
-//                String targetName = model.substring(0, 1).toUpperCase() + model.substring(1);
+            for (int i = 0; i < modelList.size(); i++) {
+
+                String model = modelList.get(i);
+                String targetName = model.substring(0, 1).toUpperCase() + model.substring(1);
                 Class<? extends ContactsVo> aClass = contactsVo.getClass();
                 Class<? extends ContactsVo> aClass = contactsVo.getClass();
-                String value="";
-//                String value = String.valueOf(aClass.getMethod("get" + targetName).invoke(contactsVo)==null?"":aClass.getMethod("get" + targetName).invoke(contactsVo));
-                /*if(model.equals("inchargerId")){
+                String value = "";
+
+                if(model.equals("customId")){
                     if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
                     if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
-                        value = "$userName"+String.valueOf(aClass.getMethod("getInchargerName").invoke(product))+"$";
+                        value = "$userName"+String.valueOf(aClass.getMethod("getCustomName").invoke(contactsVo))+"$";
                     }else {
                     }else {
-                        value = String.valueOf(aClass.getMethod("getInchargerName").invoke(product));
+                        value = String.valueOf(aClass.getMethod("getCustomName").invoke(contactsVo)).equals("null") ?"" :String.valueOf(aClass.getMethod("getCustomName").invoke(contactsVo));
                     }
                     }
-                }*/
-                if(model.equals("sex")){
-                    value = String.valueOf(aClass.getMethod("getSex").invoke(contactsVo)).equals("null") ?"":String.valueOf(aClass.getMethod("getSex").invoke(contactsVo));
                 }
                 }
-                if(model.equals("name")){
-                    value = String.valueOf(aClass.getMethod("getName").invoke(contactsVo)).equals("null")?"":String.valueOf(aClass.getMethod("getName").invoke(contactsVo));
+                else if(model.equals("sex")){
+                    value = String.valueOf(aClass.getMethod("getSex").invoke(contactsVo)).equals("null") ?"":String.valueOf(aClass.getMethod("getSex").invoke(contactsVo));
+                    if (StringUtils.isNotEmpty(value)){
+                        if (value.equals("0")){
+                            value="女";
+                        }else {
+                            value="男";
+                        }
+                    }
+
                 }
                 }
+                else if(model.equals("ownerId")){
+                    if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                        value = "$userName"+String.valueOf(aClass.getMethod("getOwnerName").invoke(contactsVo))+"$";
+                    }else {
+                        value = String.valueOf(aClass.getMethod("getOwnerName").invoke(contactsVo)).equals("null") ? "" :String.valueOf(aClass.getMethod("getOwnerName").invoke(contactsVo));
+                    }
+                }else
+                    value= String.valueOf(aClass.getMethod("get" + targetName).invoke(contactsVo)==null?"":aClass.getMethod("get" + targetName).invoke(contactsVo));
+
                 item.add(value);
                 item.add(value);
             }
             }
             dataList.add(item);
             dataList.add(item);
@@ -620,5 +718,34 @@ public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> i
         }
         }
     }
     }
 
 
+    @Override
+    public int claimContacts(Contacts contactsGet, User user) {
+        UpdateWrapper<Contacts> contactsUpdateWrapper = new UpdateWrapper<>();
+        contactsUpdateWrapper.eq("id", contactsGet.getId());
+        contactsUpdateWrapper.set("owner_id", contactsGet.getOwnerId());
+        int count1 = contactsMapper.update(null, contactsUpdateWrapper);
+
+        ContactsLog contactsLog = new ContactsLog();
+        contactsLog.setCompanyId(user.getCompanyId());
+        contactsLog.setContactsId(contactsGet.getId());
+        contactsLog.setOperateId(user.getId());
+        contactsLog.setOperateDate(LocalDateTime.now());
+        contactsLog.setMsg("认领联系人");
+        int count2 = contactsLogMapper.insert(contactsLog);
+        if (count1>0&&count2>0){
+            return 1;
+        }else {
+            return 0;
+        }
+    }
+
+    @Override
+    public HttpRespMsg getAll(HttpServletRequest request) {
+        User user = userMapper.selectById(request.getHeader("Token"));
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg.setData(contactsMapper.selectList(new QueryWrapper<Contacts>().eq("company_id",user.getCompanyId())));
+        return httpRespMsg;
+    }
+
 
 
 }
 }

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

@@ -1,5 +1,9 @@
 package com.management.platform.service.impl;
 package com.management.platform.service.impl;
 
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.management.platform.entity.*;
 import com.management.platform.entity.*;
@@ -8,20 +12,30 @@ import com.management.platform.mapper.*;
 import com.management.platform.service.CustomService;
 import com.management.platform.service.CustomService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.service.SysFunctionService;
 import com.management.platform.service.SysFunctionService;
+import com.management.platform.service.WxCorpInfoService;
+import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.FileUtil;
 import com.management.platform.util.FileUtil;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MessageUtils;
 import com.management.platform.util.MessageUtils;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartFile;
 
 
+import javax.annotation.Resource;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.net.URLEncoder;
 import java.net.URLEncoder;
 import java.util.*;
 import java.util.*;
 
 
@@ -43,12 +57,25 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
     private BusinessItemCustomMapper businessItemCustomMapper;
     private BusinessItemCustomMapper businessItemCustomMapper;
     @Autowired
     @Autowired
     private CustomItemContactsMapper customItemContactsMapper;
     private CustomItemContactsMapper customItemContactsMapper;
+    @Resource
+    private ExcelExportServiceImpl excelExportService;
+    @Resource
+    private SysFormMapper sysFormMapper;
+    @Autowired
+    private WxCorpInfoService wxCorpInfoService;
     @Autowired
     @Autowired
     private ActionLogMapper actionLogMapper;
     private ActionLogMapper actionLogMapper;
 
 
     @Autowired
     @Autowired
     private UploadFileMapper uploadFileMapper;
     private UploadFileMapper uploadFileMapper;
 
 
+
+    @Resource
+    private HttpServletRequest request;
+
+    @Resource
+    private SysDictMapper sysDictMapper;
+
     @Autowired
     @Autowired
     private BusinessOpportunityMapper businessOpportunityMapper;
     private BusinessOpportunityMapper businessOpportunityMapper;
     @Autowired
     @Autowired
@@ -99,6 +126,13 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
 //                msg.setError("电话号码重复了");
 //                msg.setError("电话号码重复了");
                 return msg;
                 return msg;
             }
             }
+
+            if (custom.getCustomName() != null && contactsMapper.selectCount(new QueryWrapper<Contacts>()
+                    .eq("name", custom.getContactsName())
+            ) == 0) {
+                msg.setError("此联系人不存在");
+                return msg;
+            }
             custom.setCreateTime(new Date());
             custom.setCreateTime(new Date());
             custom.setCreatorId(user.getId());
             custom.setCreatorId(user.getId());
             custom.setIsDelete(0);
             custom.setIsDelete(0);
@@ -110,6 +144,13 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
             actionLog.setItemId(custom.getId());
             actionLog.setItemId(custom.getId());
             actionLogMapper.insert(actionLog);
             actionLogMapper.insert(actionLog);
             customMapper.insert(custom);
             customMapper.insert(custom);
+            if (custom.getCustomName() != null && custom.getCustomName()!="" &&custom.getTelPhone() !="" &&custom.getTelPhone()!=null){
+                Contacts contacts = contactsMapper.selectOne(new QueryWrapper<Contacts>().eq("name", custom.getCustomName()).eq("phone", custom.getTelPhone()));
+                if (contacts != null){
+                    contacts.setCustomId(custom.getId());
+                    contactsMapper.update(contacts,new UpdateWrapper<Contacts>().eq("id",contacts.getId()));
+                }
+            }
         }
         }
         msg.setMsg("操作成功");
         msg.setMsg("操作成功");
         return msg;
         return msg;
@@ -170,6 +211,8 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
         customMapper.update(custom, updateWrapper);
         customMapper.update(custom, updateWrapper);
     }
     }
 
 
+    @Autowired
+    private SalesOrderMapper salesOrderMapper;
     @Override
     @Override
     public HttpRespMsg getInfo(Custom custom, HttpServletRequest request) {
     public HttpRespMsg getInfo(Custom custom, HttpServletRequest request) {
         Custom custom1 = customMapper.getInfo(custom.getId());
         Custom custom1 = customMapper.getInfo(custom.getId());
@@ -180,15 +223,19 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
         custom1.setBusinessOpportunitys(businessOpportunityMapper.selectList(new QueryWrapper<BusinessOpportunity>().eq("customer_id",custom1.getId())));
         custom1.setBusinessOpportunitys(businessOpportunityMapper.selectList(new QueryWrapper<BusinessOpportunity>().eq("customer_id",custom1.getId())));
         //操作记录
         //操作记录
         custom1.setActionLogs(actionLogMapper.selectList(new QueryWrapper<ActionLog>().eq("code","custom").eq("item_id",custom1.getId())));
         custom1.setActionLogs(actionLogMapper.selectList(new QueryWrapper<ActionLog>().eq("code","custom").eq("item_id",custom1.getId())));
-        List<CustomItemContacts> contacts = customItemContactsMapper.selectList(new QueryWrapper<CustomItemContacts>().eq("contacts_id", custom1.getId()));
-        List<Integer> ids = new ArrayList<>();
-        for (CustomItemContacts contact : contacts) {
-            ids.add(contact.getCustomId());
-        }
-        if (ids.size() > 0){
-            List<Contacts> cs = contactsMapper.selectListByIds(ids);
-            custom1.setContactsList(cs);
-        }
+//        List<CustomItemContacts> contacts = customItemContactsMapper.selectList(new QueryWrapper<CustomItemContacts>().eq("contacts_id", custom1.getId()));
+//        List<Integer> ids = new ArrayList<>();
+//        for (CustomItemContacts contact : contacts) {
+//            ids.add(contact.getCustomId());
+//        }
+//        if (ids.size() > 0){
+//            List<Contacts> cs = contactsMapper.selectListByIds(ids);
+//            custom1.setContactsList(cs);
+//        }
+        //联系人
+        custom1.setContacts(contactsMapper.selectList((new QueryWrapper<Contacts>().eq("custom_id",custom1.getId()))));
+        //订单
+        custom1.setSalesOrders(salesOrderMapper.selectList((new QueryWrapper<SalesOrder>().eq("custom_id",custom1.getId()))));
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         httpRespMsg.setData(custom1);
         httpRespMsg.setData(custom1);
         return httpRespMsg;
         return httpRespMsg;
@@ -393,7 +440,7 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
     }
     }
 
 
     @Override
     @Override
-    public HttpRespMsg getCustomerTotalCount(String startDate, String endDate, String userId, HttpServletRequest request) {
+    public HttpRespMsg getCustomerTotalCount(String startDate, String endDate, String userId, Integer departmentId, Integer exportType, HttpServletRequest request) {
         User user = userMapper.selectById(request.getHeader("token"));
         User user = userMapper.selectById(request.getHeader("token"));
         Integer companyId = user.getCompanyId();
         Integer companyId = user.getCompanyId();
         List<UserVO> userVoList=userMapper.getCustomerTotalCount(startDate,endDate,userId,companyId);
         List<UserVO> userVoList=userMapper.getCustomerTotalCount(startDate,endDate,userId,companyId);
@@ -412,7 +459,7 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
     }
     }
 
 
     @Override
     @Override
-    public HttpRespMsg getCustomerTransferRate(String startDate, String endDate, String userId, HttpServletRequest request) {
+    public HttpRespMsg getCustomerTransferRate(String startDate, String endDate, String userId, Integer departmentId, Integer exportType, HttpServletRequest request) {
         User user = userMapper.selectById(request.getHeader("token"));
         User user = userMapper.selectById(request.getHeader("token"));
         Integer companyId = user.getCompanyId();
         Integer companyId = user.getCompanyId();
         List<UserVO> userVoList=userMapper.getCustomerTransferRate(startDate,endDate,userId,companyId);
         List<UserVO> userVoList=userMapper.getCustomerTransferRate(startDate,endDate,userId,companyId);
@@ -432,6 +479,168 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
 
 
     }
     }
 
 
+    @Override
+    public HttpRespMsg importData(MultipartFile multipartFile) {
+        HttpRespMsg msg=new HttpRespMsg();
+        String fileName = multipartFile.getOriginalFilename();
+        File file = new File(fileName == null ? "file" : fileName);
+        User user = userMapper.selectById(request.getHeader("token"));
+        Integer companyId = user.getCompanyId();
+        WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, companyId));
+        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
+        List<SysDict> sysDictOfClueSources = sysDictMapper.selectList(new LambdaQueryWrapper<SysDict>().eq(SysDict::getCompanyId, companyId).eq(SysDict::getCode, "ClueSources"));
+        InputStream inputStream = null;
+        OutputStream outputStream = null;
+        try {
+            inputStream = multipartFile.getInputStream();
+            outputStream = new FileOutputStream(file);
+            byte[] buffer = new byte[4096];
+            int temp = 0;
+            while ((temp = inputStream.read(buffer, 0, 4096)) != -1) {
+                outputStream.write(buffer, 0, temp);
+            }
+            inputStream.close();
+            outputStream.close();
+            //解析表格
+            XSSFWorkbook workbook = new XSSFWorkbook(file);
+            //我们只需要第一个sheet
+            XSSFSheet sheet = workbook.getSheetAt(0);
+            //由于第一行需要指明列对应的标题
+            int rowNum = sheet.getLastRowNum();
+            //获取当前表单模板 校验规则
+            SysForm sysForm = sysFormMapper.selectOne(new LambdaQueryWrapper<SysForm>().eq(SysForm::getCode, "Customer").eq(SysForm::getCompanyId, companyId).eq(SysForm::getIsCurrent, 1));
+            if(sysForm==null){
+                msg.setError("当前模块未配置自定义模板,需先完成配置");
+                return msg;
+            }
+            String config = sysForm.getConfig();
+            JSONObject configOb = JSON.parseObject(config);
+            JSONArray configObJSONArray = configOb.getJSONArray("list");
+            List<String> userNameList=new ArrayList<>();
+            HttpRespMsg respMsg=new HttpRespMsg();
+            for (int rowIndex = 0; rowIndex <= rowNum; rowIndex++) {
+                XSSFRow row = sheet.getRow(rowIndex);
+                if (row == null) {
+                    continue;
+                }
+                //跳过空行
+                if (ExcelUtil.isRowEmpty(row)) {
+                    continue;
+                }
+                //获取到当前行的列数据
+                int cellNum = row.getLastCellNum();
+                for (int i = 0; i < cellNum; i++) {
+                    JSONObject item = configObJSONArray.getJSONObject(i);
+                    String modelName = item.getString("model");
+                    XSSFCell cell = row.getCell(i);
+                    if(cell!=null){
+                        switch (item.getString("type")){
+//                            case "time":cell.setCellType(CellType.NUMERIC);
+//                                break;
+                            default:cell.setCellType(CellType.STRING);
+                        }
+                    }
+                    if(modelName.equals("inchargerId")){
+                        System.out.println("=====");
+                        System.out.println(modelName);
+                        System.out.println(cell.toString());
+                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                            userNameList.add(cell.getStringCellValue());
+                        }
+                    }
+
+                }
+            }
+            System.out.println("参与搜索的人员列表"+userNameList + userNameList.size());
+            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1&&userNameList.size()>0){
+                respMsg = wxCorpInfoService.getBatchSearchUserInfo(wxCorpInfo, userNameList,null);
+                if(respMsg.code.equals("0")){
+                    msg.setError("姓名为["+String.valueOf(respMsg.data)+"]的人员存在重复,请使用工号!");
+                    return msg;
+                }
+            }
+            List<User> targetUserList= (List<User>) respMsg.data;
+            //直接忽略空行 从row1开始
+            for (int rowIndex = 1; rowIndex <= rowNum; rowIndex++) {
+                XSSFRow row = sheet.getRow(rowIndex);
+                if (row == null) {
+                    continue;
+                }
+                //跳过空行
+                if (ExcelUtil.isRowEmpty(row)) {
+                    continue;
+                }
+                //获取到当前行的列数据
+                int cellNum = row.getLastCellNum();
+                Custom custom =new Custom();
+                custom.setCompanyId(companyId);
+                custom.setCreateTime(new Date());
+                custom.setCreatorId(user.getId());
+                for (int i = 0; i < cellNum; i++) {
+                    JSONObject item = configObJSONArray.getJSONObject(i);
+                    String modelName = item.getString("model");
+                    String className = modelName.substring(0, 1).toUpperCase() + modelName.substring(1);
+                    String getter="get"+className;
+                    String setter="set"+className;
+                    XSSFCell cell = row.getCell(i);
+                    if(cell!=null){
+                        switch (item.getString("type")){
+
+                            default:cell.setCellType(CellType.STRING);
+                        }
+                    }
+                    //校验当前列是否为必填
+                    JSONObject options = item.getJSONObject("options");
+                    JSONObject rules = options.getJSONObject("rules");
+                    Boolean required = rules.getBoolean("required");
+                    if(required){
+                        if(StringUtils.isEmpty(cell.getStringCellValue())){
+                            msg.setError(item.getString("label")+"值不能为空值");
+                            return msg;
+                        }
+                    }
+                    if(modelName.equals("inchargerId")){
+                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                            String userName = cell.getStringCellValue();
+                            Optional<User> first;
+                            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                                Optional<User> optional = targetUserList.stream().filter(tl -> tl.getName().equals(userName)).findFirst();
+                                first= userList.stream().filter(u ->(u.getJobNumber()!=null&&u.getJobNumber().equals(userName))||(optional.isPresent()&&u.getCorpwxUserid()!=null&&u.getCorpwxUserid().equals(optional.get().getCorpwxUserid()))).findFirst();
+                            }else {
+                                first= userList.stream().filter(u -> u.getName().equals(userName)||(u.getJobNumber()!=null&&u.getJobNumber().equals(userName))).findFirst();
+                            }
+                            if (first.isPresent()) {
+                                custom.setInchargerId(first.get().getId());
+                            } else {
+                                msg.setError("负责人["+userName+"]在系统中不存在");
+                                return msg;
+                            }
+                        }
+                    }else {
+                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                            Class<Clue> clueClass = Clue.class;
+                            Method method = clueClass.getMethod(setter,String.class);
+                            method.invoke(custom,cell.getStringCellValue());
+                        }
+                    }
+
+                }
+                customMapper.insert(custom);
+            }
+        } catch (IOException | NoSuchMethodException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();
+        } catch (Exception e) {
+            e.printStackTrace();
+            msg.setError("验证失败");
+            return msg;
+        }
+        return msg;
+    }
+
 
 
     private Custom setNull(Custom clue) {
     private Custom setNull(Custom clue) {
         if (clue.getPlate1() == "") {
         if (clue.getPlate1() == "") {

+ 57 - 6
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -22,12 +22,10 @@ import org.apache.commons.io.FileUtils;
 import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.usermodel.*;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.*;
 import org.springframework.http.*;
 import org.springframework.http.client.ClientHttpResponse;
 import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
@@ -37,7 +35,6 @@ import org.springframework.web.client.RestTemplate;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartFile;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
-import javax.print.DocFlavor;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import java.io.*;
 import java.io.*;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
@@ -168,6 +165,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     @Resource
     @Resource
     private TaskService taskService;
     private TaskService taskService;
     @Resource
     @Resource
+    private CustomService customService;
+    @Resource
     private ReportAuditorSettingService reportAuditorSettingService;
     private ReportAuditorSettingService reportAuditorSettingService;
     @Resource
     @Resource
     private ReportAuditorSettingMapper reportAuditorSettingMapper;
     private ReportAuditorSettingMapper reportAuditorSettingMapper;
@@ -5575,8 +5574,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                             if (company.getIsInternational() == 1) {
                             if (company.getIsInternational() == 1) {
                                 operateDate = operateDate.plusSeconds(offsetSeconds);
                                 operateDate = operateDate.plusSeconds(offsetSeconds);
                             }
                             }
-							
-								
+
+
                             String time = dtf.format(operateDate);
                             String time = dtf.format(operateDate);
                             String msg= "";
                             String msg= "";
 							if (auditMsg != null) {
 							if (auditMsg != null) {
@@ -5605,7 +5604,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 								}else {
 								}else {
 									msg = time+" " + auditMsg;
 									msg = time+" " + auditMsg;
 								}
 								}
-							} 
+							}
                             if (!isFirst) {
                             if (!isFirst) {
                                 sb.append("->");
                                 sb.append("->");
                             } else {
                             } else {
@@ -8732,4 +8731,56 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         httpRespMsg.data = finalMap;
         httpRespMsg.data = finalMap;
         return httpRespMsg;
         return httpRespMsg;
     }
     }
+
+    @Override
+    public HttpRespMsg exportCustomerTotalCount(String startDate, String endDate, String userId, Integer departmentId, Integer exportType, HttpServletRequest request) throws Exception {
+        User user = userMapper.selectById(request.getHeader("token"));
+        WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, user.getCompanyId()));
+
+
+        List<List<String>> dataList=new ArrayList<>();
+        List<String> titleList=new ArrayList<>();
+        Collections.addAll(titleList,"员工姓名","新增客户数","成交客户数","客户成交率");
+        dataList.add(titleList);
+        HttpRespMsg respMsg = customService.getCustomerTotalCount(startDate, endDate, userId,departmentId, exportType, request);
+        List<UserVO> userVOList = (List<UserVO>) respMsg.getData();
+        for (UserVO userVO : userVOList) {
+            List<String> item = new ArrayList<>();
+            item.add(userVO.getName());
+            item.add((userVO.getCustomertotal()==null ? 0: userVO.getCustomertotal())+"");
+            item.add((userVO.getCustomerDeal()==null ? 0: userVO.getCustomerDeal())+"");
+            item.add((userVO.getDealRate()==null ? 0: userVO.getDealRate())+"");
+
+            dataList.add(item);
+
+        }
+        String fileName="客户总量分析表_"+ System.currentTimeMillis();
+        return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,fileName,dataList,path);
+    }
+
+    @Override
+    public HttpRespMsg exportCustomerTransferRate(String startDate, String endDate, String userId, Integer departmentId, Integer exportType, HttpServletRequest request) throws Exception {
+        User user = userMapper.selectById(request.getHeader("token"));
+        WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, user.getCompanyId()));
+
+
+        List<List<String>> dataList=new ArrayList<>();
+        List<String> titleList=new ArrayList<>();
+        Collections.addAll(titleList,"员工姓名","客户转化率");
+
+        HttpRespMsg respMsg = customService.getCustomerTransferRate(startDate, endDate, userId, departmentId, exportType, request);
+        List<UserVO> userVOList = (List<UserVO>) respMsg.getData();
+
+        dataList.add(titleList);
+
+
+        for (UserVO userVO : userVOList) {
+            List<String> item = new ArrayList<>();
+            item.add(userVO.getName());
+            item.add(userVO.getDealRate()+"");
+            dataList.add(item);
+        }
+        String fileName="客户转化率分析表_"+ System.currentTimeMillis();
+        return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,fileName,dataList,path);
+    }
 }
 }

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

@@ -736,9 +736,26 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         JSONArray configObJSONArray = configOb.getJSONArray("list");
         JSONArray configObJSONArray = configOb.getJSONArray("list");
         List<List<String>> dataList=new ArrayList<>();
         List<List<String>> dataList=new ArrayList<>();
         List<String> titleList=new ArrayList<>();
         List<String> titleList=new ArrayList<>();
+        List<String> modelList=new ArrayList<>();
         for (int i = 0; i < configObJSONArray.size(); i++) {
         for (int i = 0; i < configObJSONArray.size(); i++) {
             JSONObject item = configObJSONArray.getJSONObject(i);
             JSONObject item = configObJSONArray.getJSONObject(i);
-            titleList.add(item.getString("label"));
+            String type = item.getString("type");
+            if (type.equals("grid")){
+                JSONArray columns = item.getJSONArray("columns");
+                for (int j = 0; j < columns.size(); j++) {
+                    JSONObject columnsJSONObject = columns.getJSONObject(j);
+                    JSONArray listJsonArray = columnsJSONObject.getJSONArray("list");
+                    for (int k = 0; k < listJsonArray.size(); k++) {
+                        JSONObject listJsonArrayJSONObject = listJsonArray.getJSONObject(k);
+                        titleList.add(listJsonArrayJSONObject.getString("label"));
+                        modelList.add(listJsonArrayJSONObject.getString("model"));
+                    }
+                }
+            }
+            else {
+                titleList.add(item.getString("label"));
+                modelList.add(item.getString("model"));
+            }
         }
         }
         dataList.add(titleList);//设置表头
         dataList.add(titleList);//设置表头
 
 
@@ -762,23 +779,13 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
 
 
         for (TasKVo tasKVo : taskVoList) {
         for (TasKVo tasKVo : taskVoList) {
             List<String> item=new ArrayList<>();
             List<String> item=new ArrayList<>();
-            for (int i = 0; i < configObJSONArray.size(); i++) {
-                JSONObject target = configObJSONArray.getJSONObject(i);
-                String model = target.getString("model");
-//                String targetName = model.substring(0, 1).toUpperCase() + model.substring(1);
+            for (int i = 0; i <  modelList.size(); i++) {
+
+                String model = modelList.get(i);
+                String targetName = model.substring(0, 1).toUpperCase() + model.substring(1);
                 Class<? extends TasKVo> aClass = tasKVo.getClass();
                 Class<? extends TasKVo> aClass = tasKVo.getClass();
                 String value="";
                 String value="";
-//                String value = String.valueOf(aClass.getMethod("get" + targetName).invoke(tasKVo)==null?"":aClass.getMethod("get" + targetName).invoke(tasKVo));
-                /*if(model.equals("inchargerId")){
-                    if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
-                        value = "$userName"+String.valueOf(aClass.getMethod("getInchargerName").invoke(product))+"$";
-                    }else {
-                        value = String.valueOf(aClass.getMethod("getInchargerName").invoke(product));
-                    }
-                }*/
-                /*if(model.equals("sex")){
-                    value = String.valueOf(aClass.getMethod("getSex").invoke(tasKVo)).equals("null") ?"":String.valueOf(aClass.getMethod("getSex").invoke(tasKVo));
-                }*/
+
                 if(model.equals("taskName")){
                 if(model.equals("taskName")){
                     value = String.valueOf(aClass.getMethod("getTaskName").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getTaskName").invoke(tasKVo));
                     value = String.valueOf(aClass.getMethod("getTaskName").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getTaskName").invoke(tasKVo));
                 }
                 }
@@ -846,6 +853,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                 else if(model.equals("phone")){
                 else if(model.equals("phone")){
                     value = String.valueOf(aClass.getMethod("getContactsPhone").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getContactsPhone").invoke(tasKVo));
                     value = String.valueOf(aClass.getMethod("getContactsPhone").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getContactsPhone").invoke(tasKVo));
                 }
                 }
+                else value= String.valueOf(aClass.getMethod("get" + targetName).invoke(tasKVo)==null?"":aClass.getMethod("get" + targetName).invoke(tasKVo));
                 item.add(value);
                 item.add(value);
             }
             }
             dataList.add(item);
             dataList.add(item);

+ 4 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java

@@ -95,10 +95,10 @@ public interface ReportMapper extends BaseMapper<Report> {
                                                          @Param("userId") String userId,
                                                          @Param("userId") String userId,
                                                          @Param("companyId") Integer companyId, String viewUserId, Integer pageStart, Integer pageSize);
                                                          @Param("companyId") Integer companyId, String viewUserId, Integer pageStart, Integer pageSize);
 
 
-    Integer getReportNameByDateAndDeptCount(@Param("date") String date,
-                                                         @Param("deptIds") List<Integer> deptIds,
-                                                         @Param("userId") String userId,
-                                                         @Param("companyId") Integer companyId, String viewUserId);
+//    Integer getReportNameByDateAndDeptCount(@Param("date") String date,
+//                                                         @Param("deptIds") List<Integer> deptIds,
+//                                                         @Param("userId") String userId,
+//                                                         @Param("companyId") Integer companyId, String viewUserId);
     List<Map<String, Object>> getDetailByStateInMyProfession(@Param("state") Integer state,
     List<Map<String, Object>> getDetailByStateInMyProfession(@Param("state") Integer state,
                                                @Param("companyId") Integer companyId,
                                                @Param("companyId") Integer companyId,
                                                @Param("leaderId") String leaderId);
                                                @Param("leaderId") String leaderId);

+ 42 - 10
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -71,7 +71,6 @@ import java.util.stream.Collectors;
  * @since 2019-12-31
  * @since 2019-12-31
  */
  */
 @Service
 @Service
-@Transactional
 public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> implements ReportService {
 public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> implements ReportService {
 //    @Resource
 //    @Resource
 //    AsyncTaskExecutor asyncTaskExecutor;//注入线程池对象
 //    AsyncTaskExecutor asyncTaskExecutor;//注入线程池对象
@@ -249,7 +248,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             TimeType timeType = timeTypeMapper.selectById(companyId);
             TimeType timeType = timeTypeMapper.selectById(companyId);
             List<Map<String, Object>> nameList = new ArrayList<>();
             List<Map<String, Object>> nameList = new ArrayList<>();
             List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全公司工时");
             List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全公司工时");
-            Integer totalMembCount = 0;
+//            Integer totalMembCount = 0;
             if (functionList.size() == 0) {
             if (functionList.size() == 0) {
                 List<Map<String, Object>> list = new ArrayList<>();
                 List<Map<String, Object>> list = new ArrayList<>();
                 List<Integer> allVisibleDeptIdList = null;
                 List<Integer> allVisibleDeptIdList = null;
@@ -271,10 +270,15 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 } else {
                 } else {
                     allVisibleDeptIdList = getAllVisibleDeptIdList(user, null);
                     allVisibleDeptIdList = getAllVisibleDeptIdList(user, null);
                 }
                 }
+                long start = System.currentTimeMillis();
                 //需要看可见部门(部门主要负责人和其他负责人以及查看本部门工时权限)所有人员的日报
                 //需要看可见部门(部门主要负责人和其他负责人以及查看本部门工时权限)所有人员的日报
                 nameList = reportMapper.getReportNameByDateAndDept(date,
                 nameList = reportMapper.getReportNameByDateAndDept(date,
                         allVisibleDeptIdList.size() > 0?allVisibleDeptIdList:null, targetUid, companyId, (deptId == null?viewUserId:null), pageStart, pageSize);
                         allVisibleDeptIdList.size() > 0?allVisibleDeptIdList:null, targetUid, companyId, (deptId == null?viewUserId:null), pageStart, pageSize);
-                totalMembCount = reportMapper.getReportNameByDateAndDeptCount(date, allVisibleDeptIdList.size() > 0?allVisibleDeptIdList:null, targetUid, companyId, (deptId == null?viewUserId:null));
+                long middle = System.currentTimeMillis();
+                System.out.println("中间获取getReportNameByDateAndDept 耗时:" + (middle - start) + "ms");
+//                totalMembCount = reportMapper.getReportNameByDateAndDeptCount(date, allVisibleDeptIdList.size() > 0?allVisibleDeptIdList:null, targetUid, companyId, (deptId == null?viewUserId:null));
+                long end = System.currentTimeMillis();
+                System.out.println("获取totalMembCount 耗时:" + (end - middle) + "ms");
             } else {
             } else {
                 //查看全公司的数据
                 //查看全公司的数据
                 List<Integer> ids = null;
                 List<Integer> ids = null;
@@ -296,9 +300,14 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         }
                         }
                     }
                     }
                 }
                 }
+                long start = System.currentTimeMillis();
                 nameList = reportMapper.getReportNameByDateAndDept(date,
                 nameList = reportMapper.getReportNameByDateAndDept(date,
                         ids, targetUid, companyId, null, pageStart, pageSize);
                         ids, targetUid, companyId, null, pageStart, pageSize);
-                totalMembCount = reportMapper.getReportNameByDateAndDeptCount(date, ids, targetUid, companyId, null);
+                long middle = System.currentTimeMillis();
+                System.out.println("中间获取getReportNameByDateAndDept 耗时:" + (middle - start) + "ms");
+//                totalMembCount = reportMapper.getReportNameByDateAndDeptCount(date, ids, targetUid, companyId, null);
+//                long end = System.currentTimeMillis();
+//                System.out.println("获取totalMembCount 耗时:" + (end - middle) + "ms");
             }
             }
             if (nameList.size() > 0) {
             if (nameList.size() > 0) {
                 List<String> userIds = new ArrayList<>();
                 List<String> userIds = new ArrayList<>();
@@ -492,7 +501,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 HashMap retMap = new HashMap();
                 HashMap retMap = new HashMap();
                 retMap.put("data", nameList);
                 retMap.put("data", nameList);
                 retMap.put("pageIndex", pageIndex);
                 retMap.put("pageIndex", pageIndex);
-                retMap.put("hasMore", pageIndex * pageSize + pageSize < totalMembCount);
+                retMap.put("hasMore", nameList.size() > 0);
                 httpRespMsg.data = retMap;
                 httpRespMsg.data = retMap;
             }
             }
         } catch (NullPointerException e) {
         } catch (NullPointerException e) {
@@ -1046,6 +1055,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
 
     //新增或编辑报告
     //新增或编辑报告
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg editReport(List<Report> reportList, String date, List<User> userList, BigDecimal hourCost, Integer companyId, String summary) {
     public HttpRespMsg editReport(List<Report> reportList, String date, List<User> userList, BigDecimal hourCost, Integer companyId, String summary) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         TimeType timeType = timeTypeMapper.selectById(companyId);
         TimeType timeType = timeTypeMapper.selectById(companyId);
@@ -1467,6 +1477,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
 
     //删除报告
     //删除报告
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg deleteReport(String userId, String date) {
     public HttpRespMsg deleteReport(String userId, String date) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         String delUserId = request.getHeader("TOKEN");
         String delUserId = request.getHeader("TOKEN");
@@ -1756,6 +1767,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
 
     //审核通过某天某人的某报告
     //审核通过某天某人的某报告
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg approveReport(String reportIds, Integer isDepartment, HttpServletRequest request,String evaluate) {
     public HttpRespMsg approveReport(String reportIds, Integer isDepartment, HttpServletRequest request,String evaluate) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         String token = request.getHeader("Token");
         String token = request.getHeader("Token");
@@ -2672,6 +2684,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
 
     //审核未通过 以及 撤销审核某天某人
     //审核未通过 以及 撤销审核某天某人
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg denyReport(String date, String reportIds, String reason, Integer isDepartment, HttpServletRequest request) {
     public HttpRespMsg denyReport(String date, String reportIds, String reason, Integer isDepartment, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         User user = userMapper.selectById(request.getHeader("Token"));
         User user = userMapper.selectById(request.getHeader("Token"));
@@ -2984,22 +2997,25 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         if (list.size() > 0) {
         if (list.size() > 0) {
             //存在查看权限的部门
             //存在查看权限的部门
             //获取公司全部人员; 按照人员状态,如果是已经离职的,当前日期在离职日期以后的,不需要显示该人员
             //获取公司全部人员; 按照人员状态,如果是已经离职的,当前日期在离职日期以后的,不需要显示该人员
+
             QueryWrapper<User> queryWrapper = new QueryWrapper<User>().eq("company_id", companyId);
             QueryWrapper<User> queryWrapper = new QueryWrapper<User>().eq("company_id", companyId);
             queryWrapper.and(wrapper->wrapper.eq("is_active", 1).eq("report_status",0)
             queryWrapper.and(wrapper->wrapper.eq("is_active", 1).eq("report_status",0)
                     .or(wrapper2->wrapper2.eq("is_active", 0).gt("inactive_date", date)));
                     .or(wrapper2->wrapper2.eq("is_active", 0).gt("inactive_date", date)));
             List<User> userList = userMapper.selectList(queryWrapper);
             List<User> userList = userMapper.selectList(queryWrapper);
+            long t3 = System.currentTimeMillis();
+            System.out.println("获取人员列表耗时:" + (t3 - t2) + "ms");
             List<LeaveSheet> leaveSheetList = leaveSheetMapper.selectList(
             List<LeaveSheet> leaveSheetList = leaveSheetMapper.selectList(
                     new QueryWrapper<LeaveSheet>().select("id, owner_id, start_date, end_date, leave_type, time_type, time_days, time_hours").eq("company_id", companyId));
                     new QueryWrapper<LeaveSheet>().select("id, owner_id, start_date, end_date, leave_type, time_type, time_days, time_hours").eq("company_id", companyId));
-            long t3 = System.currentTimeMillis();
-            System.out.println("获取人员请假列表耗时:" + (t3 - t2) + "ms");
+            long t4 = System.currentTimeMillis();
+            System.out.println("获取人员请假列表耗时:" + (t4 - t3) + "ms");
             LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
             LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
             List<HashMap> userMapList = new ArrayList<>();
             List<HashMap> userMapList = new ArrayList<>();
             LocalDate curDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
             LocalDate curDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
 
 
             //获取当日已填写的人员报告
             //获取当日已填写的人员报告
             List<Map<String, Object>> reportNameByDate = reportMapper.getReportNameByDate(date, companyId, null);
             List<Map<String, Object>> reportNameByDate = reportMapper.getReportNameByDate(date, companyId, null);
-            long t4 = System.currentTimeMillis();
-            System.out.println("获取当日已填写的人员报告耗时:" + (t4 - t3) + "ms");
+            long t5 = System.currentTimeMillis();
+            System.out.println("获取当日已填写的人员报告耗时:" + (t5 - t4) + "ms");
             Company company = companyMapper.selectById(companyId);
             Company company = companyMapper.selectById(companyId);
             TimeType timeType = timeTypeMapper.selectById(companyId);
             TimeType timeType = timeTypeMapper.selectById(companyId);
             //如果没有开通OA模块,有开通企业微信同步考勤,从user_corpwx_time表中获取请假时长
             //如果没有开通OA模块,有开通企业微信同步考勤,从user_corpwx_time表中获取请假时长
@@ -3082,6 +3098,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg batchApproveReport(String reportIds, Integer isDepartment, HttpServletRequest request,String evaluate) throws Exception {
     public HttpRespMsg batchApproveReport(String reportIds, Integer isDepartment, HttpServletRequest request,String evaluate) throws Exception {
         String token = request.getHeader("Token");
         String token = request.getHeader("Token");
         User user = userMapper.selectById(token);
         User user = userMapper.selectById(token);
@@ -3871,6 +3888,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
 
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg batchDenyReport(String reportIds, Integer isDepartment, String reason, HttpServletRequest request) {
     public HttpRespMsg batchDenyReport(String reportIds, Integer isDepartment, String reason, HttpServletRequest request) {
         User user = userMapper.selectById(request.getHeader("Token"));
         User user = userMapper.selectById(request.getHeader("Token"));
         Company company = companyMapper.selectById(user.getCompanyId());
         Company company = companyMapper.selectById(user.getCompanyId());
@@ -4013,6 +4031,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg cancelReport(String userId, String reportIds, HttpServletRequest request) {
     public HttpRespMsg cancelReport(String userId, String reportIds, HttpServletRequest request) {
         HttpRespMsg msg = new HttpRespMsg();
         HttpRespMsg msg = new HttpRespMsg();
         User user = userMapper.selectById(userId);
         User user = userMapper.selectById(userId);
@@ -6023,6 +6042,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg saveProjectTime(Integer companyId, List<Report> reportList, JSONArray userReportArray) {
     public HttpRespMsg saveProjectTime(Integer companyId, List<Report> reportList, JSONArray userReportArray) {
         //如果当天该员工已有报告,要删除
         //如果当天该员工已有报告,要删除
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         HttpRespMsg httpRespMsg = new HttpRespMsg();
@@ -6485,6 +6505,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg approveAllImport(HttpServletRequest request) {
     public HttpRespMsg approveAllImport(HttpServletRequest request) {
         String token = request.getHeader("TOKEN");
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
         User user = userMapper.selectById(token);
@@ -6501,6 +6522,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg denyHisReport(Integer hisId, String reason, HttpServletRequest request) {
     public HttpRespMsg denyHisReport(Integer hisId, String reason, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
         try {
@@ -6675,6 +6697,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg fixIssue(Integer companyId, String startDate, String endDate) {
     public HttpRespMsg fixIssue(Integer companyId, String startDate, String endDate) {
         HttpRespMsg msg = new HttpRespMsg();
         HttpRespMsg msg = new HttpRespMsg();
         List<Map<String, Object>> reportList = reportMapper.selectErrorGroupData(companyId, startDate, endDate);
         List<Map<String, Object>> reportList = reportMapper.selectErrorGroupData(companyId, startDate, endDate);
@@ -6928,6 +6951,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg uploadThirdReportData(String yearMonth,HttpServletRequest request) {
     public HttpRespMsg uploadThirdReportData(String yearMonth,HttpServletRequest request) {
         HttpRespMsg httpRespMsg=new HttpRespMsg();
         HttpRespMsg httpRespMsg=new HttpRespMsg();
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
@@ -7070,6 +7094,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg correctWorkingTime(String userIds, String startDate, String endDate) {
     public HttpRespMsg correctWorkingTime(String userIds, String startDate, String endDate) {
         HttpRespMsg msg=new HttpRespMsg();
         HttpRespMsg msg=new HttpRespMsg();
         QueryWrapper<Report> queryWrapper=new QueryWrapper<>();
         QueryWrapper<Report> queryWrapper=new QueryWrapper<>();
@@ -7208,7 +7233,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         reportMapper.update(upR, new QueryWrapper<Report>().in("id", targetRids));
         reportMapper.update(upR, new QueryWrapper<Report>().in("id", targetRids));
     }
     }
 
 
-
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg approveDeptAuditReport(User user, String auditDeptId) {
     public HttpRespMsg approveDeptAuditReport(User user, String auditDeptId) {
         HttpRespMsg msg = new HttpRespMsg();
         HttpRespMsg msg = new HttpRespMsg();
         Integer companyId = user.getCompanyId();
         Integer companyId = user.getCompanyId();
@@ -7261,6 +7286,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
      * @return
      * @return
      */
      */
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void moveReport(User sourceUser,User targetUser) {
     public void moveReport(User sourceUser,User targetUser) {
         //转移日报
         //转移日报
         List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("creator_id", sourceUser.getId()));
         List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("creator_id", sourceUser.getId()));
@@ -7332,6 +7358,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg fillWorkingHours(String yearMonth, MonthWorkingTimeVO monthVO, HttpServletRequest request) {
     public HttpRespMsg fillWorkingHours(String yearMonth, MonthWorkingTimeVO monthVO, HttpServletRequest request) {
         HttpRespMsg msg = new HttpRespMsg();
         HttpRespMsg msg = new HttpRespMsg();
 
 
@@ -7859,6 +7886,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg batchDelete(String userIds, Integer deptId, String startDate, String endDate, HttpServletRequest request) {
     public HttpRespMsg batchDelete(String userIds, Integer deptId, String startDate, String endDate, HttpServletRequest request) {
         //限制只针对赛元微电子
         //限制只针对赛元微电子
         HttpRespMsg msg = new HttpRespMsg();
         HttpRespMsg msg = new HttpRespMsg();
@@ -7896,6 +7924,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg batchApproveByDate(String startDate, String endDate, Integer departmentId, HttpServletRequest request) {
     public HttpRespMsg batchApproveByDate(String startDate, String endDate, Integer departmentId, HttpServletRequest request) {
         HttpRespMsg msg = new HttpRespMsg();
         HttpRespMsg msg = new HttpRespMsg();
         //限制只针对赛元微电子
         //限制只针对赛元微电子
@@ -8170,6 +8199,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg pushProjectReportToSap(String pushDate,Integer reportId) {
     public HttpRespMsg pushProjectReportToSap(String pushDate,Integer reportId) {
         HttpRespMsg httpRespMsg =new HttpRespMsg();
         HttpRespMsg httpRespMsg =new HttpRespMsg();
         LocalDateTime localDateTime=LocalDateTime.now();
         LocalDateTime localDateTime=LocalDateTime.now();
@@ -9124,6 +9154,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg changeReminder(HttpServletRequest request,String createDate,String userId,String startDate,String endDate) throws Exception {
     public HttpRespMsg changeReminder(HttpServletRequest request,String createDate,String userId,String startDate,String endDate) throws Exception {
         HttpRespMsg msg=new HttpRespMsg();
         HttpRespMsg msg=new HttpRespMsg();
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
@@ -9342,6 +9373,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg cancelReminder(HttpServletRequest request, String createDate, String userId) {
     public HttpRespMsg cancelReminder(HttpServletRequest request, String createDate, String userId) {
         HttpRespMsg msg=new HttpRespMsg();
         HttpRespMsg msg=new HttpRespMsg();
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();

+ 42 - 42
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

@@ -652,7 +652,7 @@
             AND a.create_date=#{date}
             AND a.create_date=#{date}
         </if>
         </if>
         <if test="companyId != null and companyId != ''">
         <if test="companyId != null and companyId != ''">
-            AND b.company_id=#{companyId}
+            AND a.company_id=#{companyId}
         </if>
         </if>
         <if test="leaderId != null and leaderId != ''">
         <if test="leaderId != null and leaderId != ''">
             AND (a.project_auditor_id = #{leaderId} or project.incharger_id = #{leaderId})
             AND (a.project_auditor_id = #{leaderId} or project.incharger_id = #{leaderId})
@@ -670,7 +670,7 @@
             AND a.create_date=#{date}
             AND a.create_date=#{date}
         </if>
         </if>
         <if test="companyId != null and companyId != ''">
         <if test="companyId != null and companyId != ''">
-            AND b.company_id=#{companyId}
+            AND a.company_id=#{companyId}
         </if>
         </if>
         <if test="leaderId != null and leaderId != ''">
         <if test="leaderId != null and leaderId != ''">
             AND project_ccuser.`user_id` = #{leaderId}
             AND project_ccuser.`user_id` = #{leaderId}
@@ -722,45 +722,45 @@
         </if>
         </if>
     </select>
     </select>
 
 
-    <select id="getReportNameByDateAndDeptCount" resultType="java.lang.Integer">
-        SELECT count(DISTINCT b.id) as count
-        FROM report AS a
-        JOIN user AS b ON a.creator_id=b.id
-        left join project on project.id = a.project_id
-        LEFT JOIN project_ccuser ON a.project_id = project_ccuser.project_id
-        WHERE 1=1
-        <if test="date != null and date != ''">
-            AND a.create_date=#{date}
-        </if>
-        <choose>
-            <when test="userId != null">
-                AND b.id=#{userId}
-            </when>
-            <otherwise>
-                <!--自己,担任项目经理,日报审核人,抄送人,或者自己部门的人填的日报 -->
-                <if test="viewUserId != null">
-                    and (a.creator_id = #{viewUserId} or a.project_auditor_id = #{viewUserId} or project.incharger_id = #{viewUserId}
-                    or project_ccuser.`user_id` = #{viewUserId}
-                    <if test="deptIds != null">
-                        or b.department_id in
-                        <foreach item="item" collection="deptIds" separator="," open="(" close=")" index="">
-                            #{item, jdbcType=INTEGER}
-                        </foreach>
-                    </if>
-                    )
-                </if>
-                <if test="viewUserId == null">
-                    <if test="deptIds != null">
-                        and b.department_id in
-                        <foreach item="item" collection="deptIds" separator="," open="(" close=")" index="">
-                            #{item, jdbcType=INTEGER}
-                        </foreach>
-                    </if>
-                </if>
-            </otherwise>
-        </choose>
-        AND b.company_id = #{companyId}
-    </select>
+<!--    <select id="getReportNameByDateAndDeptCount" resultType="java.lang.Integer">-->
+<!--        SELECT count(DISTINCT b.id) as count-->
+<!--        FROM report AS a-->
+<!--        JOIN user AS b ON a.creator_id=b.id-->
+<!--        left join project on project.id = a.project_id-->
+<!--        LEFT JOIN project_ccuser ON a.project_id = project_ccuser.project_id-->
+<!--        WHERE 1=1-->
+<!--        <if test="date != null and date != ''">-->
+<!--            AND a.create_date=#{date}-->
+<!--        </if>-->
+<!--        <choose>-->
+<!--            <when test="userId != null">-->
+<!--                AND b.id=#{userId}-->
+<!--            </when>-->
+<!--            <otherwise>-->
+<!--                &lt;!&ndash;自己,担任项目经理,日报审核人,抄送人,或者自己部门的人填的日报 &ndash;&gt;-->
+<!--                <if test="viewUserId != null">-->
+<!--                    and (a.creator_id = #{viewUserId} or a.project_auditor_id = #{viewUserId} or project.incharger_id = #{viewUserId}-->
+<!--                    or project_ccuser.`user_id` = #{viewUserId}-->
+<!--                    <if test="deptIds != null">-->
+<!--                        or b.department_id in-->
+<!--                        <foreach item="item" collection="deptIds" separator="," open="(" close=")" index="">-->
+<!--                            #{item, jdbcType=INTEGER}-->
+<!--                        </foreach>-->
+<!--                    </if>-->
+<!--                    )-->
+<!--                </if>-->
+<!--                <if test="viewUserId == null">-->
+<!--                    <if test="deptIds != null">-->
+<!--                        and b.department_id in-->
+<!--                        <foreach item="item" collection="deptIds" separator="," open="(" close=")" index="">-->
+<!--                            #{item, jdbcType=INTEGER}-->
+<!--                        </foreach>-->
+<!--                    </if>-->
+<!--                </if>-->
+<!--            </otherwise>-->
+<!--        </choose>-->
+<!--        AND b.company_id = #{companyId}-->
+<!--    </select>-->
 
 
     <!--专业待审核的报告列表-->
     <!--专业待审核的报告列表-->
     <select id="getDetailByStateInMyProfession" resultType="java.util.Map">
     <select id="getDetailByStateInMyProfession" resultType="java.util.Map">
@@ -785,7 +785,7 @@
         SELECT DISTINCT b.id, b.name, cast(b.department_id as SIGNED) as departmentId,a.create_date AS date
         SELECT DISTINCT b.id, b.name, cast(b.department_id as SIGNED) as departmentId,a.create_date AS date
         FROM report AS a
         FROM report AS a
         JOIN user AS b ON a.creator_id=b.id
         JOIN user AS b ON a.creator_id=b.id
-        WHERE a.department_audit_state = 0 and a.state = 0 AND b.company_id=#{companyId}
+        WHERE a.department_audit_state = 0 and a.state = 0 AND a.company_id=#{companyId}
         AND a.creator_id in (select id from user where department_id in
         AND a.creator_id in (select id from user where department_id in
         <foreach collection="departmentIds" item="deptId" open="(" close=")" index="index" separator=",">
         <foreach collection="departmentIds" item="deptId" open="(" close=")" index="index" separator=",">
             #{deptId}
             #{deptId}

+ 9 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -5689,7 +5689,15 @@
                     this.listLoading = false;
                     this.listLoading = false;
                     if (res.code == "ok") {
                     if (res.code == "ok") {
                         //扩增
                         //扩增
-                        this.reportList = this.reportList.concat(res.data.data);
+                        if (res.data.data.length > 0) {
+                            this.reportList = this.reportList.concat(res.data.data);
+                        } else if (this.pageIndex > 1){
+                            this.$message({
+                            message: '没有更多数据了',
+                            type: "info"
+                        });
+                        }
+                        
                         this.hasMore = res.data.hasMore;//标记是否还有更多数据
                         this.hasMore = res.data.hasMore;//标记是否还有更多数据
                         if(document.querySelector("#day"+this.choseDay)){
                         if(document.querySelector("#day"+this.choseDay)){
                             document.querySelector("#day"+this.choseDay).scrollIntoView(true);
                             document.querySelector("#day"+this.choseDay).scrollIntoView(true);