소스 검색

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

Guo1B0 11 달 전
부모
커밋
8ec012029e
27개의 변경된 파일916개의 추가작업 그리고 422개의 파일을 삭제
  1. 2 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/api.ts
  2. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/index.vue
  3. 2 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/components/relatedProducts/relatedProducts.vue
  4. 3 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/api.ts
  5. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/api.ts
  6. 4 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/attachment.vue
  7. 61 8
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/information.vue
  8. 18 8
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/stageSetting.vue
  9. 57 22
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue
  10. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/api.ts
  11. 120 44
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/attachment.vue
  12. 3 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/deteleTables.vue
  13. 164 28
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/information.vue
  14. 13 33
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/operationRecord.vue
  15. 170 57
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/relatedBusiness.vue
  16. 1 43
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/relatedTasks.vue
  17. 8 9
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/detail/index.vue
  18. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/index.vue
  19. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue
  20. 5 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ProductController.java
  21. 25 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/SalesOrderController.java
  22. 129 91
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserWithBeisenController.java
  23. 15 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  24. 65 47
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  25. 1 2
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  26. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json
  27. 44 14
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

+ 2 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/api.ts

@@ -56,8 +56,8 @@ export const TASK_TYPE_FIELD: {
   {
     type: "2",
     field: "orderId",
-    valueIndex: "value",
-    labelIndex: "label",
+    valueIndex: "id",
+    labelIndex: "orderName",
   },
   {
     type: "3",

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/index.vue

@@ -178,7 +178,7 @@ watch(() => props.editForm, (val) => {
   post(ALL_ORDERS, { pageIndex: -1, pageSize: -1 }).then(({ data }) => {
     orderData.value = data.record;//销售订单
     if (taskType == 2) {
-      taskTypeValueData.value = data;
+      taskTypeValueData.value = data.record;
     }
   })
   get(ALL_CLUE, {}).then(({ data }) => {

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

@@ -64,7 +64,7 @@ import { ref, reactive, onMounted, inject, watchEffect } from "vue";
 const props = defineProps<{
     productTableList: any,
     height?: string,
-    productTableListValue: any
+    productTableListValue?: any
 }>()
 
 const productTable: any = ref([{}])
@@ -118,7 +118,7 @@ function returnData() {
     if (jsonstr == json) {
         return false
     }
-    productTable.value.forEach(item => {
+    productTable.value.forEach((item: any) => {
         delete item.index
     });
     return productTable.value

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

@@ -2,6 +2,9 @@ export const SENDVCODE = "/user/sendVcode";     //发送验证码
 export const REGISTER = "/user/insertCompany";  //注册
 export const LOGIN = "/user/loginAdmin";        //登录
 export const IMPORTTIMELIST = "/sys-form/getExportTemplate" // 下载模板
+export const URL_UPLOADFILE = `/contacts-document/fileUpload` // 上传文件
+export const URLFILEDETELE = `/contacts-document/fileDelete` // 删除文件
+export const URL_REFNAME = `/contacts-document/reNameFile` // 文件重命名
 
 export const SEX: sexTYpe[] = [
     { label: "男", value: '1' },

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

@@ -20,6 +20,7 @@ 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 URL_SAVECONTACT = `/business-opportunity/saveContactsId`
 
 
 export const stageStatus = [

+ 4 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/attachment.vue

@@ -61,6 +61,7 @@ const attachmenttable = ref([])
 const information = ref<any>({})
 const renameDialogVisible = ref(false)
 const renameVal = ref('')
+const uploadRef = ref<any>()
 
 // 下载文件
 function fileDownload(item: any) {
@@ -106,7 +107,9 @@ async function httpUploadFile(param: UploadRequestOptions) {
     const formData = new FormData();
     formData.append('file', param.file)
     formData.append('id', bussinessId)
-    const res = await uploadFile(UPLOADFILEFILE, formData)
+    const res = await uploadFile(UPLOADFILEFILE, formData).finally(() => {
+        uploadRef.value.clearFiles()
+    })
     if (res.code == 'ok') {
         globalPopup?.showSuccess(res.msg || '')
         emits('refreshData');

+ 61 - 8
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/information.vue

@@ -3,9 +3,10 @@
         <div class="flex justify-between">
             <div class="title">基本信息</div>
             <div>
-                <el-button type="primary">关联联系人</el-button>
+                <el-button type="primary" @click="associateContact()" v-if="!information.cuntactsId">关联联系人</el-button>
                 <el-button type="primary" @click="claimBusiness()" v-if="!information.customerId">认领</el-button>
-                <el-button type="primary" @click="showVisible('transferBusinessVisible')" v-else>转移</el-button>
+                <el-button type="primary" @click="showVisible('transferBusinessVisible')"
+                    v-if="information.customerId">转移</el-button>
                 <el-button type="primary" @click="showVisible('editBusinessVisible')">编辑</el-button>
             </div>
         </div>
@@ -69,7 +70,8 @@
                 <div class="flex justify-between items-center border-b pb-3 dialog-header">
                     <h4 :id="titleId">{{ '转移商机' }}</h4>
                     <div>
-                        <el-button type="primary" :loading="allLoading.transferBusinessLoading" @click="transferBusiness()">转移</el-button>
+                        <el-button type="primary" :loading="allLoading.transferBusinessLoading"
+                            @click="transferBusiness()">转移</el-button>
                         <el-button @click="allVisible.transferBusinessVisible = false">取消</el-button>
                     </div>
                 </div>
@@ -84,16 +86,39 @@
                 <div class="pl-3 text-[#e94a4a]">转移后,将看不到此商机</div>
             </div>
         </el-dialog>
+
+        <!-- 关联 -->
+        <el-dialog v-model="allVisible.saveContactVisible" width="600" :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.saveContactLoading"
+                            @click="saveAssociateContact()">关联</el-button>
+                        <el-button @click="allVisible.saveContactVisible = false">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="scroll-bar m-6">
+                <div class="flex mb-4">
+                    <div class="w-20 flex items-center justify-end pr-4">联系人:</div>
+                    <el-select v-model="contactsId" placeholder="请选择" class="flex1">
+                        <el-option v-for="item in contactsList" :key="item.value" :label="item.label" :value="item.value" />
+                    </el-select>
+                </div>
+            </div>
+        </el-dialog>
     </div>
 </template>
 <script lang="ts" setup>
 import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
 import { GenerateForm } from '@zmjs/form-design';
 import { get, post } from '@/utils/request';
-import { BATCHTRANSFER, GETGENERATEFOEM, GETPERSONNEL, UPDATEINSET } from '../api';
+import { BATCHTRANSFER, GETGENERATEFOEM, GETPERSONNEL, UPDATEINSET, URL_SAVECONTACT } from '../api';
 import { formatDateTime } from '@/utils/times';
 import { confirmAction } from '@/utils/tools';
 import { useStore } from '@/store/index'
+import { URL_GETALL } from '@/pages/contacts/api';
 
 const { userInfo } = useStore()
 const globalPopup = inject<GlobalPopup>('globalPopup')
@@ -107,20 +132,49 @@ const transferValue = ref('')
 const transferOptions = ref<personnelInterface[]>([])
 const generateFormValue = ref({})
 const generateForm = ref<typeof GenerateForm>() // 自定义表单dom
+const contactsId = ref('')
+const contactsList = ref<optionType[]>([])
 const allVisible = reactive({
     editBusinessVisible: false,
-    transferBusinessVisible: false
+    transferBusinessVisible: false,
+    saveContactVisible: false
 })
 const allLoading = reactive({
     editBusinessLoading: false,
     businessSaveLading: false,
-    transferBusinessLoading: false
+    transferBusinessLoading: false,
+    saveContactLoading: false
 })
 const generateFormData = ref({
     config: {},
     list: []
 }) // 自定义表单数据
 
+function associateContact() {
+    contactsId.value = ''
+    getContactList()
+    showVisible('saveContactVisible')
+}
+
+function getContactList() {
+    post(URL_GETALL, { customerId: information.value.customerId }).then(({ data }) => {
+        contactsList.value = data.map((item: any) => {
+            return { value: item.id, label: item.name }
+        })
+    })
+}
+
+function saveAssociateContact() {
+    allLoading.saveContactLoading = false
+    post(URL_SAVECONTACT, { id: information.value.id, contactsId: contactsId.value }).then(() => {
+        globalPopup?.showSuccess('关联成功')
+        closeVisible('saveContactVisible')
+        emits('refreshData')
+    }).finally(() => {
+        allLoading.saveContactLoading = false
+    })
+}
+
 function transferBusiness() {
     const ids = information.value?.id
     const inchargerId = information.value?.inchargerName ? transferValue.value : userInfo.id
@@ -222,5 +276,4 @@ onMounted(() => {
             line-height: 1.5;
         }
     }
-}
-</style>
+}</style>

+ 18 - 8
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/stageSetting.vue

@@ -6,7 +6,7 @@
                     <h4 :id="titleId">阶段设置</h4>
                     <div>
                         <el-button type="primary" @click="addStage(false)">新增</el-button>
-                        <el-button type="primary" @click="saveState()" v-loading="allLoading.saveLoading">保存</el-button>
+                        <el-button type="primary" @click="saveState()" :loading="allLoading.saveLoading">保存</el-button>
                         <el-button @click="cancel()">取消</el-button>
                     </div>
                 </div>
@@ -139,7 +139,7 @@ function editState(flag: boolean) {
         globalPopup?.showWarning('请输入阶段名称')
         return
     }
-    const listIndex = stageTableList.value.findIndex((item: stageFormType) => item.name == stageForm.name)
+    const listIndex = stageTableList.value.findIndex((item: stageFormType) => item.seq == stageForm.seq)
     const newStage = {
         ...stageForm,
         plan: stageForm.plan,
@@ -158,14 +158,19 @@ function editState(flag: boolean) {
 
 function addStage(item: any) {
     const row = JSON.parse(JSON.stringify(item))
+    console.log(item)
     if (!item) {
         resetStage()
     } else {
-        Object.assign(stageForm, {
+        let newData: any = {
             name: row.name,
             plan: row.plan,
-            seq: row.seq
-        })
+            seq: row.seq,
+            ...(row.id && { id: row.id }),
+            ...(row.companyId && { companyId: row.companyId }),
+            ...(row.isFinish && { isFinish: row.isFinish })
+        }
+        Object.assign(stageForm, newData)
     }
     allVisible.editVisible = true
 }
@@ -173,11 +178,16 @@ function addStage(item: any) {
 function resetStage() {
     let newData = JSON.parse(JSON.stringify(stageTableList.value))
     let maxnum = newData.sort((a: any, b: any) => { return b.seq - a.seq; })[0];
-    Object.assign(stageForm, {
+    console.log(maxnum)
+    let formVal = {
         name: '',
         plan: 0,
-        seq: +maxnum + 1
-    })
+        seq: +maxnum.seq + 1
+    }
+    delete stageForm.id
+    delete stageForm.isFinish
+    Object.assign(stageForm, formVal);
+    console.log(stageForm, '<=== 新增的数据', formVal)
 }
 
 function moveStage(index: number, stageType: moveStageType) {

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

@@ -47,7 +47,7 @@
     <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="flex justify-end pb-3">
-          <el-button type="primary" @click="showVisible('newBusinessisible')">新建商机</el-button>
+          <el-button type="primary" @click="editNewBusiness(false)">新建商机</el-button>
           <el-button type="primary" @click="showVisible('batchTransferVisible')"
             :disabled="batchTableData.length <= 0">批量转移</el-button>
           <el-button type="primary" @click="batchDeteleItem()" :disabled="batchTableData.length <= 0">批量删除</el-button>
@@ -60,16 +60,17 @@
           <el-table ref="businessTableRef" :data="businessTable" border v-loading="allLoading.businessTableLading"
             @selection-change="changeBatch" style="width: 100%;height: 100%;">
             <el-table-column type="selection" width="55" />
-            <el-table-column v-for="(item, index) in tableColumn" :prop="item.prop" :label="item.label" :key="index" :width="item.width">
+            <el-table-column v-for="(item, index) in tableColumn" :prop="item.prop" :label="item.label" :key="index"
+              :width="item.width">
               <template #default="scope">
-                <el-button link type="primary" size="large" @click="dealWithTableColumn(scope.row, item.eventName)" v-if="item.eventName">{{scope.row[item.prop]}}</el-button>
-                <template v-else>{{scope.row[item.prop]}}</template>
+                <el-button link type="primary" size="large" @click="dealWithTableColumn(scope.row, item.eventName)"
+                  v-if="item.eventName">{{ scope.row[item.prop] }}</el-button>
+                <template v-else>{{ scope.row[item.prop] }}</template>
               </template>
             </el-table-column>
             <el-table-column label="操作" fixed="right" width="200">
               <template #default="scope">
-                <el-button link type="primary" size="large"
-                  @click="editShowVisible('newBusinessisible', scope.row)">编辑</el-button>
+                <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="danger" size="large"
                   @click="businessDeteleItem(scope.row.id, scope.row.name)">删除</el-button>
@@ -98,10 +99,12 @@
           </div>
         </div>
       </template>
-      <div class="h-[60vh] overflow-y-auto scroll-bar pt-3">
-        <GenerateForm ref="generateForm" :data="generateFormData" />
+      <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" />
+        <RelatedProducts ref="relatedProductsRef" :productTableList="productTableList"
+          :productTableListValue="productTableListValue" />
       </div>
     </el-dialog>
 
@@ -133,7 +136,8 @@
         <div class="flex justify-between items-center border-b pb-3 dialog-header">
           <h4 :id="titleId">导入产品</h4>
           <div class="flex">
-            <el-upload class="upload-demo mr-3" :limit="1" :show-file-list="false" accept=".xlsx" :http-request="importBusiness">
+            <el-upload class="upload-demo mr-3" :limit="1" :show-file-list="false" accept=".xlsx"
+              :http-request="importBusiness">
               <el-button type="primary" :loading="allLoading.importLoading">导入</el-button>
             </el-upload>
             <el-button @click="allVisible.importVisible = false">取消</el-button>
@@ -142,7 +146,8 @@
       </template>
       <div class="p-8">
         <div class="ml-4 mr-4">
-          <div class="flex items-center">1、点击下载 <el-link type="primary" @click="downloadTemplate(MODURL, '商机导入模板.xlsx')">商机导入模板.xlsx</el-link></div>
+          <div class="flex items-center">1、点击下载 <el-link type="primary"
+              @click="downloadTemplate(MODURL, '商机导入模板.xlsx')">商机导入模板.xlsx</el-link></div>
           <div class="mt-4">2、填写excel文件、商机名称、商机金额、商机阶段必填</div>
         </div>
       </div>
@@ -182,9 +187,11 @@ const router = useRouter()
 const globalPopup = inject<GlobalPopup>('globalPopup')
 const businessTableRef = ref<InstanceType<typeof ElTable>>() // 商机table dom
 const businessTotalTable = ref(0)
-const generateForm = ref<typeof GenerateForm>() // 自定义表单dom
+const businessTemplateRef = ref<typeof GenerateForm>() // 自定义表单dom
 const relatedProductsRef = ref<typeof RelatedProducts>()
-const generateFormData = ref({
+const businessTemplateValue = ref({})
+const businessTemplateKey = ref(1)
+const businessTemplate = ref({
   config: {},
   list: []
 }) // 自定义表单数据
@@ -196,6 +203,7 @@ const allLoading = reactive({
   transferLoading: false,
   importLoading: false,
   exoprtLoading: false,
+  generateFormLading: false
 })
 const allVisible = reactive({
   newBusinessisible: false,
@@ -233,10 +241,11 @@ const fixedData = reactive({
   Personnel: [] as personnelInterface[]
 })
 const productTableList = ref([])
+const productTableListValue = ref([])
 
 
 function editBusiness(visibles: boolean) {
-  generateForm.value?.getData().then((res: any) => {
+  businessTemplateRef.value?.getData().then((res: any) => {
     let productTableListData = relatedProductsRef?.value?.returnData()
     let newForm = {
       ...res,
@@ -257,9 +266,25 @@ function editBusiness(visibles: boolean) {
   })
 }
 
-function editShowVisible(type: keyof typeof allVisible, item: any) {
+function editNewBusiness(item: any) {
   console.log(item, '选择数据')
-  showVisible(type)
+  showVisible('newBusinessisible')
+  allLoading.generateFormLading = true
+  if (item) {
+    editProduct(item)
+    businessTemplateValue.value = item
+    allText.newBusinessisibleText = '编辑商机'
+  }
+  if (!item) {
+    businessTemplateValue.value = {}
+    productTableListValue.value = []
+    allText.newBusinessisibleText = '新建商机'
+  }
+  setTimeout(() => {
+    businessTemplateRef.value && businessTemplateRef.value.reset()
+    businessTemplateKey.value++
+    allLoading.generateFormLading = false
+  }, 500)
 }
 
 function newTask(item: any) {
@@ -336,7 +361,7 @@ async function importBusiness(param: UploadRequestOptions) {
 function exportBusinessTableList() {
   allLoading.exoprtLoading = true
   let valueForm = getFromValue(businessOpportunityForm)
-  post('接口名称', {...valueForm}).then((res) => {
+  post('接口名称', { ...valueForm }).then((res) => {
     downloadFile(res.data, '商机表导出.xlsx')
   }).finally(() => {
     allLoading.exoprtLoading = false
@@ -352,6 +377,17 @@ function changeBatch(flag: boolean = true) {
   }
 }
 
+function editProduct(row: any) {
+  const list = row.businessItemProductList.map((item: any) => {
+    const { id, productName, productCode, unit, unitName, typeName, type, price, inventory, orderProductDetail, num, discount, sealPrice, totalPrice } = item
+    return {
+      id, productId: id, productName, productCode, unit, unitName, typeName, type, price, inventory,
+      num, discount, sealPrice, totalPrice 
+    }
+  })
+  productTableListValue.value = list
+}
+
 function showVisible(type: keyof typeof allVisible) { // 显示弹窗
   allVisible[type] = true
 }
@@ -408,7 +444,7 @@ async function getSystemField() {
   fixedData.BusinessStage = (row.data || []).map((item: any) => {
     const { name, id, seq } = item
     return { name, id, seq }
-  }).sort(function (a: any, b: any) {return a.seq - b.seq;});
+  }).sort(function (a: any, b: any) { return a.seq - b.seq; });
 
   const { data } = await post(GETPERSONNEL, {})
   fixedData.Personnel = data.map((item: any) => {
@@ -419,7 +455,7 @@ async function getSystemField() {
   })
 
   const res = await get(GETGENERATEFOEM)
-  generateFormData.value = JSON.parse(res.data[0].config)
+  businessTemplate.value = JSON.parse(res.data[0].config)
 }
 
 function toBusinessTableDetail(row: any) {
@@ -430,7 +466,7 @@ function toBusinessTableDetail(row: any) {
 }
 
 function dealWithTableColumn(row: any, eventName: string) {
-  if(eventName == 'toClueTableDetail') {
+  if (eventName == 'toClueTableDetail') {
     toBusinessTableDetail(row)
   }
 }
@@ -474,5 +510,4 @@ onMounted(() => {
     font-size: 18px;
     line-height: 24px;
   }
-}
-</style>
+}</style>

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

@@ -17,6 +17,7 @@ export const URL_DETELEITEM = `${URL}/confirmDeleteContacts`
 export const URL_RESTORE = `${URL}/returnContacts`
 export const URL_GETALL = `${URL}/getAllContacts`
 export const URL_GETDETAIL = `${URL}/getContactsDetail`
+export const URL_TRANSFERCONTACTS = `${URL}/transferContacts`
 
 export const actionButtons: any[] = [
     { text: '新建联系人' },

+ 120 - 44
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/attachment.vue

@@ -3,64 +3,140 @@
         <div class="flex justify-between">
             <div class="title">附件</div>
             <div>
-                <el-button type="primary">上传</el-button>
+                <el-upload ref="uploadRef" :http-request="httpUploadFile" :limit="1" :show-file-list="false"
+                    element-loading-text="正在上传" :loading="allLoading.uploadFileLoading">
+                    <template #trigger>
+                        <el-button type="primary">上传</el-button>
+                    </template>
+                </el-upload>
             </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
             <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="documentName" label="附件名称" width="180" />
+                <el-table-column prop="size" label="附件大小" width="120" />
+                <el-table-column prop="creatorName" label="上传人" width="120" />
+                <el-table-column prop="indate" label="上传时间" width="180" />
                 <el-table-column label="操作" width="180" fixed="right">
                     <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="operation(scope.row)">重命名</el-button>
+                        <el-button link type="danger" size="large" @click="fileDetele(scope.row)">删除</el-button>
                     </template>
                 </el-table-column>
             </el-table>
         </div>
+
+        <!-- 弹窗 -->
+        <el-dialog v-model="allVisible.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()" :loading="allLoading.saveLoading">保存</el-button>
+                        <el-button @click="allVisible.renameDialogVisible = false">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="pt-3">
+                <el-input v-model.trim="fileFormVal.name" style="width: 100%" class="pb-3" clearable />
+            </div>
+        </el-dialog>
     </div>
 </template>
 <script lang="ts" setup>
+import { post, uploadFile } from '@/utils/request';
+import { UploadRequestOptions } from 'element-plus';
 import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+import { URLFILEDETELE, URL_REFNAME, URL_UPLOADFILE } from '@/pages/api';
+import { downloadFile } from '@/utils/tools';
+
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const emits = defineEmits(['refreshData']);
+const props = defineProps<{
+    data: any
+}>()
+
+type fileFormVal = {
+    id?: string,
+    name?: string
+}
+
+const uploadRef = ref<any>()
+const information = ref<any>({})
+const attachmenttable = ref([])
+const fileTypeStr = ref('') // 文件重命名的类型
+const fileFormVal = ref<fileFormVal>({})
+const allLoading = reactive({
+    uploadFileLoading: false,
+    saveLoading: false
+})
+const allVisible = reactive({
+    renameDialogVisible: false
+})
+
+function saveEditClue() {
+    if(!fileFormVal.value.name) {
+        globalPopup?.showWarning('请输入文件名称')
+        return
+    }
+    allLoading.saveLoading = true
+    post(URL_REFNAME, {
+        fileId: fileFormVal.value.id,
+        newName: fileFormVal.value.name + '.' + fileTypeStr.value
+    }).then(() => {
+        allVisible.renameDialogVisible = false
+        globalPopup?.showSuccess('重命名成功')
+        emits('refreshData');
+    }).finally(() => {
+        allLoading.saveLoading = false
+    })
+}
+
+function operation(item: any) {
+    fileTypeStr.value = item.documentName.split('.').pop()
+    fileFormVal.value = {
+        id: item.id,
+        name: item.documentName.replace(/\.[^/.]+$/, '')
+    }
+    allVisible.renameDialogVisible = true
+}
+
+function fileDownload(item: any) {
+    downloadFile(`${item.url}`, item.documentName)
+}
+
+function fileDetele(item: any) {
+    post(URLFILEDETELE, { fileIds: item.id }).then(() => {
+        globalPopup?.showSuccess('删除成功')
+        emits('refreshData');
+    })
+}
+
+// 上传附件
+async function httpUploadFile(param: UploadRequestOptions) {
+    const id = information.value.id
+    const formData = new FormData();
+    formData.append('file', param.file)
+    formData.append('contactsId', id)
+    allLoading.uploadFileLoading = true
+    const res = await uploadFile(URL_UPLOADFILE, formData).finally(() => {
+        allLoading.uploadFileLoading = false
+        uploadRef.value.clearFiles()
+    })
+    if (res.code == 'ok') {
+        globalPopup?.showSuccess(res.msg || '')
+        emits('refreshData');
+        return
+    }
+    globalPopup?.showError(res.msg || '')
+    return res
+}
 
-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',
-}])
+watchEffect(() => {
+    const { data } = props
+    information.value = data
+    attachmenttable.value = data.contactsDocumentList || []
+});
 </script>
 <style scoped lang="scss"></style>

+ 3 - 3
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/deteleTables.vue

@@ -3,7 +3,7 @@
         top="10vh">
         <template #header="{ close, titleId, titleClass }">
             <div class="flex justify-between items-center border-b pb-3 dialog-header">
-                <h4 :id="titleId">商机回收站</h4>
+                <h4 :id="titleId">联系人回收站</h4>
                 <div>
                     <el-button type="primary" v-loading="allLoading.batchRecoveryLoading" :disabled="batchTableData.length == 0"
                         @click="batchOperation('恢复')">批量恢复</el-button>
@@ -118,8 +118,8 @@ function getTableList() {
     allLoading.tableLoading = true
     post(URL_RECYCLELIST, { ...tableForm }).then((res) => {
         if (res.code == 'ok') {
-            const { data, total } = res.data
-            deteleBusinessTable.value = data.map((item: any) => {
+            const { records, total } = res.data
+            deteleBusinessTable.value = records.map((item: any) => {
                 return {
                     ...item,
                     expectedTransactionDate: formatDate(new Date(item.expectedTransactionDate))

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

@@ -3,8 +3,9 @@
         <div class="flex justify-between">
             <div class="title">基本信息</div>
             <div>
-                <el-button type="primary">转移</el-button>
-                <el-button type="primary">编辑</el-button>
+                <el-button type="primary" v-if="!info.ownerId">认领</el-button>
+                <el-button type="primary" v-else @click="operationCli(false)">转移</el-button>
+                <el-button type="primary" @click="editInfo(info)">编辑</el-button>
             </div>
         </div>
         <div class="form flex flex-wrap justify-between">
@@ -13,54 +14,189 @@
                 <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ item.value }}</div>
             </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" @click="editContactsSave()"
+                            :loading="allLoading.editContactsSaveLoading">保存</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>
+
+        <el-dialog v-model="allVisible.transferVisible" width="600" :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.operationText }}</h4>
+                    <div>
+                        <el-button type="primary" :loading="allLoading.transferLoading"
+                            @click="transferBusiness(true)">转移</el-button>
+                        <el-button @click="allVisible.transferVisible = false">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="scroll-bar m-6">
+                <div class="flex mb-4">
+                    <div class="w-20 flex items-center justify-end pr-4">转移至:</div>
+                    <el-select v-model="transferValue" placeholder="请选择" class="flex1">
+                        <el-option v-for="item in transferOptions" :key="item.value" :label="item.label"
+                            :value="item.value" />
+                    </el-select>
+                </div>
+                <div class="pl-3 text-[#e94a4a]">转移后,将看不到此联系人</div>
+            </div>
+        </el-dialog>
     </div>
 </template>
 <script lang="ts" setup>
 import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+import { GenerateForm } from '@zmjs/form-design';
+import { getFromValue, getTemplateKey } from '@/utils/tools';
+import { GETGENERATEFOEM, GETPERSONNEL, URL_TRANSFERCONTACTS, URL_UPLOAD } from '../api';
+import { get, post } from '@/utils/request';
 
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const emits = defineEmits(['refreshData']);
 const props = defineProps<{
     data: any
 }>()
-
+const allLoading = reactive({
+    contactsTemplateRefLoading: false,
+    editContactsSaveLoading: false,
+    transferLoading: false
+})
+const allVisible = reactive({
+    editContactsVisible: false,
+    transferVisible: false
+})
+const allText = reactive({
+    operationText: '认领联系人'
+})
+const contactsTemplate = ref({
+    list: [],
+    config: {}
+})
+const contactsTemplateValue = ref({})
+const contactsTemplateRef = ref<typeof GenerateForm>()
+const contactsTemplateRefKey = ref(1)
 const info: any = ref({})
+const transferValue = ref('')
+const transferOptions = ref<optionType[]>([])
+
+function operationCli(flag: boolean) {
+    transferValue.value = flag ? '' : info.value.ownerId
+    allText.operationText = flag ? '认领联系人' : '转移联系人'
+    showVisible('transferVisible')
+}
+
+function transferBusiness(flag: boolean) {
+    const url = flag ? URL_TRANSFERCONTACTS : ''
+    const formVal = flag ? { id: info.value.id, ownerId: transferValue.value } : {}
+    allLoading.transferLoading = true
+    post(url, { ...formVal }).then((_res) => {
+        closeVisible('transferVisible')
+        globalPopup?.showSuccess('转移成功')
+        emits('refreshData')
+    }).finally(() => {
+        allLoading.transferLoading = false
+    })
+}
+
+function editInfo(row: any) {
+    showVisible('editContactsVisible')
+    const templateKey = getTemplateKey(contactsTemplate.value.list)
+    const formVal: templateKey = { id: row.id }
+    for (let i in templateKey) {
+        if (row[templateKey[i]] || row[templateKey[i]] == 0) {
+            formVal[templateKey[i]] = templateKey[i] == 'sex' ? row[templateKey[i]] + '' : row[templateKey[i]]
+        }
+    }
+    setTemplateVal(formVal)
+}
+
+function editContactsSave(flag: boolean = false) {
+    contactsTemplateRef.value?.getData().then((res: any) => {
+        let formVal = getFromValue({ ...contactsTemplateValue.value, ...res })
+        allLoading.editContactsSaveLoading = true
+        post(URL_UPLOAD, { ...formVal }).then((_res) => {
+            allVisible.editContactsVisible = flag
+            globalPopup?.showSuccess('保存成功')
+            emits('refreshData')
+        }).finally(() => {
+            allLoading.editContactsSaveLoading = false
+        })
+    }).catch((_err: any) => {
+        console.log(_err)
+        globalPopup?.showError('请填写完整')
+    })
+}
+
+function setTemplateVal(val: any = {}) {
+    contactsTemplateValue.value = val
+    allLoading.contactsTemplateRefLoading = true
+    setTimeout(() => {
+        contactsTemplateRefKey.value++
+        allLoading.contactsTemplateRefLoading = false
+    }, 1000);
+}
+
+function showVisible(type: keyof typeof allVisible) {
+    allVisible[type] = true
+}
+
+function closeVisible(type: keyof typeof allVisible) {
+    allVisible[type] = false
+}
 
 const formItems = reactive([
-    { label: '联系人', key: 'productCode', value: '', labelClass: 'w-20 text-right text-gray-500', width: '48%' },
+    { label: '联系人', key: 'name', 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: 'typeName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '邮箱', key: 'unitName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '职务', key: 'price', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '性别', key: 'unit', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '地址', key: 'status', 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: 'position', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
+    { label: '性别', key: 'sexValue', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
+    { label: '地址', key: 'address', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
     { label: '负责人', key: 'inchargerName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
     { label: '创建人', key: 'creatorName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
     { label: '创建时间', key: 'createTime', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '备注', key: 'descs', value: '', labelClass: 'w-22 text-right text-gray-500', width: '100%' },
+    { label: '备注', key: 'remark', value: '', labelClass: 'w-22 text-right text-gray-500', width: '100%' },
 ])
 
 watchEffect(() => {
-
+    const { data } = props
+    info.value = data
+    formItems.forEach(item => {
+        item.value = info.value[item.key];
+    });
 });
 
+async function getSystemField() {
+    const { data } = await post(GETPERSONNEL, {})
+    transferOptions.value = data.map((item: any) => {
+        const { id, name, phone, jobNumber } = item
+        return {
+            value: id,
+            label: name
+        }
+    })
+
+    const datas = await get(GETGENERATEFOEM)
+    contactsTemplate.value = JSON.parse(datas.data[0].config)
+}
+
 // 生命周期钩子
 onMounted(async () => {
-    info.value = {
-        productCode: '联系的人',
-        productName: '客户名称',
-        typeName: '电话号码',
-        unitName: '邮箱地址',
-        price: '职务',
-        unit: '性别',
-        status: 1,
-        inchargerName: '负责人姓名',
-        creatorName: '创建人姓名',
-        createTime: '创建时间',
-        descs: '备注信息'
-    };
-
-    formItems.forEach(item => {
-        item.value = info.value[item.key];
-    });
+    getSystemField()
 });
 </script>
 <style scoped lang="scss">

+ 13 - 33
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/operationRecord.vue

@@ -5,45 +5,25 @@
         </div>
         <div class="flex-1 overflow-auto pt-5">
             <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="operateDate" label="操作时间" width="150" />
+                <el-table-column prop="operateName" label="操作人" width="120" />
+                <el-table-column prop="msg" label="操作内容" />
             </el-table>
         </div>
     </div>
 </template>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+const props = defineProps<{
+    data: any
+}>()
 
-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',
-},])
+const operationRecordtable = ref([])
+
+watchEffect(() => {
+    const { data } = props
+    operationRecordtable.value = data.contactsLogList || []
+});
 // 生命周期钩子
 onMounted(() => {
 });

+ 170 - 57
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/relatedBusiness.vue

@@ -3,78 +3,191 @@
         <div class="flex justify-between">
             <div class="title">相关商机</div>
             <div>
-                <el-button type="primary">新建商机</el-button>
+                <el-button type="primary" @click="addBusiness()">新建商机</el-button>
             </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
-            <el-table :data="relatedTaskstable" border style="width: 100%;height: 100%;">
-                <el-table-column prop="taskName" label="商机名称">
+            <el-table :data="relatedTaskstable" border height="300" style="width: 100%;">
+                <el-table-column prop="name" label="商机名称">
                     <template #default="scope">
-                        <el-button link type="primary" size="large">{{
-                            scope.row.taskName
+                        <el-button link type="primary" size="large" @click="toBusDetal(scope.row)">{{
+                            scope.row.name
                         }}</el-button>
                     </template>
                 </el-table-column>
-                <el-table-column prop="priority" label="客户名称" width="130" />
-                <el-table-column prop="status" label="负责人" width="130" />
-                <el-table-column prop="executor" label="商机金额" width="130" />
-                <el-table-column prop="startTime" label="预计成交时间" width="130" />
-                <el-table-column prop="endTime" label="商机阶段" width="130" />
-                <el-table-column prop="endTime" label="创建人" width="130" />
-                <el-table-column prop="endTime" label="创建时间" width="130" />
-                <el-table-column prop="endTime" label="修改时间" width="130" />
+                <el-table-column prop="customerName" label="客户名称" width="130" />
+                <el-table-column prop="inchargerName" label="负责人" width="130" />
+                <el-table-column prop="amountOfMoney" label="商机金额" width="130" />
+                <el-table-column prop="expectedTransactionDate" label="预计成交时间" width="170" />
+                <el-table-column prop="stageValue" label="商机阶段" width="130" />
+                <el-table-column prop="creatorName" label="创建人" width="130" />
+                <el-table-column prop="createTime" label="创建时间" width="130" />
+                <el-table-column prop="modifyTime" label="修改时间" width="130" />
             </el-table>
         </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()"
+                            :loading="allLoading.businessSaveLading">保存</el-button>
+                        <el-button @click="closeVisible('newBusinessisible')">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="h-[60vh] overflow-y-auto scroll-bar pt-3" v-loading="allLoading.generateFormLading">
+                <GenerateForm ref="businessTemplateRef" :data="businessTemplate" :value="businessTemplateValue"
+                    :key="businessTemplateKey" />
+                <div>相关产品</div>
+                <RelatedProducts ref="relatedProductsRef" :productTableList="productTableList" />
+            </div>
+        </el-dialog>
     </div>
 </template>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+import { GenerateForm } from '@zmjs/form-design';
+import { get, post } from '@/utils/request';
+import { useRouter, useRoute } from "vue-router";
+
+import RelatedProducts from '@/components/relatedProducts/relatedProducts.vue'
+import { formatDateTime } from '@/utils/times';
+import { GETGENERATEFOEM, UPDATEINSET } from '@/pages/business/api';
+import { GETTABLELIST } from '@/pages/product/api';
+
+const router = useRouter()
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const emits = defineEmits(['refreshData']);
+const props = defineProps<{
+    data: any
+}>()
+
+const information = ref<any>({})
+const relatedTaskstable = ref([])
+const businessTemplateRef = ref<typeof GenerateForm>() // 自定义表单dom
+const relatedProductsRef = ref<typeof RelatedProducts>()
+const productTableList = ref([])
+const businessTemplateValue = ref({})
+const businessTemplateKey = ref(1)
+const businessTemplate = ref({
+    config: {},
+    list: []
+}) // 自定义表单数据
+const allLoading = reactive({
+    newBusinessSaveLading: false,
+    businessSaveLading: false,
+    generateFormLading: false
+})
+const allVisible = reactive({
+    newBusinessisible: false
+})
+
+function toBusDetal(row: any) {
+    router.push({
+        path: `/business/detail`,
+        query: { id: row.id }
+    })
+}
+
+function editBusiness() {
+    businessTemplateRef.value?.getData().then((res: any) => {
+        let productTableListData = relatedProductsRef?.value?.returnData()
+        let newForm = {
+            ...res,
+            expectedTransactionDate: res.expectedTransactionDate ? formatDateTime(new Date(res.expectedTransactionDate)) : '',
+            businessItemProductList: productTableListData ? JSON.stringify(productTableListData) : []
+        }
+        allLoading.businessSaveLading = true
+        post(UPDATEINSET, { ...businessTemplateValue.value, ...newForm }).then((_res) => {
+            allVisible.newBusinessisible = false
+            globalPopup?.showSuccess('保存成功')
+            emits('refreshData')
+        }).finally(() => {
+            allLoading.businessSaveLading = false
+        })
+    }).catch((_err: any) => {
+        console.log(_err)
+        globalPopup?.showError('请填写完整')
+    })
+}
+
+function addBusiness() {
+    showVisible('newBusinessisible')
+    allLoading.generateFormLading = true
+    businessTemplateValue.value = {
+        customerId: information.value.customId,
+        contactsId: information.value.id
+    }
+    setTimeout(() => {
+        businessTemplateRef.value && businessTemplateRef.value.reset()
+        businessTemplateKey.value++
+        allLoading.generateFormLading = false
+    }, 500)
+}
+
+function showVisible(type: keyof typeof allVisible) { // 显示弹窗
+    allVisible[type] = true
+}
+
+function closeVisible(type: keyof typeof allVisible) {
+    allVisible[type] = false
+}
+
+watchEffect(() => {
+    const { data } = props
+    information.value = data
+    relatedTaskstable.value = data.businessOpportunityList
+});
+
+async function getSystemField() {
+    const res = await get(GETGENERATEFOEM)
+    let config = JSON.parse(res.data[0].config)
+    config.list.forEach((item: any) => {
+        if (item.type == "grid") {
+            item.columns.forEach((column: any) => {
+                column.list.forEach((newColumn: any) => {
+                    if (newColumn.model == 'customerId' || newColumn.model == "contactsId") {
+                        newColumn.options.disabled = true
+                    }
+                })
+            })
+        }
+    })
+    businessTemplate.value = config
+}
 
-const relatedTaskstable = ref([{
-    taskName: '相关商机',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '相关商机',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '相关商机',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '相关商机',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '相关商机',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '相关商机',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}])
+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: ''
+                }
+            })
+        }
+    })
+}
 // 生命周期钩子
 onMounted(() => {
+    getSystemField()
+    getProductTableList()
 });
 </script>
 <style scoped lang="scss"></style>

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

@@ -27,49 +27,7 @@
 <script lang="ts" setup>
 import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
 
-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',
-}])
+const relatedTaskstable = ref([])
 // 生命周期钩子
 onMounted(() => {
 });

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

@@ -7,7 +7,7 @@
                 </el-link>
             </div>
             <div class="mr-8">
-                <el-select v-model="values" placeholder="请选择" style="width: 150px">
+                <el-select v-model="values" placeholder="请选择" style="width: 300px" @change="getDetail">
                     <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
                 </el-select>
             </div>
@@ -16,10 +16,10 @@
         <div class="flex-1 flex flex-col overflow-y-auto overflow-x-hidden scroll-bar" v-loading="pageLoading">
             <div class="w-full h-auto flex justify-between">
                 <div class="bg-white shadow-md rounded-md" style="width: 46%;">
-                    <Information :data="information" />
+                    <Information :data="information" @refreshData="getDetail" />
                 </div>
                 <div class="bg-white ml-2 shadow-md rounded-md flex-1">
-                    <Attachment :data="attachment" :information="information" />
+                    <Attachment :data="information" @refreshData="getDetail" />
                 </div>
             </div>
 
@@ -29,13 +29,13 @@
                     <Detailcompinents :data="relatedTasks" :information="information" :formTaskType="0" :filed="'contactsId'" :disabledList="['contactsId']" @refreshData="getDetail" />
                 </div>
                 <div class="bg-white ml-2 shadow-md rounded-md flex-1">
-                    <OperationRecord :data="operationRecord" />
+                    <OperationRecord :data="information" />
                 </div>
             </div>
 
             <div class="w-full h-auto flex justify-between mt-2">
                 <div class="bg-white shadow-md rounded-md w-full">
-                    <RelatedBusiness :data="relatedBusiness" />
+                    <RelatedBusiness :data="information" @refreshData="getDetail" />
                 </div>
             </div>
         </div>
@@ -60,10 +60,7 @@ import RelatedBusiness from '../component/relatedBusiness.vue'
 const route = useRoute()
 const globalPopup = inject<GlobalPopup>('globalPopup')
 const information = ref({}) // 基本信息
-const attachment = ref([]) // 附件
 const relatedTasks = ref([]) // 相关任务
-const operationRecord = ref([]) // 操作记录
-const relatedBusiness = ref([]) // 相关商机
 const rowId = ref(+(route.query.id || ''))
 const values = ref<number | string>('')
 const options = ref<optionType[]>([])
@@ -72,7 +69,9 @@ const pageLoading = ref(false)
 function getDetail() {
     pageLoading.value = true
     post(URL_GETDETAIL, { id: rowId.value }).then((res) => {
-        console.log(res)
+        res.data.sexValue = res.data.sex === 1 ? '男' : '女'
+        information.value = res.data
+        relatedTasks.value = res.data.taskList
     }).finally(() => {
         pageLoading.value = false
     })

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

@@ -261,7 +261,7 @@ function contactsDeteleItem(value: string | number, label: string, batch: boolea
       changeBatch(false)
       getContactPerson()
     }).catch((err) => {
-      globalPopup?.showError(err.message)
+      globalPopup?.showError(err.msg)
     })
   })
 }

+ 1 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue

@@ -250,6 +250,7 @@ function editProduct(item: any) {
   }
   if (!item) {
     genereditForm.value = {}
+    allText.editClueText = '新建产品'
   }
   setTimeout(() => {
     generateForm.value && generateForm.value.reset()

+ 5 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ProductController.java

@@ -144,7 +144,11 @@ public class ProductController {
             List<Integer> idList = splitList.stream().map(i -> Integer.valueOf(i)).collect(Collectors.toList());
             int count = taskService.count(new LambdaQueryWrapper<Task>().in(Task::getProductId, idList));
             if(count>0){
-                msg.setError("当前产品已绑定到相关任务,删除失败");
+                msg.setError("存在已绑定到相关任务的产品,删除失败");
+                return msg;
+            }
+            if(orderProductDetailService.count(new LambdaQueryWrapper<OrderProductDetail>().in(OrderProductDetail::getOrderId,idList))>0){
+                msg.setError("存在关联订单的产品,删除失败");
                 return msg;
             }
             if(idList.size()>0){

+ 25 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/SalesOrderController.java

@@ -12,6 +12,7 @@ import com.management.platform.util.HttpRespMsg;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -160,6 +161,10 @@ public class SalesOrderController {
             List<String> splitList = Arrays.asList(idSplit);
             List<Integer> idList = splitList.stream().map(s -> Integer.valueOf(s)).collect(Collectors.toList());
             List<SalesOrder> orderList = salesOrderService.list(new LambdaQueryWrapper<SalesOrder>().in(SalesOrder::getId, idList));
+            if(orderProductDetailService.count(new LambdaQueryWrapper<OrderProductDetail>().in(OrderProductDetail::getOrderId,idList))>0){
+                msg.setError("存在关联产品的订单,删除失败");
+                return msg;
+            }
             orderList.forEach(o->{
                 o.setIsDelete(1);
             });
@@ -187,6 +192,26 @@ public class SalesOrderController {
         return msg;
     }
 
+    /**
+     * @Description:批量删除产品数据
+     * @Param: [ids]
+     * @return: com.management.platform.util.HttpRespMsg
+     * @Author: yurk
+     * @Date: 2024/5/21
+     */
+    @RequestMapping("/batchDeleteOrder")
+    public HttpRespMsg batchDeleteProduct(String ids){
+        HttpRespMsg msg=new HttpRespMsg();
+        if(!StringUtils.isEmpty(ids)){
+            String[] idsSplit = ids.split(",");
+            List<String> splitList = Arrays.asList(idsSplit);
+            List<Integer> idList = splitList.stream().map(i -> Integer.valueOf(i)).collect(Collectors.toList());
+            idList.add(-1);
+            salesOrderService.removeByIds(idList);
+        }
+        return msg;
+    }
+
 
     /**
      * 恢复订单(假删除 isDelete标记 1-->0)

+ 129 - 91
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserWithBeisenController.java

@@ -229,7 +229,12 @@ public class UserWithBeisenController {
                         List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
                                 && (a.getIntValue("ApproveStatus") == 2||a.getIntValue("ApproveStatus") == 1)).collect(Collectors.toList());
                         //加班数据可能存在结束日期是当前日期的情况的情况
-                        BigDecimal overTimeBigDecimal = new BigDecimal(0);
+                        BigDecimal overTimeBigDecimal;
+                        if(workDay){
+                            overTimeBigDecimal = new BigDecimal(0);
+                        }else {
+                            overTimeBigDecimal = new BigDecimal(8);
+                        }
                         for (JSONObject o : overTimeList) {
                             //存在开始日期为当前日期的数据以及结束日期为当天日期的数据 分开计算
                             if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(localDate)){
@@ -238,16 +243,18 @@ public class UserWithBeisenController {
                                     //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
                                     if(max.get().isAfter(LocalTime.parse("19:00:00",df4))){
                                         //判断打卡时间是不是大于19:00 大于才算加班 通过打卡计算加班时长 与加班单作比较 取小
-                                        Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max.get());
-                                        //如果结束时间大于13:00
-                                        if(max.get().isAfter(LocalTime.parse("13:00:00",df4))){
-                                            timeDurantion.minusHours(1);
-                                        }
-                                        //如果结束时间大于18:00
-                                        if(max.get().isAfter(LocalTime.parse("18:00:00",df4))){
-                                            timeDurantion.minusMinutes(30);
-                                        }
-                                        long l = timeDurantion.toMinutes() / 60;
+                                        Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max.get());
+//                                        //如果结束时间大于13:00
+//                                        if(max.get().isAfter(LocalTime.parse("13:00:00",df4))){
+//                                            timeDurantion=timeDurantion.minusHours(1);
+//                                        }
+//                                        //如果结束时间大于18:00
+//                                        if(max.get().isAfter(LocalTime.parse("18:00:00",df4))){
+//                                            timeDurantion=timeDurantion.minusMinutes(30);
+//                                        }
+                                        BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
+                                        decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                        double l = decimal.doubleValue();
                                         if(l<o.getDouble("OverTimeDuration")){
                                             overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
                                         }else {
@@ -259,18 +266,22 @@ public class UserWithBeisenController {
                                     LocalDateTime start = LocalDateTime.parse(o.getString("StartDate"), df1);
                                     LocalDateTime stop = start.toLocalDate().atTime(LocalTime.MAX);
                                     Duration duration = Duration.between(start, stop);
-                                    if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
-                                        duration.minusHours(1);
-                                    }
-                                    //如果结束时间大于18:00
-                                    if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
-                                        duration.minusMinutes(30);
-                                    }
-                                    long l = duration.toMinutes() / 60;
+//                                    if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
+//                                        duration=duration.minusHours(1);
+//                                    }
+//                                    //如果结束时间大于18:00
+//                                    if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
+//                                        duration=duration.minusMinutes(30);
+//                                    }
+                                    BigDecimal decimal = new BigDecimal(duration.toMinutes());
+                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                    double l = decimal.doubleValue();
                                     if(max.get().isAfter(LocalTime.parse("19:00:00",df4))){
                                         //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                        Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max.get());
-                                        long l1 = timeDurantion.toMinutes() / 60;
+                                        Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max.get());
+                                        BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
+                                        decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                        double l1 = decimal1.doubleValue();
                                         if(l1<l){
                                             overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1));
                                         }else {
@@ -284,16 +295,18 @@ public class UserWithBeisenController {
                                     //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
                                     if(max.get().isAfter(LocalTime.parse("19:00:00",df4))){
                                         //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                        Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max.get());
-                                        //如果结束时间大于13:00
-                                        if(max.get().isAfter(LocalTime.parse("13:00:00",df4))){
-                                            timeDurantion.minusHours(1);
-                                        }
-                                        //如果结束时间大于18:00
-                                        if(max.get().isAfter(LocalTime.parse("18:00:00",df4))){
-                                            timeDurantion.minusMinutes(30);
-                                        }
-                                        long l = timeDurantion.toMinutes() / 60;
+                                        Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max.get());
+//                                        //如果结束时间大于13:00
+//                                        if(max.get().isAfter(LocalTime.parse("13:00:00",df4))){
+//                                            timeDurantion=timeDurantion.minusHours(1);
+//                                        }
+//                                        //如果结束时间大于18:00
+//                                        if(max.get().isAfter(LocalTime.parse("18:00:00",df4))){
+//                                            timeDurantion=timeDurantion.minusMinutes(30);
+//                                        }
+                                        BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
+                                        decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                        double l = decimal.doubleValue();
                                         if(l<o.getDouble("OverTimeDuration")){
                                             overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
                                         }else {
@@ -305,19 +318,23 @@ public class UserWithBeisenController {
                                     LocalDateTime stop = LocalDateTime.parse(o.getString("StopDate"), df1);
                                     LocalDateTime start = stop.toLocalDate().atTime(LocalTime.MIN);
                                     Duration duration = Duration.between(start, stop);
-                                    //如果结束时间大于13:00
-                                    if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
-                                        duration.minusHours(1);
-                                    }
-                                    //如果结束时间大于18:00
-                                    if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
-                                        duration.minusMinutes(30);
-                                    }
-                                    long l = duration.toMinutes() / 60;
+//                                    //如果结束时间大于13:00
+//                                    if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
+//                                        duration=duration.minusHours(1);
+//                                    }
+//                                    //如果结束时间大于18:00
+//                                    if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
+//                                        duration=duration.minusMinutes(30);
+//                                    }
+                                    BigDecimal decimal = new BigDecimal(duration.toMinutes());
+                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                    double l = decimal.doubleValue();
                                     if(max.get().isAfter(LocalTime.parse("19:00:00",df4))){
                                         //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                        Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max.get());
-                                        long l1 = timeDurantion.toMinutes() / 60;
+                                        Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max.get());
+                                        BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
+                                        decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                        double l1 = decimal1.doubleValue();
                                         if(l1<l){
                                             overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1));
                                         }else {
@@ -332,10 +349,12 @@ public class UserWithBeisenController {
                             workTime= workTime+overTimeBigDecimal.doubleValue();
                         }else {
                             //非工作日加班 根据实际打卡时长 比较 加班单时长
-                            if((between.toMinutes()/60)>overTimeBigDecimal.doubleValue()){
+                            BigDecimal decimal = new BigDecimal(between.toMinutes());
+                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                            if((decimal.doubleValue())>overTimeBigDecimal.doubleValue()){
                                 workTime= workTime+overTimeBigDecimal.doubleValue();
                             }else {
-                                workTime= workTime+(between.toMinutes()/60);
+                                workTime= workTime+(decimal.doubleValue());
                             }
                         }
                         //处理修改
@@ -428,10 +447,9 @@ public class UserWithBeisenController {
                     leaveSheet.setStatus(jsonObject.getString("ApproveStatus").equals("通过")?0:jsonObject.getString("Reason").equals("审批中")?1:2);
                     leaveSheet.setProcinstId(jsonObject.getString("VacationId"));
                     LeaveSheet one = leaveSheetService.getOne(new LambdaQueryWrapper<LeaveSheet>().eq(LeaveSheet::getProcinstId,leaveSheet.getProcinstId()).eq(LeaveSheet::getOwnerId, first.get().getId()).eq(LeaveSheet::getStartDate, leaveSheet.getStartDate()).eq(LeaveSheet::getEndDate, endDate));
-                    if(one!=null){
-                        leaveSheet.setId(one.getId());
+                    if(one==null){
+                        leaveSheetList.add(leaveSheet);
                     }
-                    leaveSheetList.add(leaveSheet);
                 }
             }
         }
@@ -511,7 +529,12 @@ public class UserWithBeisenController {
                 List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
                         && (a.getIntValue("ApproveStatus") == 2||a.getIntValue("ApproveStatus") == 1)).collect(Collectors.toList());
                 //加班数据可能存在结束日期是当前日期的情况的情况
-                BigDecimal overTimeBigDecimal = new BigDecimal(0);
+                BigDecimal overTimeBigDecimal;
+                if(workDay){
+                    overTimeBigDecimal = new BigDecimal(0);
+                }else {
+                    overTimeBigDecimal = new BigDecimal(8);
+                }
                 LocalDate localDate = LocalDate.parse(createDate, df);
                 for (JSONObject o : overTimeList) {
                     //存在开始日期为当前日期的数据以及结束日期为当天日期的数据 分开计算
@@ -521,16 +544,19 @@ public class UserWithBeisenController {
                             //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
                             if(max.isAfter(LocalTime.parse("19:00:00",df4))){
                                 //判断打卡时间是不是大于19:00 大于才算加班 通过打卡计算加班时长 与加班单作比较 取小
-                                Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max);
-                                //如果结束时间大于13:00
-                                if(max.isAfter(LocalTime.parse("13:00:00",df4))){
-                                    timeDurantion.minusHours(1);
-                                }
-                                //如果结束时间大于18:00
-                                if(max.isAfter(LocalTime.parse("18:00:00",df4))){
-                                    timeDurantion.minusMinutes(30);
-                                }
-                                long l = timeDurantion.toMinutes() / 60;
+                                Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max);
+//                                //如果结束时间大于13:00
+//                                if(max.isAfter(LocalTime.parse("13:00:00",df4))){
+//                                    timeDurantion=timeDurantion.minusHours(1);
+//                                }
+//                                //如果结束时间大于18:00
+//                                if(max.isAfter(LocalTime.parse("18:00:00",df4))){
+//                                    timeDurantion=timeDurantion.minusMinutes(30);
+//                                }
+                                System.out.println(timeDurantion.toMinutes());
+                                BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
+                                decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                double l = decimal.doubleValue();
                                 if(l<o.getDouble("OverTimeDuration")){
                                     overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
                                 }else {
@@ -542,18 +568,22 @@ public class UserWithBeisenController {
                             LocalDateTime start = LocalDateTime.parse(o.getString("StartDate"), df1);
                             LocalDateTime stop = start.toLocalDate().atTime(LocalTime.MAX);
                             Duration duration = Duration.between(start, stop);
-                            if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
-                                duration.minusHours(1);
-                            }
-                            //如果结束时间大于18:00
-                            if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
-                                duration.minusMinutes(30);
-                            }
-                            long l = duration.toMinutes() / 60;
+//                            if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
+//                                duration=duration.minusHours(1);
+//                            }
+//                            //如果结束时间大于18:00
+//                            if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
+//                                duration=duration.minusMinutes(30);
+//                            }
+                            BigDecimal decimal = new BigDecimal(duration.toMinutes());
+                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                            double l = decimal.doubleValue();
                             if(max.isAfter(LocalTime.parse("19:00:00",df4))){
                                 //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max);
-                                long l1 = timeDurantion.toMinutes() / 60;
+                                Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max);
+                                BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
+                                decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                double l1 = decimal1.doubleValue();
                                 if(l1<l){
                                     overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1));
                                 }else {
@@ -567,16 +597,18 @@ public class UserWithBeisenController {
                             //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
                             if(max.isAfter(LocalTime.parse("19:00:00",df4))){
                                 //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max);
-                                //如果结束时间大于13:00
-                                if(max.isAfter(LocalTime.parse("13:00:00",df4))){
-                                    timeDurantion.minusHours(1);
-                                }
-                                //如果结束时间大于18:00
-                                if(max.isAfter(LocalTime.parse("18:00:00",df4))){
-                                    timeDurantion.minusMinutes(30);
-                                }
-                                long l = timeDurantion.toMinutes() / 60;
+                                Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max);
+//                                //如果结束时间大于13:00
+//                                if(max.isAfter(LocalTime.parse("13:00:00",df4))){
+//                                    timeDurantion=timeDurantion.minusHours(1);
+//                                }
+//                                //如果结束时间大于18:00
+//                                if(max.isAfter(LocalTime.parse("18:00:00",df4))){
+//                                    timeDurantion=timeDurantion.minusMinutes(30);
+//                                }
+                                BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
+                                decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                double l = decimal.doubleValue();
                                 if(l<o.getDouble("OverTimeDuration")){
                                     overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
                                 }else {
@@ -588,19 +620,23 @@ public class UserWithBeisenController {
                             LocalDateTime stop = LocalDateTime.parse(o.getString("StopDate"), df1);
                             LocalDateTime start = stop.toLocalDate().atTime(LocalTime.MIN);
                             Duration duration = Duration.between(start, stop);
-                            //如果结束时间大于13:00
-                            if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
-                                duration.minusHours(1);
-                            }
-                            //如果结束时间大于18:00
-                            if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
-                                duration.minusMinutes(30);
-                            }
-                            long l = duration.toMinutes() / 60;
+//                            //如果结束时间大于13:00
+//                            if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
+//                                duration=duration.minusHours(1);
+//                            }
+//                            //如果结束时间大于18:00
+//                            if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
+//                                duration=duration.minusMinutes(30);
+//                            }
+                            BigDecimal decimal = new BigDecimal(duration.toMinutes());
+                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                            double l = decimal.doubleValue();
                             if(max.isAfter(LocalTime.parse("19:00:00",df4))){
                                 //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max);
-                                long l1 = timeDurantion.toMinutes() / 60;
+                                Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max);
+                                BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
+                                decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                double l1 = decimal1.doubleValue();
                                 if(l1<l){
                                     overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1));
                                 }else {
@@ -615,10 +651,12 @@ public class UserWithBeisenController {
                     workTime= workTime+overTimeBigDecimal.doubleValue();
                 }else {
                     //非工作日加班 根据实际打卡时长 比较 加班单时长
-                    if((between.toMinutes()/60)>overTimeBigDecimal.doubleValue()){
+                    BigDecimal decimal = new BigDecimal(between.toMinutes());
+                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                    if((decimal.doubleValue())>overTimeBigDecimal.doubleValue()){
                         workTime= workTime+overTimeBigDecimal.doubleValue();
                     }else {
-                        workTime= workTime+(between.toMinutes()/60);
+                        workTime= workTime+(decimal.doubleValue());
                     }
                 }
                 //处理修改

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

@@ -5663,19 +5663,30 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     }
                 }
                 Department finalDept = dept;
-                Optional<User> manager = userList.stream().filter(u -> u.getId().equals(finalDept.getManagerId())).findFirst();
+
+                String managerName = null;
+                if (finalDept != null) {
+                    User manageUser = null;
+                    Optional<User> manager = userList.stream().filter(u -> u.getId().equals(finalDept.getManagerId())).findFirst();
+                    if (manager.isPresent()) {
+                        manageUser = manager.get();
+                    }
+                    if (manageUser != null) {
+                        managerName = manageUser.getName();
+                    }
+                }
                 if(needCorpWxTranslate){
                     item.add("$userName="+(map.get("corpwxUserId")==null?"":map.get("corpwxUserId"))+"$");
                     item.add(departmentService.exportWxDepartment(dept,departments));
-                    item.add(manager.isPresent()?("$userName="+manager.get().getName()+"$"):"");
+                    item.add(managerName != null?("$userName="+managerName+"$"):"");
                 }else if(dingding!=null&&dingding.getContactNeedTranslate()==1){
                     item.add("$userName="+(map.get("name")==null?"":map.get("name"))+"$");
                     item.add(departmentService.exportDdDepartment(dept,departments));
-                    item.add(manager.isPresent()?("$userName="+manager.get().getName()+"$"):"");
+                    item.add(managerName != null?("$userName="+managerName+"$"):"");
                 }else  {
                     item.add((String) map.get("name"));
                     item.add(departmentService.getSupDepartment(dept,departments));
-                    item.add(manager.isPresent()?manager.get().getName():"");
+                    item.add(managerName != null?managerName:"");
                 }
                 item.add((String) map.get("projectCode"));
                 item.add((String) map.get("project"));

+ 65 - 47
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -2180,7 +2180,12 @@ public class TimingTask {
                         List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
                                 && (a.getIntValue("ApproveStatus") == 2||a.getIntValue("ApproveStatus") == 1)).collect(Collectors.toList());
                         //加班数据可能存在结束日期是当前日期的情况的情况
-                        BigDecimal overTimeBigDecimal = new BigDecimal(0);
+                        BigDecimal overTimeBigDecimal;
+                        if(workDay){
+                            overTimeBigDecimal = new BigDecimal(0);
+                        }else {
+                            overTimeBigDecimal = new BigDecimal(8);
+                        }
                         for (JSONObject o : overTimeList) {
                             //存在开始日期为当前日期的数据以及结束日期为当天日期的数据 分开计算
                             if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(localDate)){
@@ -2189,16 +2194,18 @@ public class TimingTask {
                                     //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
                                     if(max.get().isAfter(LocalTime.parse("19:00:00",df4))){
                                         //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                        Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max.get());
-                                        //如果结束时间大于13:00
-                                        if(max.get().isAfter(LocalTime.parse("13:00:00",df4))){
-                                            timeDurantion.minusHours(1);
-                                        }
-                                        //如果结束时间大于18:00
-                                        if(max.get().isAfter(LocalTime.parse("18:00:00",df4))){
-                                            timeDurantion.minusMinutes(30);
-                                        }
-                                        long l = timeDurantion.toMinutes() / 60;
+                                        Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max.get());
+//                                        //如果结束时间大于13:00
+//                                        if(max.get().isAfter(LocalTime.parse("13:00:00",df4))){
+//                                            timeDurantion.minusHours(1);
+//                                        }
+//                                        //如果结束时间大于18:00
+//                                        if(max.get().isAfter(LocalTime.parse("18:00:00",df4))){
+//                                            timeDurantion.minusMinutes(30);
+//                                        }
+                                        BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
+                                        decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                        double l = decimal.doubleValue();
                                         if(l<o.getDouble("OverTimeDuration")){
                                             overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
                                         }else {
@@ -2210,18 +2217,22 @@ public class TimingTask {
                                     LocalDateTime start = LocalDateTime.parse(o.getString("StartDate"), df1);
                                     LocalDateTime stop = start.toLocalDate().atTime(LocalTime.MAX);
                                     Duration duration = Duration.between(start, stop);
-                                    if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
-                                        duration.minusHours(1);
-                                    }
-                                    //如果结束时间大于18:00
-                                    if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
-                                        duration.minusMinutes(30);
-                                    }
-                                    long l = duration.toMinutes() / 60;
+//                                    if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
+//                                        duration.minusHours(1);
+//                                    }
+//                                    //如果结束时间大于18:00
+//                                    if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
+//                                        duration.minusMinutes(30);
+//                                    }
+                                    BigDecimal decimal = new BigDecimal(duration.toMinutes());
+                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                    double l = decimal.doubleValue();
                                     if(max.get().isAfter(LocalTime.parse("19:00:00",df4))){
                                         //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                        Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max.get());
-                                        long l1 = timeDurantion.toMinutes() / 60;
+                                        Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max.get());
+                                        BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
+                                        decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                        double l1 = decimal1.doubleValue();
                                         if(l1<l){
                                             overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1));
                                         }else {
@@ -2235,16 +2246,18 @@ public class TimingTask {
                                     //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
                                     if(max.get().isAfter(LocalTime.parse("19:00:00",df4))){
                                         //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                        Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max.get());
-                                        //如果结束时间大于13:00
-                                        if(max.get().isAfter(LocalTime.parse("13:00:00",df4))){
-                                            timeDurantion.minusHours(1);
-                                        }
-                                        //如果结束时间大于18:00
-                                        if(max.get().isAfter(LocalTime.parse("18:00:00",df4))){
-                                            timeDurantion.minusMinutes(30);
-                                        }
-                                        long l = timeDurantion.toMinutes() / 60;
+                                        Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max.get());
+//                                        //如果结束时间大于13:00
+//                                        if(max.get().isAfter(LocalTime.parse("13:00:00",df4))){
+//                                            timeDurantion.minusHours(1);
+//                                        }
+//                                        //如果结束时间大于18:00
+//                                        if(max.get().isAfter(LocalTime.parse("18:00:00",df4))){
+//                                            timeDurantion.minusMinutes(30);
+//                                        }
+                                        BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
+                                        decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                        double l = decimal.doubleValue();
                                         if(l<o.getDouble("OverTimeDuration")){
                                             overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
                                         }else {
@@ -2256,19 +2269,23 @@ public class TimingTask {
                                     LocalDateTime stop = LocalDateTime.parse(o.getString("StopDate"), df1);
                                     LocalDateTime start = stop.toLocalDate().atTime(LocalTime.MIN);
                                     Duration duration = Duration.between(start, stop);
-                                    //如果结束时间大于13:00
-                                    if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
-                                        duration.minusHours(1);
-                                    }
-                                    //如果结束时间大于18:00
-                                    if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
-                                        duration.minusMinutes(30);
-                                    }
-                                    long l = duration.toMinutes() / 60;
+//                                    //如果结束时间大于13:00
+//                                    if(stop.toLocalTime().isAfter(LocalTime.parse("13:00:00",df4))){
+//                                        duration.minusHours(1);
+//                                    }
+//                                    //如果结束时间大于18:00
+//                                    if(stop.toLocalTime().isAfter(LocalTime.parse("18:00:00",df4))){
+//                                        duration.minusMinutes(30);
+//                                    }
+                                    BigDecimal decimal = new BigDecimal(duration.toMinutes());
+                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                    double l = decimal.doubleValue();
                                     if(max.get().isAfter(LocalTime.parse("19:00:00",df4))){
                                         //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                        Duration timeDurantion = Duration.between(LocalTime.parse("19:00:00", df4), max.get());
-                                        long l1 = timeDurantion.toMinutes() / 60;
+                                        Duration timeDurantion = Duration.between(LocalTime.parse("18:00:00", df4), max.get());
+                                        BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
+                                        decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                        double l1 = decimal1.doubleValue();
                                         if(l1<l){
                                             overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1));
                                         }else {
@@ -2283,10 +2300,12 @@ public class TimingTask {
                             workTime= workTime+overTimeBigDecimal.doubleValue();
                         }else {
                             //非工作日加班 根据实际打卡时长 比较 加班单时长
-                            if((between.toMinutes()/60)>overTimeBigDecimal.doubleValue()){
+                            BigDecimal decimal = new BigDecimal(between.toMinutes());
+                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                            if((decimal.doubleValue())>overTimeBigDecimal.doubleValue()){
                                 workTime= workTime+overTimeBigDecimal.doubleValue();
                             }else {
-                                workTime= workTime+(between.toMinutes()/60);
+                                workTime= workTime+(decimal.doubleValue());
                             }
                         }
                         List<JSONObject> vacationList = vacationStream.filter(a ->{
@@ -2376,10 +2395,9 @@ public class TimingTask {
                     leaveSheet.setStatus(jsonObject.getString("ApproveStatus").equals("通过")?0:jsonObject.getString("Reason").equals("审批中")?1:2);
                     leaveSheet.setProcinstId(jsonObject.getString("VacationId"));
                     LeaveSheet one = leaveSheetService.getOne(new LambdaQueryWrapper<LeaveSheet>().eq(LeaveSheet::getOwnerId, first.get().getId()).eq(LeaveSheet::getStartDate, leaveSheet.getStartDate()).eq(LeaveSheet::getProcinstId,leaveSheet.getProcinstId()).eq(LeaveSheet::getEndDate, endDate));
-                    if(one!=null){
-                        leaveSheet.setId(one.getId());
+                    if(one==null){
+                        leaveSheetList.add(leaveSheet);
                     }
-                    leaveSheetList.add(leaveSheet);
                 }
             }
         }

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

@@ -896,8 +896,7 @@
         FROM user
         left join report on user.id = report.creator_id
         left join department on department.department_id = user.department_id
-        WHERE (report.state = 0 or report.state = 1)
-        and user.company_id = #{companyId} and (user.is_active=1 or(user.is_active=0 and user.inactive_date>=#{startDate}))
+        WHERE user.company_id = #{companyId} and (user.is_active=1 or(user.is_active=0 and user.inactive_date>=#{startDate}))
         <if test="deptIds != null">
             AND ((user.department_id in
             <foreach collection="deptIds" separator="," index="index" item="item" close=")" open="(">

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json

@@ -260,7 +260,7 @@
     "enterpriseWeChatReminder": "企业微信催填",
     "dingNingurgefilling": "钉钉催填",
     "weChatReminder": "微信催填",
-    "completedHours": "已填工时情况",
+    "completedHours": "工时填报情况",
     "unfilledPersonList": "未填人员列表",
     "missingDate": "未填日期",
     "attendanceData": "考勤数据",

+ 44 - 14
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -1426,12 +1426,18 @@
               <!-- 222 -->
             </div>
             <div>
+                <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 :subjectId="deptIdForHasReport" :size="'small'" :widthStr="'200'" :clearable="true" :subject="trandepartmentList" :radios="true" :distinction="'14'" @vueCasader="vueCasader" v-if="user.userNameNeedTranslate == 1" :selectNameChuan="$t('other.allDepartments')"></vueCascader>
                 <el-input style="float:left;width:22%" v-if="user.userNameNeedTranslate != '1'" v-model="searchKeyword" @keyup.enter.native="searchScreen(0)" class="input-with-select" :placeholder="$t('defaultText.pleaseEnterNametoSearch')" clearable="true" size="small">
                     <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: left; height:32px; padding-top:10px;">
+              <span style="width:20px;height:20px;background-color: orange;padding:5px 8px;">待审核</span>
+              <span style="width:20px;height:20px;background-color: #32CD32;padding:5px 8px;margin-left:10px;">已通过</span>
+              <span style="width:20px;height:20px;background-color: red;padding:5px 8px;margin-left:10px;">已驳回</span>
+              <span style="width:20px;height:20px;background-color: #E0E0E0;padding:5px 8px;margin-left:10px;">未提交</span>
             </div>
             <div style="float: right; vertical-align: middle;height:32px">
               <el-link
@@ -1441,6 +1447,7 @@
              >
             </div>
             
+            
           </div>
 
           <el-table ref="hasworkTbl"
@@ -1606,7 +1613,7 @@
             <div>
                 <div style="margin-top:10px;">
                     <el-cascader v-if="user.userNameNeedTranslate != 1" :size="'small'" v-model="deptIdForNoReport" placeholder="请选择部门" :options="departmentList" :props="{ checkStrictly: true, value: 'id' }" clearable style="width: 200px;" @change="showMonthNotWorkTime()"></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="showMonthNotWorkTime()"></vueCascader>
+                    <vueCascader :size="'small'" :widthStr="'200'" :clearable="true" :subject="trandepartmentList" :radios="true" :distinction="'15'" @vueCasader="vueCasader" v-if="user.userNameNeedTranslate == 1" :selectNameChuan="$t('other.allDepartments')"></vueCascader>
                     <el-input style="width:200px;margin-left: 15px" v-if="user.userNameNeedTranslate != '1'" @keyup.enter.native="searchScreen(1)" v-model="searchKeyword" class="input-with-select" :placeholder="$t('defaultText.pleaseEnterNametoSearch')" clearable="true" size="small">
                         <el-button slot="append" @click="searchScreen(1)" icon="el-icon-search"></el-button>
                     </el-input>
@@ -1694,12 +1701,12 @@
             </div>
             <div>
                 <div style="margin-top:10px;">
+                    <el-cascader v-if="user.userNameNeedTranslate != 1" :size="'small'" v-model="deptIdForReminder" placeholder="请选择部门" :options="departmentList" :props="{ checkStrictly: true, value: 'id' }" clearable style="width: 200px;" @change="showMonthWorkTimeReminder()"></el-cascader>
+                    <vueCascader :size="'small'" :widthStr="'200'" :clearable="true" :subject="trandepartmentList" :radios="true" :distinction="'16'" @vueCasader="vueCasader" v-if="user.userNameNeedTranslate == 1" :selectNameChuan="$t('other.allDepartments')"></vueCascader>
                     <el-input style="float:left;width:18%" v-if="user.userNameNeedTranslate != '1'" @keyup.enter.native="searchScreen(0)" v-model="searchKeyword" class="input-with-select" :placeholder="$t('defaultText.pleaseEnterNametoSearch')" clearable="true" size="small">
                         <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="deptIdForReminder" placeholder="请选择部门" :options="departmentList" :props="{ checkStrictly: true, value: 'id' }" clearable style="width: 200px;" @change="showMonthWorkTimeReminder()"></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="showMonthWorkTimeReminder()"></vueCascader>
                     <el-checkbox v-model="isReminder" @change="showMonthWorkTimeReminder()">是否异常</el-checkbox>
                 </div>
             </div>
@@ -2423,6 +2430,7 @@
 
                 notifySelList:[],
                 departmentList: [],
+                trandepartmentList:[],
 
                 approvalProcessDialog: false,
                 approvalProcessData: [],
@@ -2572,18 +2580,21 @@
 
                     const isWorkDate = filterData[0] && filterData[0].workingTime
                     const state = filterData[0] && filterData[0].state
-                    if (state == 1) {
+                    if (state == 0 || state == -1) {
+                        return "backgroundColor: orange"
+                    } else if (state == 1) {
                         //审核通过
                         return "backgroundColor: #32CD32"
                     } else if (state == 2) {
-                        return "backgroundColor: #FF0000"
+                        return "backgroundColor: red"
                     } else {
-                        if(isWorkDate < times) {
-                            return "backgroundColor: #FC3D49"
-                        }
-                        if(isWorkDate > times) {
-                            return "backgroundColor: #20a0ff"
-                        }
+                        return "backgroundColor: #E0E0E0"
+                        // if(isWorkDate < times) {
+                        //     return "backgroundColor: #FC3D49"
+                        // }
+                        // if(isWorkDate > times) {
+                        //     return "backgroundColor: #20a0ff"
+                        // }
                     }
                     
                 }
@@ -5278,6 +5289,7 @@
                         }
                         this.departmentList = JSON.parse(JSON.stringify(res.data))
                         var list = res.data , list1 = JSON.parse(JSON.stringify(res.data));
+                        this.trandepartmentList=this.changeArr(JSON.parse(JSON.stringify(res.data)))
                         // let noAllData = JSON.parse(JSON.stringify(res.data));
                         // if (this.user.role > 0) {
                             
@@ -8493,7 +8505,7 @@
                 this.workForm.domains[obj.idx].projectAuditorId = obj.id
             },
             vueCasader(obj) {
-                console.log(obj, '看看值')
+                console.log(obj, '看看值', this.departmentList)
                 if(obj.distinction == 1 && obj.item) {
                     let arr = []
                     arr.push(obj.item.value)
@@ -8504,6 +8516,24 @@
                     const { id, other } = obj
                     this.workForm.domains[other].reportTargetDeptId = id
                 }
+                if(obj.distinction == '14' && obj) {
+                    let arr = []
+                    arr.push(obj.id)
+                    this.deptIdForHasReport = arr
+                    this.showMonthWorkTime()
+                }
+                if(obj.distinction == '15' && obj) {
+                    let arr = []
+                    arr.push(obj.id)
+                    this.deptIdForNoReport = arr
+                    this.showMonthNotWorkTime()
+                }
+                if(obj.distinction == '16' && obj) {
+                    let arr = []
+                    arr.push(obj.id)
+                    this.deptIdForReminder = arr
+                    this.showMonthWorkTimeReminder()
+                }
             },
             //分页
             handleCurrentChange(val) {