Parcourir la source

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

seyason il y a 1 an
Parent
commit
bff81274bb
30 fichiers modifiés avec 798 ajouts et 154 suppressions
  1. 8 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/components/relatedProducts/relatedProducts.vue
  2. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/api.ts
  3. 10 4
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/stageSetting.vue
  4. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/detail/index.vue
  5. 7 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue
  6. 3 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/api.ts
  7. 157 10
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/index.vue
  8. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/constant.ts
  9. 14 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue
  10. 122 16
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/BusinessOpportunityController.java
  11. 1 33
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/SalesOrderController.java
  12. 5 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/BusinessOpportunity.java
  13. 7 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/OrderProductDetail.java
  14. 3 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Product.java
  15. 5 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Stage.java
  16. 3 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/BusinessOpportunityMapper.java
  17. 6 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/BusinessOpportunityService.java
  18. 2 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/ClueService.java
  19. 2 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/SalesOrderService.java
  20. 4 2
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/StageService.java
  21. 234 26
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/BusinessOpportunityServiceImpl.java
  22. 85 25
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ClueServiceImpl.java
  23. 5 10
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CustomServiceImpl.java
  24. 48 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/SalesOrderServiceImpl.java
  25. 37 4
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/StageServiceImpl.java
  26. 2 1
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/OrderProductDetailMapper.xml
  27. 4 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  28. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  29. 15 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  30. 4 0
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

+ 8 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/components/relatedProducts/relatedProducts.vue

@@ -64,6 +64,7 @@ import { ref, reactive, onMounted, inject, watchEffect } from "vue";
 const props = defineProps<{
     productTableList: any,
     height?: string,
+    productTableListValue: any
 }>()
 
 const productTable: any = ref([{}])
@@ -114,15 +115,20 @@ function deteleTableItem(index: number) {
 function returnData() {
     let jsonstr = JSON.stringify(productTable.value)
     let json = '[{"index":0}]'
-    if(jsonstr == json) {
+    if (jsonstr == json) {
         return false
     }
+    productTable.value.forEach(item => {
+        delete item.index
+    });
     return productTable.value
 }
 
 watchEffect(() => {
-    const { productTableList, height } = props
+    const { productTableList, height, productTableListValue = [] } = props
+    console.log(productTableListValue, '<==== 数据')
     productArrar.value = productTableList || []
+    productTable.value = productTableListValue.length > 0 ? productTableListValue : [{ index: 0 }]
     heightClass.value = !height ? '200px' : height
 });
 

+ 1 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/api.ts

@@ -19,6 +19,7 @@ export const DETELEFILEFILE = `/business-opportunity/deleteFile`
 export const REFIENAMEFILE = `/business-opportunity/reFileName`
 export const UPLOADFILEFILE = `/business-opportunity/uploadFile`
 export const URL_IMPOERBUSINESS = `/business-opportunity/importData`
+export const URL_DETELESTAGE = `/business-opportunity/deleteStage`
 
 
 export const stageStatus = [

+ 10 - 4
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/stageSetting.vue

@@ -29,7 +29,7 @@
                         <el-table-column label="操作" fixed="right" width="200">
                             <template #default="scope">
                                 <el-button link type="primary" size="large" @click="addStage(scope.row)">编辑</el-button>
-                                <el-button link type="danger" size="large" @click="deteStage(+scope.$index)">删除</el-button>
+                                <el-button link type="danger" size="large" @click="deteStage(+scope.$index, scope.row)" :disabled="scope.row.isFinish == 1">删除</el-button>
                                 <el-button link type="primary" size="large" @click="moveStage(+scope.$index, 'up')"
                                     v-if="scope.$index != 0">上移</el-button>
                                 <el-button link type="primary" size="large" @click="moveStage(+scope.$index, 'down')"
@@ -75,7 +75,7 @@
 <script lang="ts" setup>
 import { post } from '@/utils/request';
 import { ref, reactive, onMounted, watch, inject } from 'vue'
-import { BUSIESS_GETSATE, BUSIESS_SAVESAIE } from '../api';
+import { BUSIESS_GETSATE, BUSIESS_SAVESAIE, URL_DETELESTAGE } from '../api';
 import { List } from 'echarts';
 
 type moveStageType = 'up' | 'down';
@@ -126,7 +126,7 @@ function saveState() {
         }
     })
     allLoading.saveLoading = true
-    post(BUSIESS_SAVESAIE, { list: JSON.stringify(data) }).then(() => {
+    post(BUSIESS_SAVESAIE, { stages: JSON.stringify(data) }).then(() => {
         globalPopup?.showSuccess('保存成功')
         cancel()
     }).finally(() => {
@@ -191,7 +191,13 @@ function moveStage(index: number, stageType: moveStageType) {
     }
 }
 
-function deteStage(index: number) {
+function deteStage(index: number, row: any) {
+    if(row.id) {
+        post(URL_DETELESTAGE, { id: row.id }).then(() => {
+            stageTableList.value.splice(index, 1)
+        })
+        return
+    }
     stageTableList.value.splice(index, 1)
 }
 

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

@@ -71,7 +71,7 @@ const pageLoading = ref(false)
 
 function getDetail() {
     pageLoading.value = true
-    post(URL_GETDETAIL, {}).then((res) => {
+    post(URL_GETDETAIL, { id: rowId.value }).then((res) => {
         console.log(res)
     }).finally(() => {
         pageLoading.value = false

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

@@ -378,11 +378,11 @@ function editCustomerSave(flag: boolean) {
 
 function editCustomer(row: any) { // row 有数据代表编辑
   if (row) {
-    const { id, companyPhone, customName, inchargerId, createTime, customSourceId, customerIndustryId, customerLevelId, email } = row
+    const { id, companyPhone, customName, inchargerId, createTime, customSourceId, customerIndustryId, customerLevelId, email, telPhone } = row
     const formVal = {
       id, customName, inchargerId, customerIndustryId, customerLevelId, email, customSourceId,
       createTime: formatDate(new Date(createTime)),
-      telPhone: companyPhone,
+      telPhone, companyPhone
     }
     allLoading.customerTemplateRefLoading = true
     setTimeout(() => {
@@ -392,6 +392,11 @@ function editCustomer(row: any) { // row 有数据代表编辑
     customerTemplateValue.value = formVal
     allText.editCustomerText = '编辑客户'
   } else { // 没有数据代表新建
+    setTimeout(() => {
+      console.log(customerTemplateRef.value)
+      customerTemplateValue.value = {}
+      customerTemplateRefKey.value++
+    }, 200)
     allText.editCustomerText = '新增客户'
   }
   showVisible('editCustomerVisible')

+ 3 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/api.ts

@@ -5,7 +5,10 @@ export const GETSYSFILED = "/sys-dict/getListByCode";
 export const GETPERSONNEL = "/user/getSimpleActiveUserList";
 export const GETGENERATEFOEM = `/sys-form/getListByCode${MOD}`
 export const GETALLPRODUCT = `/sys-form/getListByCode/Order`
+export const GETTABLELISTPRODUCT = `/product/list`
 export const GETTABLELIST = `${MOD}/list`
+export const URL_OEDERUPDATE = `${MOD}/addOrUpdate`
+export const URL_PRODUTWITHORDER = `${MOD}/productWithOrder`
 
 export const tableColumns: TableColumn[] = [
     { prop: 'orderCode', label: '订单编号', event: 'toDetali', width: '150' },

+ 157 - 10
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/index.vue

@@ -36,7 +36,7 @@
       <div class="bg-white w-full h-full p-3 shadow-md rounded-md flex flex-col">
         <div class="flex justify-end pb-3">
           <!-- 操作按钮 -->
-          <el-button v-permission="['aabbc']" type="primary">新建订单</el-button>
+          <el-button type="primary" @click="editOrder(false)">新建订单</el-button>
           <el-button type="primary">批量转移</el-button>
           <el-button type="primary">批量删除</el-button>
           <el-button type="primary">回收站</el-button>
@@ -58,7 +58,7 @@
             </el-table-column>
             <el-table-column :label="'操作'" :width="'200px'" fixed="right">
               <template #default="scope">
-                <el-button link type="primary" size="large">编辑</el-button>
+                <el-button link type="primary" size="large" @click="editOrder(scope.row)">编辑</el-button>
                 <el-button link type="primary" size="large">新建任务</el-button>
                 <el-button link type="danger" size="large">删除</el-button>
               </template>
@@ -72,19 +72,43 @@
         </div>
       </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">{{ allText.orderEditText }}</h4>
+          <div>
+            <el-button type="primary" :loading="allLoading.editSaveLading" @click="saveOrder(true)">保存并新建</el-button>
+            <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" :value="orderTemplateValue" />
+        <div>相关产品</div>
+        <RelatedProducts ref="relatedProductsRef" :productTableList="productTableList" :productTableListValue="productTableListValue" />
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script lang="ts" setup>
 import { ref, reactive, onMounted, inject, defineExpose } from "vue";
-import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate } from '@/utils/tools'
+import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, getTemplateKey } from '@/utils/tools'
 import { post, get } from "@/utils/request";
-import { tableColumns, GETSYSFILED, GETPERSONNEL, GETGENERATEFOEM, MOD, GETTABLELIST, GETALLPRODUCT } from "./api";
+import { tableColumns, GETSYSFILED, GETPERSONNEL, GETGENERATEFOEM, MOD, GETTABLELIST, GETALLPRODUCT, GETTABLELISTPRODUCT, URL_OEDERUPDATE, URL_PRODUTWITHORDER } from "./api";
 import { useRouter, useRoute } from "vue-router";
+import { GenerateForm } from '@zmjs/form-design';
 import { URL_FETALL } from "../customer/api";
 
-const router = useRouter()
+import RelatedProducts from '@/components/relatedProducts/relatedProducts.vue'
+import TaskModal from '@/components/TaskModal/index.vue'
+import { formatDateTime } from "@/utils/times";
 
+const router = useRouter()
+const globalPopup = inject<GlobalPopup>('globalPopup')
 const filterForm = reactive<FilterForm>({ // 筛选条件 Value
   contactPerson: "",
   customerId: "",
@@ -102,19 +126,91 @@ const selectData = reactive({ // 下拉数据
   RemittanceStatus: [{ id: 0, name: '已回款' }, { id: 1, name: '未回款' }, { id: 2, name: '已完全回款' }] as any[], // 回款状态
   AllProduct: [] as any[] // 所有产品
 })
-const filterItems = ref<FilterItem[]>([]) // 渲染筛选条件
 const formTablePaging = reactive({ // 分页条件
   currentPage: 1,
   pageSize: 10,
   total: 0,
 })
-const formTable = ref([]) // 表格数据
 const allLoading = reactive({ // 按钮加载 Loading
   formTableLading: false,
+  editSaveLading: false,
+  orderTemplateLoadinng: false
 })
 const allVisible = reactive({
-
+  editOrderVisible: false
+})
+const allText = reactive({
+  orderEditText: '新建订单'
 })
+const orderTemplate = ref({
+  list: [],
+  config: {}
+})
+const orderTemplateValue = ref({})
+const orderTemplateKey = ref(1)
+const orderTemplateRef = ref<typeof GenerateForm>()
+const relatedProductsRef = ref<typeof RelatedProducts>()
+const filterItems = ref<FilterItem[]>([]) // 渲染筛选条件
+const formTable = ref([]) // 表格数据
+const productTableList = ref([])
+const productTableListValue = ref([])
+
+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()
+      }
+      getTableList()
+    }).finally(() => {
+      allLoading.editSaveLading = false
+    })
+  }).catch((_err: any) => {
+    console.log(_err)
+    globalPopup?.showError('请填写完整')
+  })
+}
+
+function editOrder(item: any) {
+  showVisible('editOrderVisible')
+  allLoading.orderTemplateLoadinng = true
+  if (item) {
+    editProduct(item)
+    const templateKey = getTemplateKey(orderTemplate.value.list)
+    let formVal: templateKey = { id: item.id }
+    for (let i = 0; i < orderTemplate.value.list.length; i++) {
+      const key = templateKey[i]
+      formVal[key] = item[key]
+    }
+    orderTemplateValue.value = formVal
+    allText.orderEditText = '编辑订单'
+  }
+  if (!item) {
+    orderTemplateValue.value = {}
+    productTableListValue.value = []
+    allText.orderEditText = '新增订单'
+  }
+  setTimeout(() => {
+    orderTemplateKey.value++
+    allLoading.orderTemplateLoadinng = false
+  }, 500)
+}
 
 function toDetali(row: any) {
   router.push({
@@ -171,12 +267,20 @@ async function getSystemField() {
     const { id, customName } = item
     return { id, name: customName }
   })
-  // const res = await get(GETGENERATEFOEM)
-  // generateFormData.value = JSON.parse(res.data[0].config)
+  const res = await get(GETGENERATEFOEM)
+  orderTemplate.value = JSON.parse(res.data[0].config)
 
   setFilterItems()
 }
 
+function showVisible(type: keyof typeof allVisible) { // 显示弹窗
+  allVisible[type] = true
+}
+
+function closeVisible(type: keyof typeof allVisible) {
+  allVisible[type] = false
+}
+
 function setFilterItems() {
   filterItems.value = [
     { label: '订单编号', key: 'orderCode', type: 'input' },
@@ -190,10 +294,53 @@ function setFilterItems() {
   ]
 }
 
+function editProduct(row: any) {
+  post(URL_PRODUTWITHORDER, { id: row.id }).then(({ data }) => {
+    const list = data.map((item: any) => {
+      const { id, productName, productCode, unit, unitName, typeName, type, price, inventory, orderProductDetail } = item
+      return { id, productId: id, productName, productCode, unit, unitName, typeName, type, price, inventory, 
+        quantity: +orderProductDetail?.num, 
+        discount: +orderProductDetail?.discount, 
+        sellingPrice: +orderProductDetail?.sealPrice,
+        totalPrice: +orderProductDetail?.totalPrice
+      }
+    })
+    console.log('开始执行', list)
+    productTableListValue.value = list
+  })
+}
+
+function getProductTableList() {
+  post(GETTABLELISTPRODUCT, { 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: ''
+        }
+      })
+    }
+  })
+}
+
 onMounted(() => {
   getSystemField()
   getAllProduct()
   getTableList()
+  getProductTableList()
 })
 </script>
 

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

@@ -18,3 +18,4 @@ export const DEYELWCLUE = `${prefix}/listDeleterClue`
 export const DETERDETELE = `${prefix}/deleterDelete`
 export const ROLLBACK = `${prefix}/rollback`
 export const URL_IMPORTTHREAD = `${prefix}/importData`
+export const URL_EXPOERTHREAD = `${prefix}/exportData`

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

@@ -57,7 +57,7 @@
           <el-button type="primary" @click="batchDeletes()">批量删除</el-button>
           <el-button type="primary" @click="showDeteleClue(true)">回收站</el-button>
           <el-button type="primary" @click="dialogVisible.importVisible = true">导入</el-button>
-          <el-button type="primary">导出</el-button>
+          <el-button type="primary" @click="exportTheadTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
         </div>
         <div class="flex-1 w-full overflow-hidden">
           <el-table ref="clueTableRef" :data="clueTable" border v-loading="allLoading.clueTableLading"
@@ -169,8 +169,8 @@
 
 <script lang="ts" setup>
 import { ref, reactive, onMounted, inject } from "vue";
-import { GETSYSFILED, MOD, IMPORMOD, GETPERSONNEL, GETTABLE, GETTEMPLATE, GETDETAIL, UNDATECLAIM, UNDATEFORM, DELTEROW, URL_IMPORTTHREAD } from './constant'
-import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, createTaskFromType, confirmAction, downloadTemplate } from '@/utils/tools'
+import { GETSYSFILED, MOD, IMPORMOD, GETPERSONNEL, GETTABLE, GETTEMPLATE, GETDETAIL, UNDATECLAIM, UNDATEFORM, DELTEROW, URL_IMPORTTHREAD, URL_EXPOERTHREAD } from './constant'
+import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, createTaskFromType, confirmAction, downloadTemplate, downloadFile } from '@/utils/tools'
 import { FormInstance, FormRules, ElMessageBox, ElTable, UploadRequestOptions } from 'element-plus'
 import { post, get, uploadFile } from "@/utils/request";
 import { useRouter, useRoute } from "vue-router";
@@ -219,6 +219,7 @@ const allLoading = reactive({
   generateFormLading: false,
   clueLoading: false,
   importLoading: false,
+  exoprtLoading: false,
 })
 const dialogVisible = reactive({
   editClueDialogVisible: false,
@@ -256,6 +257,16 @@ const transferForm = reactive({
 
 
 // 定义方法
+function exportTheadTableList() {
+  allLoading.exoprtLoading = true
+  let valueForm = getFromValue(filterCriteriaForm)
+  post(URL_EXPOERTHREAD, {...valueForm}).then((res) => {
+    downloadFile(res.data, '线索表表导出.xlsx')
+  }).finally(() => {
+    allLoading.exoprtLoading = false
+  })
+}
+
 function newTask(item: any) {
   const { id } = item
   taskModalForm.value = { ...createTaskFromType(3), clueId: id, }

+ 122 - 16
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/BusinessOpportunityController.java

@@ -1,15 +1,20 @@
 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.management.platform.entity.*;
 import com.management.platform.mapper.BusinessOpportunityMapper;
+import com.management.platform.mapper.SysFormMapper;
 import com.management.platform.mapper.UserMapper;
-import com.management.platform.service.BusinessOpportunityService;
-import com.management.platform.service.StageService;
-import com.management.platform.service.SysFunctionService;
-import com.management.platform.service.TaskService;
+import com.management.platform.service.*;
+import com.management.platform.service.impl.ExcelExportServiceImpl;
 import com.management.platform.util.HttpRespMsg;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 
@@ -19,10 +24,7 @@ import org.springframework.web.multipart.MultipartFile;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
 
 /**
  * <p>
@@ -35,14 +37,20 @@ import java.util.List;
 @RestController
 @RequestMapping("/business-opportunity")
 public class BusinessOpportunityController {
-
+    @Resource
+    private ExcelExportServiceImpl excelExportService;
+    @Resource
+    private SysFormMapper sysFormMapper;
+    @Autowired
+    private WxCorpInfoService wxCorpInfoService;
     @Resource
     private UserMapper userMapper;
     @Resource
     private SysFunctionService sysFunctionService;
     @Resource
     private StageService stageService;
-
+    @Value(value = "${upload.path}")
+    private String path;
     @Resource
     private BusinessOpportunityService bOservice;
     @Resource
@@ -60,11 +68,86 @@ public class BusinessOpportunityController {
     }
 
 
-    @RequestMapping("exportData")
-    public Object exportData(BusinessOpportunity bo, HttpServletRequest request) throws Exception {
-        return bOservice.exportData(bo,request);
+
+    @RequestMapping("/importData")
+    public HttpRespMsg importData(MultipartFile multipartFile){
+        return bOservice.importData(multipartFile);
     }
 
+
+    @RequestMapping("/exportData")
+    public HttpRespMsg exportData(BusinessOpportunity bo ,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(bo, 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("delete")
     public Object delete(BusinessOpportunity bo) {
@@ -132,6 +215,7 @@ public class BusinessOpportunityController {
         }else {
             //修改
             bOservice.update(bo,user.getId());
+
         }
         msg.setMsg("操作成功");
         return msg;
@@ -145,6 +229,21 @@ public class BusinessOpportunityController {
         bOservice.getAndTransfer(bo, user);
         return msg;
     }
+    @RequestMapping("saveReason")
+    public Object saveReason(BusinessOpportunity bo, HttpServletRequest request) {
+        User user = userMapper.selectById(request.getHeader("Token"));
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.setMsg("操作成功");
+        bOservice.saveReason(bo, user);
+        return msg;
+    } @RequestMapping("saveContactsId")
+    public Object saveContactsId(BusinessOpportunity bo, HttpServletRequest request) {
+        User user = userMapper.selectById(request.getHeader("Token"));
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.setMsg("操作成功");
+        bOservice.saveContactsId(bo, user);
+        return msg;
+    }
     @RequestMapping("list")
     public HttpRespMsg list(BusinessOpportunity bo, HttpServletRequest request) {
         HashMap<Object, Object> r = new HashMap<>();
@@ -214,15 +313,22 @@ public class BusinessOpportunityController {
     public HttpRespMsg saveProduct(BusinessOpportunity bo , HttpServletRequest request) {
         User user = userMapper.selectById(request.getHeader("Token"));
         return bOservice.saveProduct(bo,user);
+    } @RequestMapping("saveContacts")
+    public HttpRespMsg saveContacts(BusinessOpportunity bo , HttpServletRequest request) {
+        User user = userMapper.selectById(request.getHeader("Token"));
+        return bOservice.saveProduct(bo,user);
     }
 
     @RequestMapping("saveStage")
-    public HttpRespMsg insertStage(List<Stage> stages, HttpServletRequest request) {
+    public HttpRespMsg insertStage(String stages, HttpServletRequest request) {
         return stageService.changeStage(stages,request);
+    }   @RequestMapping("deleteStage")
+    public HttpRespMsg deleteStage(Stage stage) {
+        return stageService.deleteStage(stage);
     }
     @RequestMapping("getStage")
-    public HttpRespMsg Stage() {
-        return stageService.getStage();
+    public HttpRespMsg Stage(HttpServletRequest request) {
+        return stageService.getStage(request);
     }
 
     private BusinessOpportunity setNull(BusinessOpportunity bo) {

+ 1 - 33
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/SalesOrderController.java

@@ -44,10 +44,6 @@ public class SalesOrderController {
     @Resource
     private OrderProductDetailService orderProductDetailService;
     @Resource
-    private ProductMapper productMapper;
-    @Resource
-    private SysDictService sysDictService;
-    @Resource
     private TaskService taskService;
     @Resource
     private AuditLogCenterService auditLogCenterService;
@@ -261,35 +257,7 @@ public class SalesOrderController {
      * */
     @RequestMapping("/productWithOrder")
     public HttpRespMsg productWithOrder(Integer id){
-        HttpRespMsg msg=new HttpRespMsg();
-        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
-        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
-        List<SysDict> sysDictOfProductUnit = sysDictService.list(new LambdaQueryWrapper<SysDict>().eq(SysDict::getCode, "ProductUnit"));
-        List<SysDict> sysDictOfProductType = sysDictService.list(new LambdaQueryWrapper<SysDict>().eq(SysDict::getCode, "ProductType"));
-        List<OrderProductDetail> orderProductDetails = orderProductDetailService.list(new LambdaQueryWrapper<OrderProductDetail>().eq(OrderProductDetail::getOrderId, id));
-        List<Integer> productIds = orderProductDetails.stream().map(OrderProductDetail::getProductId).collect(Collectors.toList());
-        productIds.add(-1);
-        List<Product> productList = productMapper.selectList(new LambdaQueryWrapper<Product>().in(Product::getId, productIds));
-        productList.forEach(p->{
-            Optional<User> user = userList.stream().filter(u -> u.getId().equals(p.getInchargerId())).findFirst();
-            if(user.isPresent()){
-                p.setInchargerName(user.get().getName());
-            }
-            Optional<User> creator = userList.stream().filter(u -> u.getId().equals(p.getCreatorId())).findFirst();
-            if(creator.isPresent()){
-                p.setCreatorName(creator.get().getName());
-            }
-            Optional<SysDict> unit = sysDictOfProductUnit.stream().filter(u -> u.getId().equals(p.getUnit())).findFirst();
-            if(unit.isPresent()){
-                p.setUnitName(unit.get().getName());
-            }
-            Optional<SysDict> type = sysDictOfProductType.stream().filter(u -> u.getId().equals(p.getType())).findFirst();
-            if(type.isPresent()){
-                p.setTypeName(type.get().getName());
-            }
-        });
-        msg.setData(productList);
-        return msg;
+        return salesOrderService.productWithOrder(id);
     }
 
 

+ 5 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/BusinessOpportunity.java

@@ -51,6 +51,11 @@ public class BusinessOpportunity extends Model<BusinessOpportunity> {
      */
     @TableField("contacts_id")
     private Integer contactsId;
+    /**
+     * 赢单\输单 理由
+     */
+    @TableField("reason")
+    private String reason;
     @TableField(exist = false)
     private String contactsName;
 

+ 7 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/OrderProductDetail.java

@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2024-04-03
+ * @since 2024-05-29
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -49,6 +49,12 @@ public class OrderProductDetail extends Model<OrderProductDetail> {
     @TableField("discount")
     private Integer discount;
 
+    /**
+     * 合计
+     */
+    @TableField("total_price")
+    private BigDecimal totalPrice;
+
 
     @Override
     protected Serializable pkVal() {

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

@@ -151,6 +151,9 @@ public class Product extends Model<Product> {
     @TableField(exist = false)
     private String unitName;
 
+    @TableField(exist = false)
+    private OrderProductDetail orderProductDetail;
+
 
     @Override
     protected Serializable pkVal() {

+ 5 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Stage.java

@@ -32,6 +32,11 @@ public class Stage extends Model<Stage> {
      */
     @TableField("name")
     private String name;
+    /**
+     * 公司id
+     */
+    @TableField("company_id")
+    private Integer companyId;
 
     /**
      * 进度

+ 3 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/BusinessOpportunityMapper.java

@@ -2,7 +2,9 @@ package com.management.platform.mapper;
 
 import com.management.platform.entity.BusinessOpportunity;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.util.HttpRespMsg;
 import org.apache.ibatis.annotations.Param;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 import java.util.Map;
@@ -34,4 +36,5 @@ public interface BusinessOpportunityMapper extends BaseMapper<BusinessOpportunit
     Map<String, Object> getDataSummary(Integer companyId, String startDate, String endDate, String userId,@Param("list") List<String> targetUserIds);
 
     List<Map<String, Object>> getDataStage(Integer companyId, String startDate, String endDate, String userId,@Param("list") List<String> targetUserIds);
+
 }

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

@@ -39,7 +39,6 @@ public interface BusinessOpportunityService extends IService<BusinessOpportunity
 
     void getAndTransfer(BusinessOpportunity bo, User user);
 
-    Object exportData(BusinessOpportunity bo, HttpServletRequest request) throws Exception;
 
     HttpRespMsg saveProduct(BusinessOpportunity bo, User user);
 
@@ -60,4 +59,10 @@ public interface BusinessOpportunityService extends IService<BusinessOpportunity
     List<Map<String, Object>> getDataStage(Integer companyId, String startDate, String endDate, String userId,List<String> targetUserIds);
 
     void deleterDelete(List<Integer> ids);
+
+    HttpRespMsg importData(MultipartFile multipartFile);
+
+    void saveContactsId(BusinessOpportunity bo, User user);
+
+    void saveReason(BusinessOpportunity bo, User user);
 }

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

@@ -9,6 +9,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.InvocationTargetException;
 import java.util.List;
 
 /**
@@ -54,5 +55,5 @@ public interface ClueService extends IService<Clue> {
 
     HttpRespMsg importData(MultipartFile multipartFile);
 
-    HttpRespMsg exportData(Clue clue);
+    HttpRespMsg exportData(Clue clue) throws Exception;
 }

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

@@ -28,4 +28,6 @@ public interface SalesOrderService extends IService<SalesOrder> {
     HttpRespMsg dataSummary(Integer queryType, Integer dateType);
 
     HttpRespMsg businessOpportunityStage(Integer queryType, Integer dateType);
+
+    HttpRespMsg productWithOrder(Integer id);
 }

+ 4 - 2
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/StageService.java

@@ -17,7 +17,9 @@ import java.util.List;
  */
 public interface StageService extends IService<Stage> {
 
-    HttpRespMsg changeStage(List<Stage> stages, HttpServletRequest request);
+    HttpRespMsg changeStage(String stages, HttpServletRequest request);
 
-    HttpRespMsg getStage();
+    HttpRespMsg getStage(HttpServletRequest request);
+
+    HttpRespMsg deleteStage(Stage stage);
 }

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

@@ -13,25 +13,34 @@ import com.management.platform.mapper.*;
 import com.management.platform.service.BusinessOpportunityService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.service.WxCorpInfoService;
+import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.FileUtil;
 import com.management.platform.util.HttpRespMsg;
 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.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 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.math.BigDecimal;
 import java.net.URLEncoder;
 import java.util.*;
 
+
 /**
  * <p>
  * 服务实现类
@@ -54,6 +63,8 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
     @Resource
     private ActionLogMapper actionLogMapper;
     @Resource
+    private BusinessItemProductMapper bipMapper;
+    @Resource
     private UserMapper userMapper;
     @Resource
     private BusinessItemProductMapper biMapper;
@@ -61,7 +72,11 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
     private SysFormMapper sysFormMapper;
     @Autowired
     private UploadFileMapper uploadFileMapper;
+    @Resource
+    private HttpServletRequest request;
 
+    @Resource
+    private SysDictMapper sysDictMapper;
     @Override
     public List<BusinessOpportunity> getAll(BusinessOpportunity bo) {
         return bOMapper.selectAllList(bo);
@@ -78,8 +93,7 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
         businessOpportunity.setActionLogList(actionLogMapper.selectList(new QueryWrapper<ActionLog>().eq("item_id", bo.getId()).eq("code", "business")));
         businessOpportunity.setUploadFilePList(uploadFileMapper.selectByInfoList("business",bo.getId()));
         businessOpportunity.setTaskList(taskMapper.selectList(new QueryWrapper<Task>().eq("business_opportunity_id",bo.getId())));
-        List<BusinessItemProduct> businessItemProducts = biMapper.selectListToBoId(bo.getId());
-        businessOpportunity.setBusinessItemProducts(businessItemProducts);
+        List<BusinessItemProduct> businessItemProducts = bipMapper.selectList(new QueryWrapper<BusinessItemProduct>().eq("business_id", bo.getId()));
         if (businessItemProducts.size() > 0){
             BigDecimal finalPrice = new BigDecimal(0);
             BigDecimal discountedPrice = new BigDecimal(0);
@@ -96,6 +110,8 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
             // 整单折扣率
             businessOpportunity.setFinalPrice(divide.multiply(new BigDecimal(100)));
         }
+        businessOpportunity.setBusinessItemProducts(businessItemProducts);
+
         return businessOpportunity;
     }
 
@@ -126,7 +142,10 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
         bo.setCreateTime(new Date());
         bOMapper.insert(bo);
         List<BusinessItemProduct> businessItemProducts = JSONArray.parseArray(bo.getBusinessItemProductList(), BusinessItemProduct.class);
-        System.out.println(businessItemProducts);
+        for (BusinessItemProduct businessItemProduct : businessItemProducts) {
+            businessItemProduct.setBusinessId(bo.getId());
+            bipMapper.insert(businessItemProduct);
+        }
         ActionLog actionLog = new ActionLog();
         actionLog.setUserId(bo.getUserId());
         actionLog.setItemId(bo.getId());
@@ -140,6 +159,12 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
     public void update(BusinessOpportunity bo, String userId) {
         setNull(bo);
         bOMapper.updateById(bo);
+        bipMapper.delete(new QueryWrapper<BusinessItemProduct>().eq("business_id",bo.getId()));
+        List<BusinessItemProduct> businessItemProducts = JSONArray.parseArray(bo.getBusinessItemProductList(), BusinessItemProduct.class);
+        for (BusinessItemProduct businessItemProduct : businessItemProducts) {
+            businessItemProduct.setBusinessId(bo.getId());
+            bipMapper.insert(businessItemProduct);
+        }
         ActionLog log = new ActionLog();
         log.setItemId(bo.getId());
         log.setName("编辑了商机");
@@ -191,28 +216,7 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
     @Value(value = "${upload.file}")
     private String path;
 
-    @Override
-    public Object exportData(BusinessOpportunity bo, 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, "Clue").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);//设置表头
-
 
-        bo.setCompanyId(user.getCompanyId());
-
-        String fileName = "商机表导出_" + System.currentTimeMillis();
-        return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo, fileName, dataList, path);
-    }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -379,6 +383,210 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
         bOMapper.deleteBatchIds(ids);
     }
 
+    @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, "Thread").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();
+                BusinessOpportunity bo =new BusinessOpportunity();
+                bo.setCompanyId(companyId);
+                bo.setCreateTime(new Date());
+                bo.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")){
+//                            case "time":cell.setCellType(CellType.NUMERIC);
+//                                break;
+                            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()) {
+                                bo.setInchargerId(first.get().getId());
+                            } else {
+                                msg.setError("负责人["+userName+"]在系统中不存在");
+                                return msg;
+                            }
+                        }
+                    }else if(modelName.equals("contactsId")){
+                        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()) {
+                                bo.setContactsId(Integer.parseInt(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(bo,cell.getStringCellValue());
+                        }
+                    }
+
+                }
+                bOMapper.insert(bo);
+            }
+        } 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;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void saveContactsId(BusinessOpportunity bo, User user) {
+        bOMapper.update(bo, new UpdateWrapper<BusinessOpportunity>().eq("id", bo.getId()).set("contacts_id", bo.getContactsId()));
+        ActionLog al = new ActionLog();
+        al.setCode("business");
+        al.setName("关联了联系人");
+        al.setUserId(user.getId());
+        al.setItemId(bo.getId());
+        actionLogMapper.insert(al);
+    }
+
+    @Override
+    public void saveReason(BusinessOpportunity bo, User user) {
+        bOMapper.update(bo, new UpdateWrapper<BusinessOpportunity>().eq("id", bo.getId()).set("reason", bo.getReason()));
+        ActionLog al = new ActionLog();
+        al.setCode("business");
+        al.setName("编辑了 结束理由");
+        al.setUserId(user.getId());
+        al.setItemId(bo.getId());
+        actionLogMapper.insert(al);
+    }
+
+
     private BusinessOpportunity setNull(BusinessOpportunity bo) {
         if (bo.getPlate1() == "") {
             bo.setPlate1(null);

+ 85 - 25
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ClueServiceImpl.java

@@ -42,6 +42,7 @@ import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 
@@ -85,6 +86,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
     @Resource
     private SysDictMapper sysDictMapper;
 
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void insert(Clue clue) {
@@ -370,6 +372,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg importData(MultipartFile multipartFile) {
         HttpRespMsg msg=new HttpRespMsg();
         String fileName = multipartFile.getOriginalFilename();
@@ -429,30 +432,30 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
                     XSSFCell cell = row.getCell(i);
                     if(cell!=null){
                         switch (item.getString("type")){
-                            case "time":cell.setCellType(CellType.NUMERIC);
-                                break;
+//                            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());
-//                        }
-//                    }
+                    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;
-//                }
-//            }
+            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++) {
@@ -479,8 +482,8 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
                     XSSFCell cell = row.getCell(i);
                     if(cell!=null){
                         switch (item.getString("type")){
-                            case "time":cell.setCellType(CellType.NUMERIC);
-                                break;
+//                            case "time":cell.setCellType(CellType.NUMERIC);
+//                                break;
                             default:cell.setCellType(CellType.STRING);
                         }
                     }
@@ -511,7 +514,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
                                 return msg;
                             }
                         }
-                    }else if(modelName.equals("customLevel")){
+                    }else if(modelName.equals("customLevelId")){
                         if(!StringUtils.isEmpty(cell.getStringCellValue())){
                             Optional<SysDict> first = sysDictOfCustomLevel.stream().filter(s -> s.getName().equals(cell.getStringCellValue())).findFirst();
                             if(first.isPresent()){
@@ -520,7 +523,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
                                 throw new Exception("客户级别["+cell.getStringCellValue()+"不存在,请在系统字典中增加");
                             }
                         }
-                    }else if(modelName.equals("clueSources")){
+                    }else if(modelName.equals("clueSourcesId")){
                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
                            Optional<SysDict> first = sysDictOfClueSources.stream().filter(s -> s.getName().equals(cell.getStringCellValue())).findFirst();
                            if(first.isPresent()){
@@ -530,7 +533,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
                                throw new Exception("线索来源["+cell.getStringCellValue()+"不存在,请在系统字典中增加");
                            }
                        }
-                   }else if(modelName.equals("customIndustry")){
+                   }else if(modelName.equals("customIndustryId")){
                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
                            Optional<SysDict> first = sysDictOfCustomIndustry.stream().filter(s -> s.getName().equals(cell.getStringCellValue())).findFirst();
                            if(first.isPresent()){
@@ -565,8 +568,65 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
     }
 
     @Override
-    public HttpRespMsg exportData(Clue clue) {
-        return null;
+    public HttpRespMsg exportData(Clue clue) 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);
+        List<Clue> list1 = getList(clue);
+        for (Clue clue1 : list1) {
+            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 Clue> aClass = clue1.getClass();
+                            String value = String.valueOf(aClass.getMethod("get" + targetName).invoke(clue1)==null?"":aClass.getMethod("get" + targetName).invoke(clue1));
+                            if(model.equals("inchargerId")){
+                                if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                                    value = "$userName"+String.valueOf(aClass.getMethod("getInchargerName").invoke(clue1))+"$";
+                                }else {
+                                    value = String.valueOf(aClass.getMethod("getInchargerName").invoke(clue1));
+                                }
+                            }
+                            item.add(value);
+                        }
+                    }
+                }else {
+                    String model = target.getString("model");
+                    String targetName = model.substring(0, 1).toUpperCase() + model.substring(1);
+                    Class<? extends Clue> aClass = clue1.getClass();
+                    String value = String.valueOf(aClass.getMethod("get" + targetName).invoke(clue1)==null?"":aClass.getMethod("get" + targetName).invoke(clue1));
+                    if(model.equals("inchargerId")){
+                        if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                            value = "$userName"+String.valueOf(aClass.getMethod("getInchargerName").invoke(clue1))+"$";
+                        }else {
+                            value = String.valueOf(aClass.getMethod("getInchargerName").invoke(clue1));
+                        }
+                    }
+                    item.add(value);
+                }
+            }
+            dataList.add(item);
+        }
+        String fileName="线索表导出_"+ System.currentTimeMillis();
+        return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,fileName,dataList,path);
     }
 
 

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

@@ -184,21 +184,16 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
         for (CustomItemContacts contact : contacts) {
             ids.add(contact.getCustomId());
         }
-//        List<Contacts> cs = contactsMapper.selectList(new QueryWrapper<Contacts>().in("id", ids));
-        List<Contacts> cs = contactsMapper.selectListByIds(ids);
-        custom1.setContactsList(cs);
+        if (ids.size() > 0){
+            List<Contacts> cs = contactsMapper.selectListByIds(ids);
+            custom1.setContactsList(cs);
+        }
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         httpRespMsg.setData(custom1);
         return httpRespMsg;
     }
 
-//    @Override
-//    public HttpRespMsg getLog(Custom custom, HttpServletRequest request) {
-//        List<ActionLog> actionLogs = actionLogMapper.selectList(new QueryWrapper<ActionLog>().eq("code", "custom").eq("item_id", custom.getId()));
-//        HttpRespMsg httpRespMsg = new HttpRespMsg();
-//        httpRespMsg.setData(actionLogs);
-//        return httpRespMsg;
-//    }
+
 
     @Override
     public HttpRespMsg getList(Custom custom, HttpServletRequest request) {

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

@@ -81,6 +81,12 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
     @Resource
     private ContactsService contactsService;
     @Resource
+    private ProductMapper productMapper;
+    @Resource
+    private OrderProductDetailService orderProductDetailService;
+    @Resource
+    private SysDictService sysDictService;
+    @Resource
     private ClueMapper clueMapper;
     @Value(value = "${upload.path}")
     private String path;
@@ -178,6 +184,9 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
         }
         IPage<SalesOrder> orderIPage = salesOrderMapper.selectPage(new Page<>(pageIndex, pageSize), orderLambdaQueryWrapper);
         List<SalesOrder> records = orderIPage.getRecords();
+        List<Integer> orderIds = records.stream().map(SalesOrder::getId).distinct().collect(Collectors.toList());
+        orderIds.add(-1);
+        List<OrderProductDetail> orderProductDetails = orderProductDetailService.list(new LambdaQueryWrapper<OrderProductDetail>().in(OrderProductDetail::getOrderId, orderIds));
         records.forEach(r->{
             Optional<User> item = userList.stream().filter(u -> u.getId().equals(r.getCreatorId())).findFirst();
             if(item.isPresent()){
@@ -199,6 +208,8 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
             if(businessOpportunity.isPresent()){
                 r.setBusinessOpportunityName(businessOpportunity.get().getName());
             }
+            List<OrderProductDetail> details = orderProductDetails.stream().filter(o -> o.getOrderId().equals(r.getId())).collect(Collectors.toList());
+            r.setOrderProductDetailList(details);
         });
         Map map=new HashMap();
         map.put("record",records);
@@ -850,6 +861,43 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
         return msg;
     }
 
+    @Override
+    public HttpRespMsg productWithOrder(Integer id) {
+        HttpRespMsg msg=new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
+        List<SysDict> sysDictOfProductUnit = sysDictService.list(new LambdaQueryWrapper<SysDict>().eq(SysDict::getCode, "ProductUnit"));
+        List<SysDict> sysDictOfProductType = sysDictService.list(new LambdaQueryWrapper<SysDict>().eq(SysDict::getCode, "ProductType"));
+        List<OrderProductDetail> orderProductDetails = orderProductDetailService.list(new LambdaQueryWrapper<OrderProductDetail>().eq(OrderProductDetail::getOrderId, id));
+        List<Integer> productIds = orderProductDetails.stream().map(OrderProductDetail::getProductId).collect(Collectors.toList());
+        productIds.add(-1);
+        List<Product> productList = productMapper.selectList(new LambdaQueryWrapper<Product>().in(Product::getId, productIds));
+        productList.forEach(p->{
+            Optional<User> user = userList.stream().filter(u -> u.getId().equals(p.getInchargerId())).findFirst();
+            if(user.isPresent()){
+                p.setInchargerName(user.get().getName());
+            }
+            Optional<User> creator = userList.stream().filter(u -> u.getId().equals(p.getCreatorId())).findFirst();
+            if(creator.isPresent()){
+                p.setCreatorName(creator.get().getName());
+            }
+            Optional<SysDict> unit = sysDictOfProductUnit.stream().filter(u -> u.getId().equals(p.getUnit())).findFirst();
+            if(unit.isPresent()){
+                p.setUnitName(unit.get().getName());
+            }
+            Optional<SysDict> type = sysDictOfProductType.stream().filter(u -> u.getId().equals(p.getType())).findFirst();
+            if(type.isPresent()){
+                p.setTypeName(type.get().getName());
+            }
+            Optional<OrderProductDetail> first = orderProductDetails.stream().filter(o -> o.getProductId().equals(p.getId())).findFirst();
+            if(first.isPresent()){
+                p.setOrderProductDetail(first.get());
+            }
+        });
+        msg.setData(productList);
+        return msg;
+    }
+
     @Override
     public HttpRespMsg businessOpportunityStage(Integer queryType, Integer dateType) {
         HttpRespMsg msg=new HttpRespMsg();

+ 37 - 4
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/StageServiceImpl.java

@@ -1,8 +1,17 @@
 package com.management.platform.service.impl;
 
+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.QueryWrapper;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.management.platform.entity.BusinessOpportunity;
+import com.management.platform.entity.CustomerInfo;
 import com.management.platform.entity.Stage;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.BusinessOpportunityMapper;
 import com.management.platform.mapper.StageMapper;
+import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.StageService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.util.HttpRespMsg;
@@ -26,13 +35,20 @@ public class StageServiceImpl extends ServiceImpl<StageMapper, Stage> implements
 
     @Autowired
     private StageMapper stageMapper;
+    @Autowired
+    private BusinessOpportunityMapper boMapper;
+    @Autowired
+    private UserMapper userMapper;
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public HttpRespMsg changeStage(List<Stage> stages, HttpServletRequest request) {
+    public HttpRespMsg changeStage(String stages, HttpServletRequest request) {
         HttpRespMsg msg = new HttpRespMsg();
+        List<Stage> stages1 = JSONObject.parseArray(stages, Stage.class);
         int i = 0;
-        for (Stage stage : stages) {
+        User user = userMapper.selectById(request.getHeader("Token"));
+        for (Stage stage : stages1) {
             stage.setSeq(i);
+            stage.setCompanyId(user.getCompanyId());
             if(null != stage.getId()){
                 stageMapper.updateById(stage);
             }else {
@@ -44,10 +60,27 @@ public class StageServiceImpl extends ServiceImpl<StageMapper, Stage> implements
         return msg;
     }
 
+
+
+
     @Override
-    public HttpRespMsg getStage() {
+    public HttpRespMsg getStage(HttpServletRequest request) {
         HttpRespMsg msg = new HttpRespMsg();
-        msg.setData(stageMapper.selectList(new QueryWrapper<Stage>().orderBy(true, false, "seq")));
+        msg.setData(stageMapper.selectList(new QueryWrapper<Stage>().eq("company_id",userMapper.selectById(request.getHeader("Token")).getCompanyId()).orderBy(true, true, "seq")));
+        return msg;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public HttpRespMsg deleteStage(Stage stage) {
+        Integer i = boMapper.selectCount(new QueryWrapper<BusinessOpportunity>().eq("stage_id", stage.getId()));
+        HttpRespMsg msg = new HttpRespMsg();
+        if (i > 0){
+            msg.setError("此阶段已使用");
+            return msg;
+        }
+        stageMapper.deleteById(stage.getId());
+        msg.setMsg("操作成功");
         return msg;
     }
 }

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

@@ -10,11 +10,12 @@
         <result column="seal_price" property="sealPrice" />
         <result column="num" property="num" />
         <result column="discount" property="discount" />
+        <result column="total_price" property="totalPrice" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, order_id, product_id, seal_price, num, discount
+        id, order_id, product_id, seal_price, num, discount, total_price
     </sql>
 
 </mapper>

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

@@ -2114,8 +2114,8 @@ public class ReportController {
     }
 
     @RequestMapping("/getUserDailyWorkTime")
-    public HttpRespMsg getUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate) throws Exception{
-        return reportService.getUserDailyWorkTime(request, startDate, endDate);
+    public HttpRespMsg getUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate,Integer hasReportDeptId) throws Exception{
+        return reportService.getUserDailyWorkTime(request, startDate, endDate,hasReportDeptId);
     }
 
     @RequestMapping("/getUserDailyWorkTimeReminder")
@@ -2139,8 +2139,8 @@ public class ReportController {
     }
 
     @RequestMapping("/exportUserDailyWorkTime")
-    public HttpRespMsg exportUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate) throws Exception{
-        return reportService.exportUserDailyWorkTime(request, startDate, endDate);
+    public HttpRespMsg exportUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate,Integer hasReportDeptId) throws Exception{
+        return reportService.exportUserDailyWorkTime(request, startDate, endDate,hasReportDeptId);
     }
 
     @RequestMapping("/isWorkDay")

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java

@@ -62,9 +62,9 @@ public interface ReportService extends IService<Report> {
 
     HttpRespMsg listByStateDepartment(Integer state, Integer projectId, String date, HttpServletRequest request);
 
-    HttpRespMsg getUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate) throws Exception;
+    HttpRespMsg getUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate,Integer hasReportDeptId) throws Exception;
 
-    HttpRespMsg exportUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate) throws Exception;
+    HttpRespMsg exportUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate,Integer hasReportDeptId) throws Exception;
 
     HttpRespMsg importData(Integer companyId, Integer withCheckIn, MultipartFile file, HttpServletRequest request);
 

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

@@ -4300,7 +4300,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
 
     @Override
-    public HttpRespMsg getUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate) throws Exception {
+    public HttpRespMsg getUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate,Integer hasReportDeptId) throws Exception {
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
         Integer companyId = user.getCompanyId();
@@ -4335,6 +4335,10 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         //String[] weekDayCHN = {"周一","周二","周三","周四","周五","周六","周日"};
         String[] weekDayCHN = {MessageUtils.message("week.Monday"),MessageUtils.message("week.Tuesday"),MessageUtils.message("week.Wednesday"),MessageUtils.message("week.Thursday"),MessageUtils.message("week.Friday"),MessageUtils.message("week.Saturday"),MessageUtils.message("week.Sunday")};
         HttpRespMsg msg = new HttpRespMsg();
+        List<Integer> branchDepartment = null;
+        if(hasReportDeptId != null){
+            branchDepartment = departmentService.getBranchDepartment(Integer.valueOf(hasReportDeptId),departmentList);
+        }
         List<User> allRangeUserList = new ArrayList<>();
         List<Map<String, Object>> list = null;
         //分角色权限:管理员看全部的,部门负责人看自己部门的,个人只能看自己的。
@@ -4345,12 +4349,12 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             //检查是不是部门负责人(含主要负责人和其他负责人)
             List<Integer> allDeptIds = getAllVisibleDeptIdList(user, allDeptList);
             if (allDeptIds.size() > 0) {
-                list = reportMapper.getUserDailyWorkTime(companyId, startDate, endDate, allDeptIds, null,user.getId());
+                list = reportMapper.getUserDailyWorkTime(companyId, startDate, endDate, branchDepartment==null?allDeptIds:branchDepartment, null,user.getId());
                 //部门负责人看自己部门相关的 以及自己的
                 allRangeUserList = userMapper.selectList(new QueryWrapper<User>().in("department_id", allDeptIds).or().eq("id",user.getId()).orderByDesc("department_id"));
             } else {
                 //看自己的所负责的项目相关人员的
-                list = reportMapper.getUserDailyWorkTime(companyId, startDate, endDate, null, user.getId(),user.getId());
+                list = reportMapper.getUserDailyWorkTime(companyId, startDate, endDate, branchDepartment, user.getId(),user.getId());
                 //项目相关的人员列表
                 List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().eq("incharger_id", user.getId()));
                 List<Project> collect = projectList.stream().collect(Collectors.toList());
@@ -4363,11 +4367,16 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 }
             }
         } else {
-            list = reportMapper.getUserDailyWorkTime(companyId, startDate, endDate, null, null,user.getId());
+            list = reportMapper.getUserDailyWorkTime(companyId, startDate, endDate, branchDepartment, null,user.getId());
             //管理员看全公司所有人
             allRangeUserList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).orderByDesc("department_id"));
         }
         List<User> needRangeUserList=new ArrayList<>();
+        //按人员过滤
+        if(branchDepartment!=null&&branchDepartment.size()>0){
+            List<Integer> finalBranchDepartment = branchDepartment;
+            allRangeUserList=allRangeUserList.stream().filter(at-> finalBranchDepartment.contains(at.getDepartmentId())).collect(Collectors.toList());
+        }
         for (User u : allRangeUserList) {
             if(u.getInactiveDate()==null||(u.getInactiveDate()!=null&&u.getInactiveDate().isAfter(LocalDate.parse(startDate))||u.getIsActive()==1)){
                 needRangeUserList.add(u);
@@ -4554,8 +4563,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
 
     @Override
-    public HttpRespMsg exportUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate) throws Exception {
-        HttpRespMsg msg = getUserDailyWorkTime(request, startDate, endDate);
+    public HttpRespMsg exportUserDailyWorkTime(HttpServletRequest request, String startDate, String endDate,Integer hasReportDeptId) throws Exception {
+        HttpRespMsg msg = getUserDailyWorkTime(request, startDate, endDate,hasReportDeptId);
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
         WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", companyId));
         CompanyDingding dingding = companyDingdingService.getOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId));

+ 4 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -1430,6 +1430,8 @@
                     <el-button slot="append" @click="searchScreen(0)" icon="el-icon-search"></el-button>
                 </el-input>
                 <selectCat v-if="user.userNameNeedTranslate == '1'" :filterable="true"  :searchBoxTop="'1'" :size="'small'" :subject="usersList" :subjectId="usersListId" :distinction="'12'" :clearable="true" @selectCal="selectCal"></selectCat>
+                <el-cascader v-if="user.userNameNeedTranslate != 1" :size="'small'" v-model="deptIdForHasReport" placeholder="请选择部门" :options="departmentList" :props="{ checkStrictly: true, value: 'id' }" clearable style="width: 200px;" @change="showMonthWorkTime()"></el-cascader>
+                <vueCascader :size="'small'" :widthStr="'200'" :clearable="true" :subject="departmentList" :radios="true" :distinction="'1'" @vueCasader="vueCasader" v-if="user.userNameNeedTranslate == 1" :selectNameChuan="$t('other.allDepartments')" @change="showMonthWorkTime()"></vueCascader>
             </div>
             <div style="float: right; vertical-align: middle;height:32px">
               <el-link
@@ -2476,6 +2478,7 @@
                 userReportDeptList: [],
                 isReminder:true,
                 reportLogCheckDialog:false,
+                deptIdForHasReport:[],
             };
         },
         watch: {
@@ -4041,6 +4044,7 @@
         let parameter={
             startDate: this.WorktimeDatepickValue[0],
             endDate: this.WorktimeDatepickValue[1],
+            hasReportDeptId:this.deptIdForHasReport.length>0?this.deptIdForHasReport[this.deptIdForHasReport.length-1]:null,
         }
       this.http.post(
         "/report/getUserDailyWorkTime",