瀏覽代碼

Merge remote-tracking branch 'origin/master'

Guo1B0 1 年之前
父節點
當前提交
e07906d7a7
共有 31 個文件被更改,包括 1247 次插入432 次删除
  1. 18 13
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/relatedProducts.vue
  2. 34 6
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue
  3. 16 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/api.ts
  4. 127 45
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/attachment.vue
  5. 199 23
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/information.vue
  6. 21 33
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/operationRecord.vue
  7. 17 47
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/products.vue
  8. 20 44
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/relatedBusiness.vue
  9. 78 39
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/detail/index.vue
  10. 168 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/deteleTables.vue
  11. 101 40
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue
  12. 1 6
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/detail/components/attachment.vue
  13. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue
  14. 3 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/styles/global.scss
  15. 2 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/request.ts
  16. 10 12
      fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/tools.ts
  17. 4 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  18. 88 12
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserWithBeisenController.java
  19. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/CompanyDingding.java
  20. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java
  21. 14 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  22. 57 9
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  23. 54 21
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/BeiSenUtils.java
  24. 2 14
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CompanyDingdingMapper.xml
  25. 0 25
      fhKeeper/formulahousekeeper/plugIn/form-design-master/src/components.d.ts
  26. 3 0
      fhKeeper/formulahousekeeper/timesheet/index.html
  27. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json
  28. 2 1
      fhKeeper/formulahousekeeper/timesheet/src/views/Home.vue
  29. 120 16
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  30. 37 10
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue
  31. 40 3
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue

+ 18 - 13
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/relatedProducts.vue

@@ -2,25 +2,25 @@
     <div>
     <div>
         <el-table ref="productTableRef" :data="productTable" border :row-class-name="tableRowClassName"
         <el-table ref="productTableRef" :data="productTable" border :row-class-name="tableRowClassName"
             @row-click="tableRowItem" style="width: 100%;height: 200px">
             @row-click="tableRowItem" style="width: 100%;height: 200px">
-            <el-table-column label="序号" width="80">
+            <el-table-column label="序号" width="60" align="center">
                 <template #default="scope">
                 <template #default="scope">
                     <span>{{ scope.$index + 1 }}</span>
                     <span>{{ scope.$index + 1 }}</span>
                 </template>
                 </template>
             </el-table-column>
             </el-table-column>
             <el-table-column prop="productName" label="产品名称" width="180">
             <el-table-column prop="productName" label="产品名称" width="180">
                 <template #default="scope">
                 <template #default="scope">
-                    <el-select v-model="productTable[scope.$index].productName" placeholder="请选择"
+                    <el-select v-model="productTable[scope.$index].productId" placeholder="请选择"
                         v-if="productTableIndex == scope.$index" clearable @clear="clearTableItem(scope.$index)"
                         v-if="productTableIndex == scope.$index" clearable @clear="clearTableItem(scope.$index)"
                         @change="selectChange(scope.$index, productTable[scope.$index].productName)">
                         @change="selectChange(scope.$index, productTable[scope.$index].productName)">
-                        <el-option v-for="item in productArrar" :key="item.id" :label="item.productName" :value="item.id" />
+                        <el-option v-for="item in productArrar" :key="item.productId" :label="item.productName" :value="item.productId" />
                     </el-select>
                     </el-select>
                     <span v-else>{{ productTable[scope.$index].productName }}</span>
                     <span v-else>{{ productTable[scope.$index].productName }}</span>
                 </template>
                 </template>
             </el-table-column>
             </el-table-column>
-            <el-table-column prop="productType" label="产品类型" width="180"></el-table-column>
-            <el-table-column prop="unit" label="单位" width="80"></el-table-column>
+            <el-table-column prop="typeName" label="产品类型" width="180"></el-table-column>
+            <el-table-column prop="unitName" label="单位" width="120"></el-table-column>
             <el-table-column prop="price" label="标准价格" width="120"></el-table-column>
             <el-table-column prop="price" label="标准价格" width="120"></el-table-column>
-            <el-table-column prop="stock" label="库存" width="80"></el-table-column>
+            <el-table-column prop="inventory" label="库存" width="80"></el-table-column>
             <el-table-column prop="sellingPrice" label="售价" width="180">
             <el-table-column prop="sellingPrice" label="售价" width="180">
                 <template #default="scope">
                 <template #default="scope">
                     <el-input-number v-model="productTable[scope.$index].sellingPrice" class="mx-4" :min="0" :max="100000000" controls-position="right" v-if="productTableIndex == scope.$index" />
                     <el-input-number v-model="productTable[scope.$index].sellingPrice" class="mx-4" :min="0" :max="100000000" controls-position="right" v-if="productTableIndex == scope.$index" />
@@ -39,7 +39,7 @@
                     <span v-else>{{ productTable[scope.$index].discount }}</span>
                     <span v-else>{{ productTable[scope.$index].discount }}</span>
                 </template>
                 </template>
             </el-table-column>
             </el-table-column>
-            <el-table-column prop="total" label="合计" width="180"></el-table-column>
+            <el-table-column prop="totalPrice" label="合计" width="180"></el-table-column>
             <el-table-column label="操作" fixed="right" width="120">
             <el-table-column label="操作" fixed="right" width="120">
                 <template #default="scope">
                 <template #default="scope">
                     <el-button link type="primary" size="large" @click.stop="addTableItem(scope.$index)">添加</el-button>
                     <el-button link type="primary" size="large" @click.stop="addTableItem(scope.$index)">添加</el-button>
@@ -52,18 +52,18 @@
 </template>
 </template>
   
   
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, inject } from "vue";
+import { ref, reactive, onMounted, inject, watchEffect } from "vue";
+
+const props = defineProps<{
+    productTableList: any,
+}>()
 
 
 const productTable: any = ref([{}])
 const productTable: any = ref([{}])
 const productTableIndex = ref(0) // 可以编辑索引
 const productTableIndex = ref(0) // 可以编辑索引
-const productArrar = ref([
-    { id: 1, productName: '产品1', productType: '类别1', unit: '台', price: '1122', stock: '100', sellingPrice: 0, quantity: 0, discount: 0, total: '' },
-    { id: 2, productName: '产品2', productType: '类别2', unit: '台', price: '2211', stock: '300', sellingPrice: 0, quantity: 0, discount: 0, total: '' },
-])
+const productArrar: any = ref([])
 
 
 function selectChange(index: number, val: number | string) {
 function selectChange(index: number, val: number | string) {
     let newObj = productArrar.value.find((item: any) => item.id == val)
     let newObj = productArrar.value.find((item: any) => item.id == val)
-    console.log(newObj)
     productTable.value.splice(index, 1, newObj)
     productTable.value.splice(index, 1, newObj)
 }
 }
 
 
@@ -87,6 +87,11 @@ function clearTableItem(index: number) {
 function deteleTableItem(index: number) {
 function deteleTableItem(index: number) {
     productTable.value.splice(index, 1)
     productTable.value.splice(index, 1)
 }
 }
+
+watchEffect(() => {
+    const { productTableList } = props
+    productArrar.value = productTableList || []
+});
 </script>
 </script>
   
   
 <style lang="scss" scoped></style>
 <style lang="scss" scoped></style>

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

@@ -109,9 +109,9 @@
         </div>
         </div>
       </template>
       </template>
       <div class="h-[60vh] overflow-y-auto scroll-bar">
       <div class="h-[60vh] overflow-y-auto scroll-bar">
-        <GenerateForm ref="generateForm" :data="generateFormData" />
+        <!-- <GenerateForm ref="generateForm" :data="generateFormData" /> -->
         <div>相关产品</div>
         <div>相关产品</div>
-        <RelatedProducts />
+        <RelatedProducts :productTableList="productTableList" />
       </div>
       </div>
     </el-dialog>
     </el-dialog>
   </div>
   </div>
@@ -122,6 +122,7 @@ import { ref, reactive, onMounted, inject } from "vue";
 import type { FormInstance, FormRules } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
 import { useRouter, useRoute } from "vue-router";
 import { useRouter, useRoute } from "vue-router";
 import { GETSYSFILED, MOD, GETPERSONNEL, GETGENERATEFOEM } from './api'
 import { GETSYSFILED, MOD, GETPERSONNEL, GETGENERATEFOEM } from './api'
+import { GETTABLELIST } from '@/pages/product/api'
 import { post, get } from "@/utils/request";
 import { post, get } from "@/utils/request";
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate } from '@/utils/tools'
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate } from '@/utils/tools'
 import { GenerateForm } from '@zmjs/form-design';
 import { GenerateForm } from '@zmjs/form-design';
@@ -166,13 +167,14 @@ const fixedData = reactive({
   BusinessStage: [] as fixedDataInterface[],
   BusinessStage: [] as fixedDataInterface[],
   Personnel: [] as personnelInterface[]
   Personnel: [] as personnelInterface[]
 })
 })
+const productTableList = ref([])
 
 
 
 
 function editBusiness() {
 function editBusiness() {
   generateForm.value?.getData().then((res: any) => {
   generateForm.value?.getData().then((res: any) => {
     console.log('正确')
     console.log('正确')
     console.log(res)
     console.log(res)
-  }).catch( (_err: any) => {
+  }).catch((_err: any) => {
     globalPopup?.showError('请填写完整')
     globalPopup?.showError('请填写完整')
   })
   })
 }
 }
@@ -214,14 +216,40 @@ async function getSystemField() {
 
 
 function toBusinessTableDetail(row: any) {
 function toBusinessTableDetail(row: any) {
   console.log('点击跳转详情')
   console.log('点击跳转详情')
-  router.push({ 
-    path: `${MOD}/detail`, 
-    query: { id: row.id } 
+  router.push({
+    path: `${MOD}/detail`,
+    query: { id: row.id }
+  })
+}
+
+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 {
+          productId: id,
+          productName,
+          productCode,
+          unit,
+          unitName,
+          price,
+          type,
+          typeName,
+          inventory,
+          quantity: '',
+          discount: '',
+          totalPrice: ''
+        }
+      })
+    }
   })
   })
 }
 }
 
 
 onMounted(() => {
 onMounted(() => {
   getSystemField()
   getSystemField()
+  getProductTableList()
 })
 })
 </script>
 </script>
 
 

+ 16 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/api.ts

@@ -1,8 +1,23 @@
 export const MOD = '/product'
 export const MOD = '/product'
+export const MODUCODE = 'Product'
 export const prefix = '/product'
 export const prefix = '/product'
+export const GETDOEMCODE = '/sys-form/getListByCode'
 export const GETSYSFILED = '/sys-dict/getListByCode'
 export const GETSYSFILED = '/sys-dict/getListByCode'
 export const GETPERSONNEL = '/user/getSimpleActiveUserList'
 export const GETPERSONNEL = '/user/getSimpleActiveUserList'
 export const GETTEMPLATE = `/sys-form/getListByCode${MOD}`
 export const GETTEMPLATE = `/sys-form/getListByCode${MOD}`
 export const GETTABLELIST = `${prefix}/list`
 export const GETTABLELIST = `${prefix}/list`
 export const ADDPRODUCT = `${prefix}/addOrUpdate`
 export const ADDPRODUCT = `${prefix}/addOrUpdate`
-export const ALLDETELE = `${prefix}/delete`
+export const ALLDETELE = `${prefix}/delete`
+export const UPLOADFILE = `${prefix}/importData`
+export const RECYCLELIST = `${prefix}/recycleList`
+export const DETERDETELE = `${prefix}/batchDeleteProduct`
+export const ROLLBACK = `${prefix}/batchRecoveryProduct`
+export const GETDETAIL = `${prefix}/detail`
+export const GETINCHARGER = `${prefix}/transferIncharger`
+export const GETBUSINESS = `${prefix}/businessListWithProduct`
+export const GETORDER = `${prefix}/orderWithProduct`
+export const UPLOADATTACHMENT = `/attachment/uploadAttachment`
+export const GETCENTERLIST = `/audit-log-center/list`
+export const GETATTACHMENT = `/attachment/attachmentList`
+export const FILEDETELE = `/attachment/delete`
+export const FILERENAME = `/attachment/rename`

+ 127 - 45
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/attachment.vue

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

File diff suppressed because it is too large
+ 199 - 23
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/information.vue


+ 21 - 33
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/operationRecord.vue

@@ -5,47 +5,35 @@
         </div>
         </div>
         <div class="flex-1 overflow-auto pt-5">
         <div class="flex-1 overflow-auto pt-5">
             <el-table :data="operationRecordtable" border style="width: 100%;height: 278px;">
             <el-table :data="operationRecordtable" border style="width: 100%;height: 278px;">
-                <el-table-column prop="operatingTime" label="操作时间" width="140" />
-                <el-table-column prop="operator" label="操作人" width="120" />
-                <el-table-column prop="operationContent" label="操作内容" />
+                <el-table-column prop="auditTime" label="操作时间" width="140" />
+                <el-table-column prop="auditorName" label="操作人" width="120" />
+                <el-table-column prop="auditorContent" label="操作内容" />
             </el-table>
             </el-table>
         </div>
         </div>
     </div>
     </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+
+const operationRecordtable = ref([])
+const information: any = ref({})
+
+const props = defineProps<{
+    data: any,
+}>()
+
+// 接收参数赋值
+function receiveAssignment(item: any) {
+    operationRecordtable.value = item.data
+}
+
+watchEffect(() => {
+    receiveAssignment(props)
+});
 
 
-const operationRecordtable = ref([{
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-},])
 // 生命周期钩子
 // 生命周期钩子
 onMounted(() => {
 onMounted(() => {
+    receiveAssignment(props)
 });
 });
 </script>
 </script>
 <style scoped lang="scss">
 <style scoped lang="scss">

+ 17 - 47
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/products.vue

@@ -2,9 +2,6 @@
     <div class="relatedTasks pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
     <div class="relatedTasks pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
         <div class="flex justify-between">
         <div class="flex justify-between">
             <div class="title">相关产品</div>
             <div class="title">相关产品</div>
-            <div>
-                <el-button type="primary">编辑产品</el-button>
-            </div>
         </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
         <div class="flex-1 overflow-auto pt-3">
             <el-table :data="relatedTaskstable" border style="width: 100%;height: 300px;">
             <el-table :data="relatedTaskstable" border style="width: 100%;height: 300px;">
@@ -34,53 +31,26 @@
     </div>
     </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+
+const relatedTaskstable = ref([])
+
+const props = defineProps<{
+    data: any
+}>()
+
+// 接收参数赋值
+function receiveAssignment(item: any) {
+    relatedTaskstable.value = item.data
+}
+
+watchEffect(() => {
+    receiveAssignment(props)
+});
 
 
-const relatedTaskstable = ref([{
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}])
 // 生命周期钩子
 // 生命周期钩子
 onMounted(() => {
 onMounted(() => {
+    receiveAssignment(props)
 });
 });
 </script>
 </script>
 <style scoped lang="scss">
 <style scoped lang="scss">

+ 20 - 44
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/relatedBusiness.vue

@@ -22,53 +22,29 @@
     </div>
     </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+
+const relatedTaskstable = ref([])
+const information: any = ref({})
+
+const props = defineProps<{
+    data: any,
+    information: any
+}>()
+
+// 接收参数赋值
+function receiveAssignment(item: any) {
+    relatedTaskstable.value = item.data
+    information.value = item.information
+}
+
+watchEffect(() => {
+    receiveAssignment(props)
+});
 
 
-const relatedTaskstable = ref([{
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}])
 // 生命周期钩子
 // 生命周期钩子
 onMounted(() => {
 onMounted(() => {
+    receiveAssignment(props)
 });
 });
 </script>
 </script>
 <style scoped lang="scss">
 <style scoped lang="scss">

+ 78 - 39
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/detail/index.vue

@@ -7,34 +7,34 @@
         </el-link>
         </el-link>
       </div>
       </div>
       <div class="mr-8">
       <div class="mr-8">
-        <el-select v-model="value" placeholder="请选择" style="width: 150px">
-          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+        <el-select v-model="value" placeholder="请选择" style="width: 150px" @change="getDetail(false)">
+          <el-option v-for="item in options" :key="item.id" :label="item.productName" :value="item.id" />
         </el-select>
         </el-select>
       </div>
       </div>
     </div>
     </div>
     <!-- 内容 -->
     <!-- 内容 -->
-    <div class="flex-1 flex flex-col overflow-y-auto overflow-x-hidden scroll-bar">
+    <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="w-full h-auto flex justify-between">
         <div class="bg-white shadow-md rounded-md" style="width: 46%;">
         <div class="bg-white shadow-md rounded-md" style="width: 46%;">
-          <Information />
+          <Information :data="information" @getInformationData="getInformationData" />
         </div>
         </div>
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
-          <Attachment />
+          <Attachment :data="attachment" :information="information" @getFileList="getFileList" />
         </div>
         </div>
       </div>
       </div>
 
 
       <div class="w-full h-auto flex justify-between mt-2">
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md" style="width: 65%;">
         <div class="bg-white shadow-md rounded-md" style="width: 65%;">
-          <RelatedBusiness />
+          <RelatedBusiness :data="relatedBusiness" :information="information" />
         </div>
         </div>
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
-          <OperationRecord />
+          <OperationRecord :data="operationRecord" />
         </div>
         </div>
       </div>
       </div>
 
 
       <div class="w-full h-auto flex justify-between mt-2">
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md w-full">
         <div class="bg-white shadow-md rounded-md w-full">
-          <Products />
+          <Products :data="products" />
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
@@ -45,6 +45,7 @@
 import { ref, reactive, onMounted, inject } from "vue";
 import { ref, reactive, onMounted, inject } from "vue";
 import type { FormInstance, FormRules } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
 import { Edit, ArrowLeft as IconView } from '@element-plus/icons-vue'
 import { Edit, ArrowLeft as IconView } from '@element-plus/icons-vue'
+import { useRoute } from "vue-router";
 import { backPath } from '../../../utils/tools'
 import { backPath } from '../../../utils/tools'
 
 
 import Information from '../component/information.vue'
 import Information from '../component/information.vue'
@@ -52,40 +53,78 @@ import Attachment from '../component/attachment.vue'
 import RelatedBusiness from '../component/relatedBusiness.vue';
 import RelatedBusiness from '../component/relatedBusiness.vue';
 import OperationRecord from '../component/operationRecord.vue';
 import OperationRecord from '../component/operationRecord.vue';
 import Products from '../component/products.vue';
 import Products from '../component/products.vue';
+import { GETBUSINESS, GETDETAIL, GETCENTERLIST, GETORDER, MODUCODE, GETATTACHMENT, GETTABLELIST } from "../api";
+import { post } from "@/utils/request";
+
+const route = useRoute()
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const addressParameters: any = ref(0) // 地址上的参数
+const information = ref({}) // 基本信息
+const attachment = ref([]) // 附件
+const relatedBusiness = ref([]) // 相关商机
+const operationRecord = ref([]) // 操作记录
+const products = ref([]) // 相关产品
+
+const pageLoading = ref(false)
 
 
 const value = ref('')
 const value = ref('')
-const stageStatusVal = ref('')
-const options = [
-  {
-    value: 'Option1',
-    label: 'Option1',
-  },
-  {
-    value: 'Option2',
-    label: 'Option2',
-  },
-  {
-    value: 'Option3',
-    label: 'Option3',
-  },
-  {
-    value: 'Option4',
-    label: 'Option4',
-  },
-  {
-    value: 'Option5',
-    label: 'Option5',
-  },
-]
-
-
-function handleScroll(event: any) { // 滚表横向滚动
-  if (event.deltaY) {
-    event.preventDefault();
-    const element = event.currentTarget;
-    element.scrollLeft += event.deltaY;
+const options: any = ref([])
+
+function getInformationData(val: any = false) {
+  const id = val ? val : addressParameters.value
+  post(GETDETAIL, { id }).then((res) => {
+    information.value = res.data
+  })
+}
+
+function getFileList(val: any = false) {
+  const id = val ? val : addressParameters.value
+  post(GETATTACHMENT, { moduleId: id, moduleCode: MODUCODE }).then((res) => {
+    attachment.value = res.data
+  })
+}
+
+async function getDetail(flag: boolean) {
+  try {
+    const id = flag ? addressParameters.value : value.value
+    pageLoading.value = true
+
+    await Promise.all([
+      getInformationData(id),
+      getFileList(id),
+      post(GETCENTERLIST, { id, moduleCode: MODUCODE }).then((res) => {
+        operationRecord.value = res.datag
+      }),
+      post(GETORDER, { id }).then((res) => {
+        products.value = res.data
+      }),
+      post(GETBUSINESS, { id }).then((res) => {
+        relatedBusiness.value = res.data
+      })
+    ])
+
+    pageLoading.value = false
+  } catch (error) {
+    pageLoading.value = false
+    console.log(error, '<==== 加载错误')
   }
   }
 }
 }
+
+function getProductList() {
+  post(GETTABLELIST, { pageIndex: -1, pageSize: -1 }).then((res) => {
+    const { record } = res.data
+    options.value = record
+  }).catch(() => {
+    globalPopup?.showError('产品列表获取失败')
+  })
+}
+
+onMounted(() => {
+  const { id } = route.query
+  addressParameters.value = id
+  getProductList()
+  getDetail(true)
+})
 </script>
 </script>
   
   
 <style lang="scss" scoped>
 <style lang="scss" scoped>
@@ -144,7 +183,7 @@ function handleScroll(event: any) { // 滚表横向滚动
     padding-bottom: 4px;
     padding-bottom: 4px;
   }
   }
 
 
-  .selectClas >>> .el-select__wrapper {
+  .selectClas>>>.el-select__wrapper {
     background-color: none !important;
     background-color: none !important;
     box-shadow: none !important;
     box-shadow: none !important;
   }
   }

+ 168 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/deteleTables.vue

@@ -0,0 +1,168 @@
+<template>
+    <el-dialog v-model="deteleClueDialogVisible" width="1000" :before-close="beForeCancel" :show-close="false" top="10vh">
+        <template #header="{ close, titleId, titleClass }">
+            <div class="flex justify-between items-center border-b pb-3 dialog-header">
+                <h4 :id="titleId">产品回收站</h4>
+                <div>
+                    <el-button type="primary" @click="batchRestore()"
+                        v-loading="allLoading.batchRecoveryLoading">批量恢复</el-button>
+                    <el-button type="primary" @click="batchDeletes()"
+                        v-loading="allLoading.batchDeteleLoading">批量删除</el-button>
+                    <el-button @click="cancel()">取消</el-button>
+                </div>
+            </div>
+        </template>
+        <div class="h-[60vh] flex flex-col">
+            <div class="flex-1 w-full overflow-hidden">
+                <el-table ref="clueTableRef" :data="deteleClueTable" border v-loading="allLoading.tableLoading"
+                    style="width: 100%;height: 100%;">
+                    <el-table-column type="selection" width="55" />
+                    <el-table-column prop="productCode" label="产品编号" width="180"></el-table-column>
+                    <el-table-column prop="productName" label="产品名称" width="180"></el-table-column>
+                    <el-table-column prop="typeName" label="产品类别" width="180"></el-table-column>
+                    <el-table-column prop="unitName" label="单位" width="180"></el-table-column>
+                    <el-table-column prop="price" label="标准价格(元)" width="180"></el-table-column>
+                    <el-table-column prop="inventory" label="库存" width="180"></el-table-column>
+                    <el-table-column prop="status" label="状态" width="180"></el-table-column>
+                    <el-table-column prop="inchargerName" label="负责人" width="190"></el-table-column>
+                    <el-table-column prop="creatorName" label="创建人" width="180"></el-table-column>
+                    <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
+                    <el-table-column label="操作" fixed="right" width="120">
+                        <template #default="scope">
+                            <el-button link type="primary" size="large" @click="restoreItemRow([scope.row])">恢复</el-button>
+                            <el-button link type="danger" size="large" @click="deteItemRow([scope.row])">删除</el-button>
+                        </template>
+                    </el-table-column>
+                </el-table>
+            </div>
+            <div class="flex justify-end pt-3">
+                <el-pagination layout="total, prev, pager, next, sizes" :page-size="tableForm.pageSize"
+                    @size-change="handleSizeChange" @current-change="handleCurrentChange" :total="clueTotalTable"
+                    :hide-on-single-page="true" />
+            </div>
+        </div>
+    </el-dialog>
+</template>
+<script lang="ts" setup>
+import { post } from '@/utils/request';
+import { ref, reactive, onMounted, watchEffect, watch, inject } from 'vue'
+import { DETERDETELE, RECYCLELIST, ROLLBACK } from './api';
+import { ElTable } from 'element-plus';
+import { confirmAction } from '@/utils/tools';
+
+const emits = defineEmits(['showDeteleProduct']);
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const deteleClueTable = ref([])
+const deteleClueDialogVisible = ref(false)
+const clueTotalTable = ref(0)
+const allLoading = reactive({
+    batchRecoveryLoading: false,
+    batchDeteleLoading: false,
+    tableLoading: false
+})
+
+const tableForm = reactive({
+    pageIndex: 1,
+    pageSize: 10
+})
+
+const clueTableRef = ref<InstanceType<typeof ElTable>>() // 产品table dom
+
+const props = defineProps<{
+    visibles: boolean
+}>()
+
+watch(() => props.visibles, (newVal) => {
+    deteleClueDialogVisible.value = newVal
+    if (newVal) {
+        getTableList()
+    }
+})
+
+function batchRestore() {
+    const data = clueTableRef.value && clueTableRef.value.getSelectionRows()
+    if (!data.length) {
+        globalPopup?.showWarning('请选择需要恢复的数据')
+        return
+    }
+    restoreItemRow(data)
+}
+
+function batchDeletes() {
+    const data = clueTableRef.value && clueTableRef.value.getSelectionRows()
+    if (!data.length) {
+        globalPopup?.showWarning('请选择需要删除的数据')
+        return
+    }
+    deteItemRow(data)
+}
+
+function deteItemRow(items: any[]) {
+    const ids = items.map((item: any) => item.id).join(',')
+    const str = items.map((item: any) => item.productName).join(',')
+    confirmAction(`确定${items.length > 1 ? '批量删除这些' : '删除'}【${str}】产品吗?`, '', 'warning').then(() => {
+        post(DETERDETELE, { ids }).then(res => {
+            if (res.code != 'ok') {
+                globalPopup?.showError(res.msg)
+                return
+            }
+            globalPopup?.showSuccess('删除成功')
+            getTableList()
+        })
+    })
+}
+
+function restoreItemRow(items: any[]) {
+    const ids = items.map((item: any) => item.id).join(',')
+    const str = items.map((item: any) => item.productName).join(',')
+    confirmAction(`确定${items.length > 1 ? '批量恢复这些' : '恢复'}【${str}】产品吗?`, '', 'warning').then(() => {
+        post(ROLLBACK, { ids }).then(res => {
+            if (res.code != 'ok') {
+                globalPopup?.showError(res.msg)
+                return
+            }
+            globalPopup?.showSuccess('恢复成功')
+            getTableList()
+        })
+    })
+}
+
+function getTableList() {
+    allLoading.tableLoading = true
+    post(RECYCLELIST, { ...tableForm }).then((res) => {
+        if (res.code == 'ok') {
+            const { record, total } = res.data
+            deteleClueTable.value = record
+            clueTotalTable.value = total
+        }
+    }).finally(() => {
+        allLoading.tableLoading = false
+    })
+}
+
+function handleSizeChange(val: number) {
+    tableForm.pageIndex = 1
+    tableForm.pageSize = val
+    getTableList()
+}
+
+function handleCurrentChange(val: number) {
+    tableForm.pageIndex = val
+    getTableList()
+}
+
+function cancel() {
+    emits('showDeteleProduct', false)
+}
+
+function beForeCancel(done: () => void) {
+    emits('showDeteleProduct', false)
+    done()
+}
+
+onMounted(() => {
+
+})
+
+</script>
+<style lang="scss" scoped></style>

+ 101 - 40
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue

@@ -39,10 +39,10 @@
     <div class="flex-1 p-5 overflow-auto">
     <div class="flex-1 p-5 overflow-auto">
       <div class="bg-white w-full h-full p-3 shadow-md rounded-md flex flex-col">
       <div class="bg-white w-full h-full p-3 shadow-md rounded-md flex flex-col">
         <div class="flex justify-end pb-3">
         <div class="flex justify-end pb-3">
-          <el-button type="primary" @click="editProduct(true)">新建产品</el-button>
-          <el-button type="primary">批量删除</el-button>
-          <el-button type="primary">回收站</el-button>
-          <el-button type="primary">导入</el-button>
+          <el-button type="primary" @click="editProduct(false)">新建产品</el-button>
+          <el-button type="primary" @click="batchDelete()">批量删除</el-button>
+          <el-button type="primary" @click="showDeteleProduct(true)">回收站</el-button>
+          <el-button type="primary" @click="dialogVisible.importVisible = true">导入</el-button>
           <el-button type="primary">导出</el-button>
           <el-button type="primary">导出</el-button>
         </div>
         </div>
         <div class="flex-1 w-full overflow-hidden">
         <div class="flex-1 w-full overflow-hidden">
@@ -57,17 +57,21 @@
                 }}</el-button>
                 }}</el-button>
               </template>
               </template>
             </el-table-column>
             </el-table-column>
-            <el-table-column prop="type" label="产品类别" width="180"></el-table-column>
-            <el-table-column prop="unit" label="单位" width="180"></el-table-column>
-            <el-table-column prop="price" label="标准价格" width="180"></el-table-column>
+            <el-table-column prop="typeName" label="产品类别" width="180"></el-table-column>
+            <el-table-column prop="unitName" label="单位" width="180"></el-table-column>
+            <el-table-column prop="price" label="标准价格(元)" width="180"></el-table-column>
             <el-table-column prop="inventory" label="库存" width="180"></el-table-column>
             <el-table-column prop="inventory" label="库存" width="180"></el-table-column>
-            <el-table-column prop="status" label="状态" width="180"></el-table-column>
-            <el-table-column prop="inchargerId" label="负责人" width="190"></el-table-column>
-            <el-table-column prop="creatorId" label="创建人" width="180"></el-table-column>
+            <el-table-column prop="status" label="状态" width="180">
+              <template #default="scope">
+                {{ scope.row.status == 1 ? '上架' : '下架' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="inchargerName" label="负责人" width="190"></el-table-column>
+            <el-table-column prop="creatorName" label="创建人" width="180"></el-table-column>
             <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
             <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
             <el-table-column label="操作" fixed="right" width="200">
             <el-table-column label="操作" fixed="right" width="200">
               <template #default="scope">
               <template #default="scope">
-                <el-button link type="primary" size="large">编辑</el-button>
+                <el-button link type="primary" size="large" @click.stop="editProduct(scope.row)">编辑</el-button>
                 <el-button link type="danger" size="large" @click.stop="deteleRow([scope.row])">删除</el-button>
                 <el-button link type="danger" size="large" @click.stop="deteleRow([scope.row])">删除</el-button>
               </template>
               </template>
             </el-table-column>
             </el-table-column>
@@ -75,7 +79,8 @@
         </div>
         </div>
         <div class="flex justify-end pt-3">
         <div class="flex justify-end pt-3">
           <el-pagination layout="total, prev, pager, next, sizes" :page-size="filterProductForm.pageSize"
           <el-pagination layout="total, prev, pager, next, sizes" :page-size="filterProductForm.pageSize"
-            @size-change="handleSizeChange" @current-change="handleCurrentChange" :total="productTableTotal" :hide-on-single-page="true" />
+            @size-change="handleSizeChange" @current-change="handleCurrentChange" :total="productTableTotal"
+            :hide-on-single-page="true" />
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
@@ -86,8 +91,8 @@
         <div class="flex justify-between items-center border-b pb-3 dialog-header">
         <div class="flex justify-between items-center border-b pb-3 dialog-header">
           <h4 :id="titleId">{{ allText.editClueText }}</h4>
           <h4 :id="titleId">{{ allText.editClueText }}</h4>
           <div>
           <div>
-            <el-button type="primary" @click="saveProductRow(true)" v-loading="allLoading.saveLoading">保存并新建</el-button>
-            <el-button type="primary" @click="saveProductRow(false)" v-loading="allLoading.saveLoading">保存</el-button>
+            <el-button type="primary" @click="saveProductRow(true)" :loading="allLoading.saveLoading">保存并新建</el-button>
+            <el-button type="primary" @click="saveProductRow(false)" :loading="allLoading.saveLoading">保存</el-button>
             <el-button @click="dialogVisible.editProductVisible = false">取消</el-button>
             <el-button @click="dialogVisible.editProductVisible = false">取消</el-button>
           </div>
           </div>
         </div>
         </div>
@@ -99,17 +104,40 @@
       </div>
       </div>
     </el-dialog>
     </el-dialog>
 
 
+    <el-dialog v-model="dialogVisible.importVisible" width="680" :show-close="false" top="10vh">
+      <template #header="{ close, titleId, titleClass }">
+        <div class="flex justify-between items-center border-b pb-3 dialog-header">
+          <h4 :id="titleId">导入产品</h4>
+          <div class="flex">
+            <el-upload class="upload-demo mr-3" :limit="1" :show-file-list="false" accept=".xlsx" :http-request="importProducts">
+              <el-button type="primary" :loading="allLoading.importLoading">导入</el-button>
+            </el-upload>
+            <el-button @click="dialogVisible.importVisible = false">取消</el-button>
+          </div>
+        </div>
+      </template>
+      <div class="p-8">
+        <div class="ml-4 mr-4">
+          <div class="flex items-center">1、点击下载 <el-link type="primary">产品导入模板.xlsx</el-link></div>
+          <div class="mt-4">2、填写excel文件、产品编号、产品名称、产品类别、标准价格、库存、状态必填</div>
+        </div>
+      </div>
+    </el-dialog>
+
+    <DeteleTables :visibles="dialogVisible.deteleProductDialogVisible" @showDeteleProduct="showDeteleProduct" />
+
   </div>
   </div>
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
 import { ref, reactive, onMounted, inject } from "vue";
 import { ref, reactive, onMounted, inject } from "vue";
-import { GETSYSFILED, MOD, GETPERSONNEL, GETTEMPLATE, GETTABLELIST, ADDPRODUCT, ALLDETELE } from './api'
+import { GETSYSFILED, MOD, GETPERSONNEL, GETTEMPLATE, GETTABLELIST, ADDPRODUCT, ALLDETELE, UPLOADFILE } from './api'
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, createTaskFromType, confirmAction } from '@/utils/tools'
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, createTaskFromType, confirmAction } from '@/utils/tools'
-import { FormInstance, FormRules, ElMessageBox, ElTable } from 'element-plus'
-import { post, get } from "@/utils/request";
+import { FormInstance, FormRules, ElMessageBox, ElTable, UploadRequestOptions } from 'element-plus'
+import { post, get, uploadFile } from "@/utils/request";
 import { useRouter, useRoute } from "vue-router";
 import { useRouter, useRoute } from "vue-router";
 import { GenerateForm } from '@zmjs/form-design';
 import { GenerateForm } from '@zmjs/form-design';
+import DeteleTables from "./deteleTables.vue";
 
 
 const router = useRouter()
 const router = useRouter()
 const globalPopup = inject<GlobalPopup>('globalPopup')
 const globalPopup = inject<GlobalPopup>('globalPopup')
@@ -128,12 +156,15 @@ const allLoading = reactive({
   productTableLading: false,
   productTableLading: false,
   generateFormLading: false,
   generateFormLading: false,
   saveLoading: false,
   saveLoading: false,
+  importLoading: false
 })
 })
 const dialogVisible = reactive({
 const dialogVisible = reactive({
   editProductVisible: false,
   editProductVisible: false,
   taskModalVisible: false,
   taskModalVisible: false,
   clueDialogVisible: false,
   clueDialogVisible: false,
-  deteleClueDialogVisible: false
+  deteleClueDialogVisible: false,
+  importVisible: false,
+  deteleProductDialogVisible: false
 })
 })
 const allText = reactive({
 const allText = reactive({
   editClueText: '新建产品',
   editClueText: '新建产品',
@@ -154,17 +185,31 @@ const genereditForm = ref({}) // 编辑表单
 const generateFormKey = ref(1)
 const generateFormKey = ref(1)
 
 
 // 方法定义
 // 方法定义
+function batchDelete() {
+  const data = productTableRef.value && productTableRef.value.getSelectionRows()
+  if (!data.length) {
+    globalPopup?.showWarning('请选择数据')
+    return
+  }
+  deteleRow(data)
+}
+
+function showDeteleProduct(flag: boolean) {
+  if(!flag) {
+    getProductTableList()
+  }
+  dialogVisible.deteleProductDialogVisible = flag
+}
+
 function deteleRow(items: any[]) {
 function deteleRow(items: any[]) {
   let ids = items.map(item => item.id).join(',')
   let ids = items.map(item => item.id).join(',')
   let str = items.map(item => item.productName).join(',')
   let str = items.map(item => item.productName).join(',')
-  confirmAction(`确定${items.length > 1 ? '批量删除' : '删除'}【${str}】线索吗?`).then(() => {
-    post(ALLDETELE, { ids: ids }).then(res => {
-      if (res.code != 'ok') {
-        globalPopup?.showError(res.msg)
-        return
-      }
+  confirmAction(`确定${items.length > 1 ? '批量删除' : '删除'}【${str}】产品吗?`).then(() => {
+    post(ALLDETELE, { ids: ids }).then((_res) => {
       globalPopup?.showSuccess('删除成功')
       globalPopup?.showSuccess('删除成功')
       getProductTableList()
       getProductTableList()
+    }).catch((err) => {
+      globalPopup?.showError(err.msg)
     })
     })
   })
   })
 }
 }
@@ -172,42 +217,45 @@ function deteleRow(items: any[]) {
 async function saveProductRow(flag: boolean) {
 async function saveProductRow(flag: boolean) {
   const data = await generateForm.value.getData()
   const data = await generateForm.value.getData()
   let newData = { ...genereditForm.value, ...data }
   let newData = { ...genereditForm.value, ...data }
+  delete newData.createTime
   allLoading.saveLoading = true
   allLoading.saveLoading = true
-  post(ADDPRODUCT, { ...newData }).then((res) => {
-    console.log(res)
-    if(res.code != 'ok') {
-      globalPopup?.showError(res.msg)
-      return
-    }
+  post(ADDPRODUCT, { ...newData }).then(() => {
     globalPopup?.showSuccess('保存成功')
     globalPopup?.showSuccess('保存成功')
-    if (!flag) {
+    if (flag) {
       genereditForm.value = {}
       genereditForm.value = {}
       generateForm.value && generateForm.value.reset()
       generateForm.value && generateForm.value.reset()
-      generateFormKey.value++
     }
     }
+    getProductTableList()
     dialogVisible.editProductVisible = flag
     dialogVisible.editProductVisible = flag
-  }).catch(() => {
-    dialogVisible.editProductVisible = flag
+  }).catch((err) => {
+    globalPopup?.showError(err.msg)
   }).finally(() => {
   }).finally(() => {
     allLoading.saveLoading = false
     allLoading.saveLoading = false
   })
   })
 }
 }
 
 
-function editProduct(_flag: boolean) {
+function editProduct(item: any) {
   dialogVisible.editProductVisible = true
   dialogVisible.editProductVisible = true
   allLoading.generateFormLading = true
   allLoading.generateFormLading = true
+  if (item) {
+    genereditForm.value = item
+    allText.editClueText = '编辑产品'
+  }
+  if (!item) {
+    genereditForm.value = {}
+  }
   setTimeout(() => {
   setTimeout(() => {
     generateForm.value && generateForm.value.reset()
     generateForm.value && generateForm.value.reset()
     generateFormKey.value++
     generateFormKey.value++
     allLoading.generateFormLading = false
     allLoading.generateFormLading = false
-  }, 1000)
+  }, 500)
 }
 }
 
 
 function getProductTableList() {
 function getProductTableList() {
   allLoading.productTableLading = true
   allLoading.productTableLading = true
   let valueForm = getFromValue(filterProductForm)
   let valueForm = getFromValue(filterProductForm)
   post(GETTABLELIST, { ...valueForm }).then((res) => {
   post(GETTABLELIST, { ...valueForm }).then((res) => {
-    if(res.code == 'ok') {
+    if (res.code == 'ok') {
       const { record, total } = res.data
       const { record, total } = res.data
       productTableList.value = record
       productTableList.value = record
       productTableTotal.value = total
       productTableTotal.value = total
@@ -217,6 +265,19 @@ function getProductTableList() {
   })
   })
 }
 }
 
 
+async function importProducts(param: UploadRequestOptions) {
+  allLoading.importLoading = true
+  const formData = new FormData();
+  formData.append('multipartFile', param.file)
+  const res = await uploadFile(UPLOADFILE, formData)
+  allLoading.importLoading = false
+  if (res.code == 'ok') {
+    globalPopup?.showSuccess(res.msg || '')
+    return
+  }
+  globalPopup?.showError(res.msg || '')
+}
+
 function handleSizeChange(val: number) {
 function handleSizeChange(val: number) {
   filterProductForm.pageIndex = 1
   filterProductForm.pageIndex = 1
   filterProductForm.pageSize = val
   filterProductForm.pageSize = val
@@ -235,9 +296,9 @@ function resetFilter() {
 }
 }
 
 
 function toProductDetail(row: any) {
 function toProductDetail(row: any) {
-  router.push({ 
-    path: `${MOD}/detail`, 
-    query: { id: row.id } 
+  router.push({
+    path: `${MOD}/detail`,
+    query: { id: row.id }
   })
   })
 }
 }
 
 

+ 1 - 6
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/detail/components/attachment.vue

@@ -64,12 +64,7 @@ const props = defineProps<{
 
 
 // 下载文件
 // 下载文件
 function fileDownload(item: any) {
 function fileDownload(item: any) {
-    const id = item.id
-    post(DOWNFILE, { id }).then((res) => {
-        downloadFile(res, item.name)
-    }).catch((err) => {
-        downloadFile(err, item.name)
-    })
+    downloadFile(`${item.path}`, item.name)
 }
 }
 
 
 // 删除文件
 // 删除文件

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

@@ -139,7 +139,7 @@
     <DeteleTables :visibles="dialogVisible.deteleClueDialogVisible" @showDeteleClue="showDeteleClue" />
     <DeteleTables :visibles="dialogVisible.deteleClueDialogVisible" @showDeteleClue="showDeteleClue" />
 
 
     <TaskModal :visible="dialogVisible.taskModalVisible" :edit-form="createTaskFromType(3)" :save-loading="'1'"
     <TaskModal :visible="dialogVisible.taskModalVisible" :edit-form="createTaskFromType(3)" :save-loading="'1'"
-      @close="closeTaskModal" @submit="submitForm" />
+      @close="closeTaskModal" @submit="submitForm" :title="'新建任务'" :disabled-list="['taskType', 'clueId']" />
   </div>
   </div>
 </template>
 </template>
 
 

+ 3 - 3
fhKeeper/formulahousekeeper/customerBuler-crm/src/styles/global.scss

@@ -47,7 +47,7 @@ $modena: #6f4afe;
   height: 0px;
   height: 0px;
 }
 }
 
 
-.el-dialog__header,.el-dialog__body{
-  margin: 0;
-  padding: 0;
+.el-dialog__header, .el-dialog__body{
+  margin: 0 !important;
+  padding: 0 !important;
 }
 }

+ 2 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/request.ts

@@ -45,13 +45,13 @@ instance.interceptors.response.use(
 );
 );
 
 
 // 封装GET请求
 // 封装GET请求
-export async function get(url: string, params?: any): Promise<any> {
+export async function get(url: string, params?: any, file: boolean = false): Promise<any> {
   return new Promise((resolve, reject) => {
   return new Promise((resolve, reject) => {
     instance
     instance
       .get(url, { params })
       .get(url, { params })
       .then(({ data }: any) => {
       .then(({ data }: any) => {
         const { code } = data;
         const { code } = data;
-        if (code === "ok") {
+        if (code === "ok" || file) {
           resolve(data);
           resolve(data);
           return;
           return;
         }
         }

+ 10 - 12
fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/tools.ts

@@ -1,5 +1,6 @@
 import { defalutModalForm } from '@/components/TaskModal/api'
 import { defalutModalForm } from '@/components/TaskModal/api'
 import { ElMessageBox } from 'element-plus';
 import { ElMessageBox } from 'element-plus';
+import { get } from './request';
 /**
 /**
  * 判断值是否为空
  * 判断值是否为空
  * @param value 值
  * @param value 值
@@ -155,20 +156,17 @@ export function createTaskFromType(taskType: TASK_VALUE_TYPE) {
 
 
 /**
 /**
  * 下载文件
  * 下载文件
- * @param dataFile 接口返回的数据
+ * @param fileData 接口返回的数据 或 文件地址
  * @param fileName 文件名称
  * @param fileName 文件名称
  */
  */
-export function downloadFile(dataFile: any, fileName: string) {
-  const data = dataFile;
-  const blob = new Blob([data]);
-  const url = window.URL.createObjectURL(blob);
-  const a = document.createElement('a');
-  a.href = url;
-  a.download = fileName;
-  document.body.appendChild(a);
-  a.click();
-  window.URL.revokeObjectURL(url);
-  document.body.removeChild(a);
+export async function downloadFile(fileData: any, fileName: string) {
+  const url=fileData;
+  const link = document.createElement('a');
+  link.href = url;
+  link.setAttribute('download', fileName);
+  document.body.appendChild(link);
+  link.click();
+  document.body.removeChild(link);
 };
 };
 
 
 /**
 /**

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

@@ -1787,7 +1787,10 @@ public class ReportController {
                     }
                     }
                 }
                 }
             }else {
             }else {
-                warningMsg.append("未查询到考勤信息");
+                if(warningMsg.length()>0){
+                    warningMsg.append(",");
+                }
+                warningMsg.append(df.format(date)+"未查询到考勤信息");
             }
             }
         }
         }
         String warningMsgStr = warningMsg.toString();
         String warningMsgStr = warningMsg.toString();

+ 88 - 12
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserWithBeisenController.java

@@ -24,6 +24,8 @@ import org.springframework.web.bind.annotation.RestController;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.Duration;
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
@@ -147,6 +149,7 @@ public class UserWithBeisenController {
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         DateTimeFormatter df1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         DateTimeFormatter df1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         DateTimeFormatter df2=DateTimeFormatter.ofPattern("HH:mm");
         DateTimeFormatter df2=DateTimeFormatter.ofPattern("HH:mm");
+        DateTimeFormatter df3=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
         TimeType timeType = timeTypeMapper.selectById(companyId);
         TimeType timeType = timeTypeMapper.selectById(companyId);
         List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
         List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
@@ -161,12 +164,15 @@ public class UserWithBeisenController {
         //todo 获取到指定日期的加班数据
         //todo 获取到指定日期的加班数据
         List<LocalDate> workDaysListInRange = WorkDayCalculateUtils.getWorkDaysListInRange(startDate, endDate, 1);
         List<LocalDate> workDaysListInRange = WorkDayCalculateUtils.getWorkDaysListInRange(startDate, endDate, 1);
         JSONArray allOverTimeList=new JSONArray();
         JSONArray allOverTimeList=new JSONArray();
+        JSONArray allVacationList=new JSONArray();
         List<UserFvTime> userFvTimeList=new ArrayList<>();
         List<UserFvTime> userFvTimeList=new ArrayList<>();
         for (LocalDate localDate : workDaysListInRange) {
         for (LocalDate localDate : workDaysListInRange) {
             JSONArray statisticList = BeiSenUtils.getAttendanceStatistics(df.format(localDate), df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
             JSONArray statisticList = BeiSenUtils.getAttendanceStatistics(df.format(localDate), df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
             JSONArray overTimeList = BeiSenUtils.getOverTimeList(df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
             JSONArray overTimeList = BeiSenUtils.getOverTimeList(df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
+            JSONArray vacationList = BeiSenUtils.getVacationList(df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(),1,100);
             allOverTimeList.addAll(overTimeList);
             allOverTimeList.addAll(overTimeList);
             attendanceStatistics.addAll(statisticList);
             attendanceStatistics.addAll(statisticList);
+            allVacationList.addAll(vacationList);
         }
         }
         for (LocalDate localDate : workDaysListInRange) {
         for (LocalDate localDate : workDaysListInRange) {
             Stream<JSONObject> swipingCardsStream = attendanceStatistics.stream().map(item -> (JSONObject) item);
             Stream<JSONObject> swipingCardsStream = attendanceStatistics.stream().map(item -> (JSONObject) item);
@@ -183,28 +189,68 @@ public class UserWithBeisenController {
                 //获取最早上班打卡时间
                 //获取最早上班打卡时间
                 List<LocalTime> minLocalTimeList = timeStream.filter(t -> t.getIntValue("Type") == 1).map(i -> LocalDateTime.parse(i.getString("ActualTime"),df1).toLocalTime()).collect(Collectors.toList());
                 List<LocalTime> minLocalTimeList = timeStream.filter(t -> t.getIntValue("Type") == 1).map(i -> LocalDateTime.parse(i.getString("ActualTime"),df1).toLocalTime()).collect(Collectors.toList());
                 Optional<LocalTime> min = minLocalTimeList.stream().min(LocalTime::compareTo);
                 Optional<LocalTime> min = minLocalTimeList.stream().min(LocalTime::compareTo);
-                //获取最早上班打卡时间
+                //获取最晚下班时间
                 List<LocalTime> maxLocalTimeList = timeStream1.filter(t -> t.getIntValue("Type") == 9).map(i -> LocalDateTime.parse(i.getString("ActualTime"),df1).toLocalTime()).collect(Collectors.toList());
                 List<LocalTime> maxLocalTimeList = timeStream1.filter(t -> t.getIntValue("Type") == 9).map(i -> LocalDateTime.parse(i.getString("ActualTime"),df1).toLocalTime()).collect(Collectors.toList());
                 Optional<LocalTime> max = maxLocalTimeList.stream().max(LocalTime::compareTo);
                 Optional<LocalTime> max = maxLocalTimeList.stream().max(LocalTime::compareTo);
-                //获取最晚下班时间
                 if(first.isPresent()){
                 if(first.isPresent()){
                     boolean workDay = WorkDayCalculateUtils.isWorkDay(localDate);
                     boolean workDay = WorkDayCalculateUtils.isWorkDay(localDate);
                     //todo:针对景昱 工作日默认以8小时工作制度加上加班时长 非工作日以加班时长为准
                     //todo:针对景昱 工作日默认以8小时工作制度加上加班时长 非工作日以加班时长为准
-                    Double workTime=8.0;
+                    Duration between = Duration.between(min.get(), max.get());
+                    Double workTime;
+                    if(between.toHours()>8){
+                        workTime=8.0;
+                    }else if(between.toHours()<0){
+                        workTime=0.0;
+                    }else {
+                        BigDecimal decimal = new BigDecimal(between.toMinutes());
+                        decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                        workTime=decimal.doubleValue();
+                    }
                     Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
                     Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
+                    Stream<JSONObject> vacationStream = allVacationList.stream().map(elment -> (JSONObject) elment);
                     Optional<UserWithBeisen> beisen = userWithBeisenList.stream().filter(u -> u.getJobNumber() != null && u.getJobNumber().equals(first.get().getJobNumber())).findFirst();
                     Optional<UserWithBeisen> beisen = userWithBeisenList.stream().filter(u -> u.getJobNumber() != null && u.getJobNumber().equals(first.get().getJobNumber())).findFirst();
                     if(beisen.isPresent()){
                     if(beisen.isPresent()){
                         //审核通过以及审批中都算
                         //审核通过以及审批中都算
                         List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
                         List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
-                                && (a.getIntValue("ApproveStatus") == 1||a.getIntValue("ApproveStatus") == 2)).collect(Collectors.toList());
+                                && (a.getIntValue("ApproveStatus") == 1||a.getIntValue("ApproveStatus") == 2)
+                                &&LocalDateTime.parse(a.getString("StartDate"),df1).toLocalDate().isEqual(localDate)).collect(Collectors.toList());
                         if(overTimeList.size()>0){
                         if(overTimeList.size()>0){
-                            double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("ActualOverTimeDuration")).sum();
+                            double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("OverTimeDuration")).sum();
                             if(workDay){
                             if(workDay){
                                 workTime= workTime+actualOverTimeDuration;
                                 workTime= workTime+actualOverTimeDuration;
                             }else {
                             }else {
                                 workTime= actualOverTimeDuration;
                                 workTime= actualOverTimeDuration;
                             }
                             }
                         }
                         }
+                        //处理修改
+                        List<JSONObject> vacationList = vacationStream.filter(a ->{
+                            LocalDate vacationStartDate = LocalDateTime.parse(a.getString("VacationStartDateTime"), df3).toLocalDate();
+                            LocalDate vacationStopDate = LocalDateTime.parse(a.getString("VacationStopDateTime"), df3).toLocalDate();
+                            boolean b=false;
+                            if((localDate.isAfter(vacationStartDate)||localDate.isEqual(vacationStartDate))
+                                    &&(localDate.isBefore(vacationStopDate)||localDate.isEqual(vacationStopDate))){
+                                b=true;
+                            }
+                            if(a.getString("StaffId").equals(beisen.get().getUserId())
+                                    && b
+                                    &&  (a.getString("ApproveStatus").equals("通过") || a.getString("ApproveStatus").equals("审批中"))){
+                                return true;
+                            }
+                            return false;
+                        }).collect(Collectors.toList());
+                        if(vacationList.size()>0){
+                            double vacationDuration = vacationList.stream().mapToDouble(i -> i.getDouble("VacationDuration")).sum();
+                            BigDecimal decimal = new BigDecimal(vacationDuration);
+                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                            //考勤打卡区间大于8小时 但是存在休假数据
+                            if(between.toHours()>8){
+                                if(decimal.doubleValue()>8){
+                                    workTime= workTime-8;
+                                }else {
+                                    workTime= workTime-decimal.doubleValue();
+                                }
+                            }
+                        }
                     }
                     }
                     UserFvTime userFvTime=new UserFvTime();
                     UserFvTime userFvTime=new UserFvTime();
                     userFvTime.setWorkDate(localDate);
                     userFvTime.setWorkDate(localDate);
@@ -236,6 +282,7 @@ public class UserWithBeisenController {
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         DateTimeFormatter df1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         DateTimeFormatter df1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         DateTimeFormatter df2=DateTimeFormatter.ofPattern("HH:mm");
         DateTimeFormatter df2=DateTimeFormatter.ofPattern("HH:mm");
+        DateTimeFormatter df3=DateTimeFormatter.ofPattern("HH:mm:ss");
         User user = userMapper.selectById(request.getHeader("token"));
         User user = userMapper.selectById(request.getHeader("token"));
         Integer companyId = user.getCompanyId();
         Integer companyId = user.getCompanyId();
         TimeType timeType = timeTypeMapper.selectById(companyId);
         TimeType timeType = timeTypeMapper.selectById(companyId);
@@ -246,15 +293,17 @@ public class UserWithBeisenController {
             msg.setError("北森基础数据配置未完成,请联系服务商完成配置");
             msg.setError("北森基础数据配置未完成,请联系服务商完成配置");
             return msg;
             return msg;
         }
         }
-        //todo 获取到指定日期的考勤数据
-        //todo 获取到指定日期的加班数据
         Optional<UserWithBeisen> withBeisen = userWithBeisenList.stream().filter(u ->u.getJobNumber()!=null&& u.getJobNumber().equals(user.getJobNumber())).findFirst();
         Optional<UserWithBeisen> withBeisen = userWithBeisenList.stream().filter(u ->u.getJobNumber()!=null&& u.getJobNumber().equals(user.getJobNumber())).findFirst();
         if(!withBeisen.isPresent()){
         if(!withBeisen.isPresent()){
             msg.setError("当前员工在北森系统中不存在,请完成录入员工信息");
             msg.setError("当前员工在北森系统中不存在,请完成录入员工信息");
             return msg;
             return msg;
         }
         }
+        //todo 获取到指定日期的考勤数据
         JSONObject item = BeiSenUtils.getAttendanceStatisticWithUser(createDate,withBeisen.get().getUserId(), beisenConfig.getAppKey(), beisenConfig.getAppSecret());
         JSONObject item = BeiSenUtils.getAttendanceStatisticWithUser(createDate,withBeisen.get().getUserId(), beisenConfig.getAppKey(), beisenConfig.getAppSecret());
+        //todo 获取到指定日期的加班数据
         JSONArray allOverTimeList = BeiSenUtils.getOverTimeList(createDate,beisenConfig.getAppKey(),beisenConfig.getAppSecret(),1,100);
         JSONArray allOverTimeList = BeiSenUtils.getOverTimeList(createDate,beisenConfig.getAppKey(),beisenConfig.getAppSecret(),1,100);
+        //todo 获取到指定日期的休假数据
+        JSONArray vacationList = BeiSenUtils.getVacationList(createDate, beisenConfig.getAppKey(), beisenConfig.getAppSecret(),1,100);
         //获取当前数据下的人员工号对应到工时管家
         //获取当前数据下的人员工号对应到工时管家
         Optional<User> first = userList.stream().filter(f -> f.getJobNumber().equals(withBeisen.get().getJobNumber())).findFirst();
         Optional<User> first = userList.stream().filter(f -> f.getJobNumber().equals(withBeisen.get().getJobNumber())).findFirst();
         System.out.println("考勤数据:"+item.toString());
         System.out.println("考勤数据:"+item.toString());
@@ -265,25 +314,52 @@ public class UserWithBeisenController {
         if(first.isPresent()){
         if(first.isPresent()){
             boolean workDay = WorkDayCalculateUtils.isWorkDay(LocalDate.parse(createDate,df));
             boolean workDay = WorkDayCalculateUtils.isWorkDay(LocalDate.parse(createDate,df));
             //todo:针对景昱 工作日默认以8小时工作制度加上加班时长 非工作日以加班时长为准
             //todo:针对景昱 工作日默认以8小时工作制度加上加班时长 非工作日以加班时长为准
-            Double workTime=8.0;
+            Double workTime;
+            Duration between = Duration.between(LocalTime.parse(firstCard, df3), LocalTime.parse(lastCard, df3));
+            if(between.toHours()>8){
+                workTime=8.0;
+            }else if(between.toHours()<0) {
+                workTime=0.0;
+            }else {
+                BigDecimal decimal = new BigDecimal(between.toMinutes());
+                decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                workTime=decimal.doubleValue();
+            }
             Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
             Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
+            Stream<JSONObject> vacationStream = vacationList.stream().map(elment -> (JSONObject) elment);
             Optional<UserWithBeisen> beisen = userWithBeisenList.stream().filter(u -> u.getJobNumber() != null && u.getJobNumber().equals(first.get().getJobNumber())).findFirst();
             Optional<UserWithBeisen> beisen = userWithBeisenList.stream().filter(u -> u.getJobNumber() != null && u.getJobNumber().equals(first.get().getJobNumber())).findFirst();
             if(beisen.isPresent()){
             if(beisen.isPresent()){
                 List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
                 List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
-                        && a.getIntValue("ApproveStatus") == 2).collect(Collectors.toList());
+                        && (a.getIntValue("ApproveStatus") == 2||a.getIntValue("ApproveStatus") == 1)).collect(Collectors.toList());
                 if(overTimeList.size()>0){
                 if(overTimeList.size()>0){
-                    double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("ActualOverTimeDuration")).sum();
+                    double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("OverTimeDuration")).sum();
                     if(workDay){
                     if(workDay){
                         workTime= workTime+actualOverTimeDuration;
                         workTime= workTime+actualOverTimeDuration;
                     }else {
                     }else {
                         workTime= actualOverTimeDuration;
                         workTime= actualOverTimeDuration;
                     }
                     }
                 }
                 }
+                //计算休假
+                List<JSONObject> targetVacation = vacationStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
+                        && (a.getString("ApproveStatus").equals("通过") || a.getString("ApproveStatus").equals("审批中"))).collect(Collectors.toList());
+                if(targetVacation.size()>0){
+                    double vacationDuration = targetVacation.stream().mapToDouble(i -> i.getDouble("VacationDuration")).sum();
+                    BigDecimal decimal = new BigDecimal(vacationDuration);
+                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                    //考勤打卡区间大于8小时 但是存在休假数据
+                    if(between.toHours()>8){
+                        if(decimal.doubleValue()>8){
+                            workTime= workTime-8;
+                        }else {
+                            workTime= workTime-decimal.doubleValue();
+                        }
+                    }
+                }
             }
             }
             UserFvTime userFvTime=new UserFvTime();
             UserFvTime userFvTime=new UserFvTime();
             userFvTime.setWorkDate(LocalDate.parse(createDate,df));
             userFvTime.setWorkDate(LocalDate.parse(createDate,df));
-            userFvTime.setStartTime(!StringUtils.isEmpty(firstCard)?firstCard:"08:30");
-            userFvTime.setEndTime(!StringUtils.isEmpty(lastCard)?lastCard:"17:30");
+            userFvTime.setStartTime(!StringUtils.isEmpty(firstCard)?firstCard:"08:30:00");
+            userFvTime.setEndTime(!StringUtils.isEmpty(lastCard)?lastCard:"17:30:00");
             userFvTime.setUserId(first.get().getId());
             userFvTime.setUserId(first.get().getId());
             userFvTime.setCompanyId(companyId);
             userFvTime.setCompanyId(companyId);
             userFvTime.setWorkHours(workTime.floatValue());
             userFvTime.setWorkHours(workTime.floatValue());

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

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
  * </p>
  * </p>
  *
  *
  * @author Seyason
  * @author Seyason
- * @since 2023-05-26
+ * @since 2024-04-20
  */
  */
 @Data
 @Data
 @EqualsAndHashCode(callSuper = false)
 @EqualsAndHashCode(callSuper = false)
@@ -108,6 +108,12 @@ public class CompanyDingding extends Model<CompanyDingding> {
     @TableField("sync_contact")
     @TableField("sync_contact")
     private Integer syncContact;
     private Integer syncContact;
 
 
+    /**
+     * 通讯录是否需要转译
+     */
+    @TableField("contact_need_translate")
+    private Integer contactNeedTranslate;
+
 
 
     @Override
     @Override
     protected Serializable pkVal() {
     protected Serializable pkVal() {

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

@@ -377,8 +377,6 @@ public class DingDingServiceImpl implements DingDingService {
                     .setExpirationDate(LocalDateTime.now().plusDays(15));
                     .setExpirationDate(LocalDateTime.now().plusDays(15));
             company.setPackageProject(1);
             company.setPackageProject(1);
             company.setPackageExpense(1);
             company.setPackageExpense(1);
-            company.setPackageCustomer(1);
-            company.setPackageOa(1);
             //设置来源
             //设置来源
             company.setRegFrom("钉钉");
             company.setRegFrom("钉钉");
             companyMapper.insert(company);
             companyMapper.insert(company);
@@ -483,6 +481,7 @@ public class DingDingServiceImpl implements DingDingService {
         dingding.setAgentId(agentId);
         dingding.setAgentId(agentId);
         dingding.setAuthUserId(authUserId);
         dingding.setAuthUserId(authUserId);
         dingding.setSyncContact(1);
         dingding.setSyncContact(1);
+        dingding.setContactNeedTranslate(1);//上架到钉钉应用市场,通讯录为加密模式,需要转译
 
 
         if (oldD == null) {
         if (oldD == null) {
             //第一次,查询对方企业的accessToken
             //第一次,查询对方企业的accessToken
@@ -1148,6 +1147,7 @@ public class DingDingServiceImpl implements DingDingService {
                         num = auditWorkflowTimeSettingMapper.selectCount(new QueryWrapper<AuditWorkflowTimeSetting>().in("audit_dept_id", deptIds));
                         num = auditWorkflowTimeSettingMapper.selectCount(new QueryWrapper<AuditWorkflowTimeSetting>().in("audit_dept_id", deptIds));
                     }
                     }
                     userVO.setHasAuditDept(num>0);
                     userVO.setHasAuditDept(num>0);
+                    userVO.setUserNameNeedTranslate(companyDingding.getContactNeedTranslate());
                     userService.setUserRoleMenu(userVO);
                     userService.setUserRoleMenu(userVO);
                     httpRespMsg.data = userVO;
                     httpRespMsg.data = userVO;
                 }
                 }

+ 14 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java

@@ -264,6 +264,13 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
                 if (info != null) {
                 if (info != null) {
                     userList.get(0).setUserNameNeedTranslate(info.getSaasSyncContact());
                     userList.get(0).setUserNameNeedTranslate(info.getSaasSyncContact());
                 }
                 }
+                //检测钉钉用户,是否需要转译
+                else {
+                    CompanyDingding companyDingding = companyDingdingService.getOne(new QueryWrapper<CompanyDingding>().eq("company_id", company.getId()));
+                    if (companyDingding != null) {
+                        userList.get(0).setUserNameNeedTranslate(companyDingding.getContactNeedTranslate());
+                    }
+                }
                 BeanUtils.copyProperties(userList.get(0), userVO);
                 BeanUtils.copyProperties(userList.get(0), userVO);
                 if (userVO.getRoleId() == null || userVO.getRoleId() == 0) {
                 if (userVO.getRoleId() == null || userVO.getRoleId() == 0) {
                     httpRespMsg.setError(MessageUtils.message("user.noRole"));
                     httpRespMsg.setError(MessageUtils.message("user.noRole"));
@@ -2614,7 +2621,13 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         if (info != null) {
         if (info != null) {
             user.setUserNameNeedTranslate(info.getSaasSyncContact());
             user.setUserNameNeedTranslate(info.getSaasSyncContact());
         }
         }
-
+        //检测钉钉用户,是否需要转译
+        else {
+            CompanyDingding companyDingding = companyDingdingService.getOne(new QueryWrapper<CompanyDingding>().eq("company_id", company.getId()));
+            if (companyDingding != null) {
+                user.setUserNameNeedTranslate(companyDingding.getContactNeedTranslate());
+            }
+        }
         UserVO userVO = new UserVO().setCompanyName(company.getCompanyName());
         UserVO userVO = new UserVO().setCompanyName(company.getCompanyName());
         userVO.setCompany(company);
         userVO.setCompany(company);
         BeanUtils.copyProperties(user, userVO);
         BeanUtils.copyProperties(user, userVO);

+ 57 - 9
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -38,6 +38,7 @@ import javax.annotation.Resource;
 import java.io.File;
 import java.io.File;
 import java.io.IOException;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.security.SecureRandom;
 import java.security.SecureRandom;
 import java.sql.Time;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Timestamp;
@@ -2061,7 +2062,7 @@ public class TimingTask {
     /**
     /**
      * 每天凌晨2:50同步前一天的北森考勤数据 暂时固定公司id(5978)针对景昱
      * 每天凌晨2:50同步前一天的北森考勤数据 暂时固定公司id(5978)针对景昱
      * */
      * */
-    @Scheduled(cron ="0 50 2 ? * *")
+    @Scheduled(cron ="0 38 16 ? * *")
     public void syncAttendanceFromBeisen(){
     public void syncAttendanceFromBeisen(){
         if(isDev){
         if(isDev){
             return;
             return;
@@ -2069,7 +2070,8 @@ public class TimingTask {
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         DateTimeFormatter df1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         DateTimeFormatter df1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         DateTimeFormatter df2=DateTimeFormatter.ofPattern("HH:mm");
         DateTimeFormatter df2=DateTimeFormatter.ofPattern("HH:mm");
-        String startDate=LocalDate.now().plusDays(1).format(df);
+        DateTimeFormatter df3=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+        String startDate=LocalDate.now().minusDays(1).format(df);
         String endDate=LocalDate.now().plusDays(1).format(df);
         String endDate=LocalDate.now().plusDays(1).format(df);
         List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, 5978));
         List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, 5978));
         List<UserWithBeisen> userWithBeisenList = userWithBeisenService.list(new LambdaQueryWrapper<UserWithBeisen>().eq(UserWithBeisen::getCompanyId, 5978));
         List<UserWithBeisen> userWithBeisenList = userWithBeisenService.list(new LambdaQueryWrapper<UserWithBeisen>().eq(UserWithBeisen::getCompanyId, 5978));
@@ -2077,15 +2079,21 @@ public class TimingTask {
         if(beisenConfig==null){
         if(beisenConfig==null){
             return;
             return;
         }
         }
-        //todo 获取到指定日期的考勤数据
-        JSONArray attendanceStatistics = BeiSenUtils.getAttendanceStatistics(startDate, endDate, beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
+
         //todo 获取到指定日期的加班数据
         //todo 获取到指定日期的加班数据
         List<LocalDate> workDaysListInRange = WorkDayCalculateUtils.getWorkDaysListInRange(startDate, endDate, 1);
         List<LocalDate> workDaysListInRange = WorkDayCalculateUtils.getWorkDaysListInRange(startDate, endDate, 1);
         JSONArray allOverTimeList=new JSONArray();
         JSONArray allOverTimeList=new JSONArray();
+        JSONArray attendanceStatistics=new JSONArray();
+        JSONArray allVacationList=new JSONArray();
         List<UserFvTime> userFvTimeList=new ArrayList<>();
         List<UserFvTime> userFvTimeList=new ArrayList<>();
         for (LocalDate localDate : workDaysListInRange) {
         for (LocalDate localDate : workDaysListInRange) {
             JSONArray overTimeList = BeiSenUtils.getOverTimeList(df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
             JSONArray overTimeList = BeiSenUtils.getOverTimeList(df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
+            //todo 获取到指定日期的考勤数据
+            JSONArray attendanceStatisticList = BeiSenUtils.getAttendanceStatistics(df.format(localDate), df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
+            JSONArray vacationList = BeiSenUtils.getVacationList(df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(),1,100);
             allOverTimeList.addAll(overTimeList);
             allOverTimeList.addAll(overTimeList);
+            attendanceStatistics.addAll(attendanceStatisticList);
+            allVacationList.addAll(vacationList);
         }
         }
         for (LocalDate localDate : workDaysListInRange) {
         for (LocalDate localDate : workDaysListInRange) {
             Stream<JSONObject> swipingCardsStream = attendanceStatistics.stream().map(item -> (JSONObject) item);
             Stream<JSONObject> swipingCardsStream = attendanceStatistics.stream().map(item -> (JSONObject) item);
@@ -2109,25 +2117,65 @@ public class TimingTask {
                 if(first.isPresent()){
                 if(first.isPresent()){
                     boolean workDay = WorkDayCalculateUtils.isWorkDay(localDate);
                     boolean workDay = WorkDayCalculateUtils.isWorkDay(localDate);
                     //todo:针对景昱 工作日默认以8小时工作制度加上加班时长 非工作日以加班时长为准
                     //todo:针对景昱 工作日默认以8小时工作制度加上加班时长 非工作日以加班时长为准
-                    Double workTime=8.0;
+                    Duration between = Duration.between(min.get(), max.get());
+                    Double workTime;
+                    if(between.toHours()>8){
+                        workTime=8.0;
+                    }else if(between.toHours()<0){
+                        workTime=0.0;
+                    }else {
+                        BigDecimal decimal = new BigDecimal(between.toMinutes());
+                        decimal=decimal.divide(new BigDecimal(60),1, RoundingMode.HALF_UP);
+                        workTime=decimal.doubleValue();
+                    }
                     Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
                     Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
+                    Stream<JSONObject> vacationStream = allVacationList.stream().map(elment -> (JSONObject) elment);
                     Optional<UserWithBeisen> beisen = userWithBeisenList.stream().filter(u -> u.getJobNumber() != null && u.getJobNumber().equals(first.get().getJobNumber())).findFirst();
                     Optional<UserWithBeisen> beisen = userWithBeisenList.stream().filter(u -> u.getJobNumber() != null && u.getJobNumber().equals(first.get().getJobNumber())).findFirst();
                     if(beisen.isPresent()){
                     if(beisen.isPresent()){
                         List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
                         List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
-                                && a.getIntValue("ApproveStatus") == 2).collect(Collectors.toList());
+                                && (a.getIntValue("ApproveStatus") == 2||a.getIntValue("ApproveStatus") == 1)
+                                &&LocalDateTime.parse(a.getString("StartDate"),df1).toLocalDate().isEqual(localDate)).collect(Collectors.toList());
                         if(overTimeList.size()>0){
                         if(overTimeList.size()>0){
-                            double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("ActualOverTimeDuration")).sum();
+                            double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("OverTimeDuration")).sum();
                             if(workDay){
                             if(workDay){
                                 workTime= workTime+actualOverTimeDuration;
                                 workTime= workTime+actualOverTimeDuration;
                             }else {
                             }else {
                                 workTime= actualOverTimeDuration;
                                 workTime= actualOverTimeDuration;
                             }
                             }
                         }
                         }
+                        List<JSONObject> vacationList = vacationStream.filter(a ->{
+                            LocalDate vacationStartDate = LocalDateTime.parse(a.getString("VacationStartDateTime"), df3).toLocalDate();
+                            LocalDate vacationStopDate = LocalDateTime.parse(a.getString("VacationStopDateTime"), df3).toLocalDate();
+                            boolean b=false;
+                            if((localDate.isAfter(vacationStartDate)||localDate.isEqual(vacationStartDate))
+                                    &&(localDate.isBefore(vacationStopDate)||localDate.isEqual(vacationStopDate))){
+                                b=true;
+                            }
+                            if(a.getString("StaffId").equals(beisen.get().getUserId())
+                                    && b
+                                    &&  (a.getString("ApproveStatus").equals("通过") || a.getString("ApproveStatus").equals("审批中"))){
+                                return true;
+                            }
+                            return false;
+                        }).collect(Collectors.toList());
+                        if(vacationList.size()>0){
+                            double vacationDuration = vacationList.stream().mapToDouble(i -> i.getDouble("VacationDuration")).sum();
+                            BigDecimal decimal = new BigDecimal(vacationDuration);
+                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                            //考勤打卡区间大于8小时 但是存在休假数据
+                            if(between.toHours()>8){
+                                if(decimal.doubleValue()>8){
+                                    workTime= workTime-8;
+                                }else {
+                                    workTime= workTime-decimal.doubleValue();
+                                }
+                            }
+                        }
                     }
                     }
                     UserFvTime userFvTime=new UserFvTime();
                     UserFvTime userFvTime=new UserFvTime();
                     userFvTime.setWorkDate(localDate);
                     userFvTime.setWorkDate(localDate);
-                    userFvTime.setStartTime(min.isPresent()?df2.format(min.get()):"08:30");
-                    userFvTime.setEndTime(max.isPresent()?df2.format(max.get()):"17:30");
+                    userFvTime.setStartTime(min.isPresent()?df2.format(min.get()):"08:30:00");
+                    userFvTime.setEndTime(max.isPresent()?df2.format(max.get()):"17:30:00");
                     userFvTime.setUserId(first.get().getId());
                     userFvTime.setUserId(first.get().getId());
                     userFvTime.setCompanyId(5978);
                     userFvTime.setCompanyId(5978);
                     userFvTime.setWorkHours(workTime.floatValue());
                     userFvTime.setWorkHours(workTime.floatValue());

+ 54 - 21
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/BeiSenUtils.java

@@ -110,27 +110,22 @@ public class BeiSenUtils {
                 requestMap.put("columns",columns);
                 requestMap.put("columns",columns);
             }
             }
         }
         }
-        //针对威派格的参数
-        {
-            List<Integer> serviceType=new ArrayList<>();
-            serviceType.add(0);
-            serviceType.add(1);
-            List<String> employType=new ArrayList<>();
-            employType.add("0");
-            employType.add("2");
-            List<Integer> empStatus=new ArrayList<>();
-            empStatus.add(2);
-            empStatus.add(3);
-            empStatus.add(6);
-            empStatus.add(8);
-            if(companyId!=null && companyId==936){
-                requestMap.put("serviceType",serviceType);
-                requestMap.put("employType",employType);
-                requestMap.put("empStatus",empStatus);
-                requestMap.put("isWithDeleted",true);
-                requestMap.put("enableTranslate",true);
-            }
-        }
+        List<Integer> serviceType=new ArrayList<>();
+        serviceType.add(0);
+        serviceType.add(1);
+        List<String> employType=new ArrayList<>();
+        employType.add("0");
+        employType.add("2");
+        List<Integer> empStatus=new ArrayList<>();
+        empStatus.add(2);
+        empStatus.add(3);
+        empStatus.add(6);
+        empStatus.add(8);
+        requestMap.put("serviceType",serviceType);
+        requestMap.put("employType",employType);
+        requestMap.put("empStatus",empStatus);
+        requestMap.put("isWithDeleted",true);
+        requestMap.put("enableTranslate",true);
         System.out.println("--------headers请求头数据-------"+headers);
         System.out.println("--------headers请求头数据-------"+headers);
         if(!StringUtils.isEmpty(scrollId)){
         if(!StringUtils.isEmpty(scrollId)){
             requestMap.put("scrollId",scrollId);
             requestMap.put("scrollId",scrollId);
@@ -331,4 +326,42 @@ public class BeiSenUtils {
         return data;
         return data;
     }
     }
 
 
+    /**
+     * 获取人员休假数据
+     * */
+    public static JSONArray getVacationList(String day,String appkey,String appSecret,Integer pageIndex,Integer pageSize){
+        String url = "https://openapi.italent.cn/AttendanceOpen/api/v1/Vacation/GetList";
+        HttpHeaders headers = new HttpHeaders();
+        RestTemplate restTemplate = new RestTemplate();
+        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+        headers.setContentType(type);
+        String accessToken = getToken(appkey,appSecret);
+        System.out.println("--------Bearer TOKEN--------"+accessToken);
+        headers.add("Authorization","Bearer "+accessToken);
+        JSONObject requestMap = new JSONObject();
+        requestMap.put("Day",day);
+        requestMap.put("PageIndex",pageIndex);
+        requestMap.put("PageSize",pageSize);
+        System.out.println("--------headers请求头数据-------"+headers);
+        System.out.println("--------requestMap请求参数-------"+requestMap);
+        HttpEntity<JSONObject> entity = new HttpEntity<>(requestMap, headers);
+        ResponseEntity<String> ResponseEntity = restTemplate.postForEntity(url, entity, String.class);
+        JSONArray lastJSONArray=new JSONArray();
+        if (ResponseEntity.getStatusCode() == HttpStatus.OK) {
+            String resp= ResponseEntity.getBody();
+            JSONObject respJson = JSONObject.parseObject(resp);
+            if(respJson.getIntValue("Code")==200){
+                JSONObject data = respJson.getJSONObject("Data");
+                JSONArray target = data.getJSONArray("VacationList");
+                lastJSONArray.addAll(target);
+                if (target.size()>0){
+                    pageIndex++;
+                    JSONArray overTimeList = getVacationList(day, appkey, appSecret, pageIndex, pageSize);
+                    lastJSONArray.addAll(overTimeList);
+                }
+            }
+        }
+        return lastJSONArray;
+    }
+
 }
 }

+ 2 - 14
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CompanyDingdingMapper.xml

@@ -20,24 +20,12 @@
         <result column="pc_web_url" property="pcWebUrl" />
         <result column="pc_web_url" property="pcWebUrl" />
         <result column="oa_manager_dingid" property="oaManagerDingid" />
         <result column="oa_manager_dingid" property="oaManagerDingid" />
         <result column="sync_contact" property="syncContact" />
         <result column="sync_contact" property="syncContact" />
+        <result column="contact_need_translate" property="contactNeedTranslate" />
     </resultMap>
     </resultMap>
 
 
     <!-- 通用查询结果列 -->
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
     <sql id="Base_Column_List">
-        corpid, corp_name, auth_user_id, indate, company_id, access_token, expire_time, agent_id, inner_appkey, inner_appsecret, inner_token, inner_expire_time, web_url, pc_web_url, oa_manager_dingid, sync_contact
+        corpid, corp_name, auth_user_id, indate, company_id, access_token, expire_time, agent_id, inner_appkey, inner_appsecret, inner_token, inner_expire_time, web_url, pc_web_url, oa_manager_dingid, sync_contact, contact_need_translate
     </sql>
     </sql>
 
 
-    <select id="getDingdingCompanyList" resultType="com.management.platform.entity.CompanyDingding">
-        select *
-        from company_dingding
-        left join company
-        ON company_dingding.company_id = company.id
-        where company.expiration_date >= now()
-        <if test="companyIds.size()>0">
-            and company.id in
-            <foreach collection="companyIds" item="item" separator="," open="(" close=")">
-                #{item}
-            </foreach>
-        </if>
-    </select>
 </mapper>
 </mapper>

+ 0 - 25
fhKeeper/formulahousekeeper/plugIn/form-design-master/src/components.d.ts

@@ -6,31 +6,6 @@ declare module 'vue' {
   export interface GlobalComponents {
   export interface GlobalComponents {
     CodeEditor: typeof import('./components/CodeEditor.vue')['default']
     CodeEditor: typeof import('./components/CodeEditor.vue')['default']
     ComponentGroup: typeof import('./components/ComponentGroup.vue')['default']
     ComponentGroup: typeof import('./components/ComponentGroup.vue')['default']
-    ElButton: typeof import('element-plus/es')['ElButton']
-    ElCascader: typeof import('element-plus/es')['ElCascader']
-    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
-    ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
-    ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
-    ElDialog: typeof import('element-plus/es')['ElDialog']
-    ElDivider: typeof import('element-plus/es')['ElDivider']
-    ElForm: typeof import('element-plus/es')['ElForm']
-    ElFormItem: typeof import('element-plus/es')['ElFormItem']
-    ElImage: typeof import('element-plus/es')['ElImage']
-    ElInput: typeof import('element-plus/es')['ElInput']
-    ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
-    ElOption: typeof import('element-plus/es')['ElOption']
-    ElRadio: typeof import('element-plus/es')['ElRadio']
-    ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
-    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
-    ElRate: typeof import('element-plus/es')['ElRate']
-    ElSelect: typeof import('element-plus/es')['ElSelect']
-    ElSlider: typeof import('element-plus/es')['ElSlider']
-    ElSpace: typeof import('element-plus/es')['ElSpace']
-    ElSwitch: typeof import('element-plus/es')['ElSwitch']
-    ElTable: typeof import('element-plus/es')['ElTable']
-    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
-    ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
-    ElUpload: typeof import('element-plus/es')['ElUpload']
   }
   }
 }
 }
 
 

+ 3 - 0
fhKeeper/formulahousekeeper/timesheet/index.html

@@ -15,6 +15,8 @@
       href="https://cdn.staticfile.org/element-ui/2.13.0/theme-chalk/index.css"
       href="https://cdn.staticfile.org/element-ui/2.13.0/theme-chalk/index.css"
       rel="stylesheet"
       rel="stylesheet"
     />
     />
+    <!--接入钉钉前端组件,进行通讯录组件展示-->
+    <script src="https://auth.dingtalk.com/opendata-1.1.0.js"></script>
     <!-- <link rel="stylesheet" href="./static/js/element-uiCss.css"> -->
     <!-- <link rel="stylesheet" href="./static/js/element-uiCss.css"> -->
     <!-- 接入JQ  -->
     <!-- 接入JQ  -->
     <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
     <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
@@ -162,6 +164,7 @@
       src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"
       src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"
       referrerpolicy="origin"
       referrerpolicy="origin"
     ></script>
     ></script>
+    
     <!-- <script src="./static/js/jweixin-1.2.0.js"></script>
     <!-- <script src="./static/js/jweixin-1.2.0.js"></script>
         <script src="./static/js/jwxwork-1.0.0.js"></script> -->
         <script src="./static/js/jwxwork-1.0.0.js"></script> -->
   </body>
   </body>

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

@@ -184,7 +184,7 @@
     "exportingTimeStatistics": "导出工时统计"
     "exportingTimeStatistics": "导出工时统计"
   },
   },
   "other": {
   "other": {
-    "kaoqingTimeTip": "工作时长不包含未审批加班及休假",
+    "kaoqingTimeTip": "工作时长包括已提交的加班和休假申请",
     "customerService": "咨询客服",
     "customerService": "咨询客服",
     "sweepWeChatYards": "微信扫码",
     "sweepWeChatYards": "微信扫码",
     "messageCenter": "消息中心",
     "messageCenter": "消息中心",

+ 2 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/Home.vue

@@ -83,7 +83,8 @@
                                             </span>
                                             </span>
                                             <span v-if="user.userNameNeedTranslate == 1">
                                             <span v-if="user.userNameNeedTranslate == 1">
                                                 {{scope.row.omg.textOne}}
                                                 {{scope.row.omg.textOne}}
-                                                <ww-open-data type='userName' :openid='scope.row.omg.textTwo'></ww-open-data>
+                                                <ww-open-data v-if="user.corpwxUserid != null" type='userName' :openid='scope.row.omg.textTwo'></ww-open-data>
+                                                <dd-open-data v-if="user.dingdingUserid != null" openType='userName' :openId='scope.row.omg.textTwo'></dd-open-data>
                                                 {{scope.row.omg.textThree}}
                                                 {{scope.row.omg.textThree}}
                                             </span>
                                             </span>
                                         </span>
                                         </span>

+ 120 - 16
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -1022,7 +1022,9 @@
                 <!-- <el-button @click="zhoAddlast()" style="float:left;" class="el-icon-back">{{$t('defaultText.selectProject')}}</el-button> -->
                 <!-- <el-button @click="zhoAddlast()" style="float:left;" class="el-icon-back">{{$t('defaultText.selectProject')}}</el-button> -->
                 <el-button @click="closeAddWeeklyReport()" :loading="submitingReport">{{$t('btn.cancel')}}</el-button>
                 <el-button @click="closeAddWeeklyReport()" :loading="submitingReport">{{$t('btn.cancel')}}</el-button>
                 <el-button @click="submitWeekReport(1)" :loading="submitingReport" >{{$t('btn.temporaryStorage')}}</el-button>
                 <el-button @click="submitWeekReport(1)" :loading="submitingReport" >{{$t('btn.temporaryStorage')}}</el-button>
-                <el-button type="primary" @click="submitWeekReport(0)" :loading="submitingReport">{{$t('btn.submit')}}</el-button>
+                <el-button v-if="user.companyId != 5978" type="primary" @click="submitWeekReport(0)" :loading="submitingReport">{{$t('btn.submit')}}</el-button>
+                <!--针对景昱,先检查工时是否存在异常-->
+                <el-button v-if="user.companyId == 5978" type="primary" @click="checkDateWorkTime()" :loading="submitingReport">{{$t('btn.submit')}}</el-button>
             </span>
             </span>
         </el-dialog>
         </el-dialog>
         <!-- 重庆物奇私人定制的按周填报 -->
         <!-- 重庆物奇私人定制的按周填报 -->
@@ -6823,6 +6825,43 @@
                 this.selProjectList = []
                 this.selProjectList = []
                 this.selCon = []
                 this.selCon = []
             },
             },
+            checkDateWorkTime() {
+                //针对苏州景昱,单独的检查逻辑
+                if (this.user.companyId == 5978) {
+                    //调接口,先检查工时是否存在异常
+                    var zhi = this.zhoData;
+                    var array = [];
+                    for(let n in zhi){
+                        if(zhi[n].he){
+                            var workData = {date: zhi[n].zhoDataTime, workingTime: zhi[n].he};
+                            array.push(workData)
+                        }
+                    }
+                    this.submitingReport = true;
+                    this.http.post('/report/checkBeiSengCardTime', {userId:this.user.id, dateWorkingTime:JSON.stringify(array)},
+                    res => {
+                        this.submitingReport = false;
+                        if (res.code == "ok") {
+                            this.submitWeekReport(0)
+                        } else {
+                            this.$confirm(res.msg, '提示', {
+                                confirmButtonText: '忽略并提交',
+                                cancelButtonText: '取消',
+                                type: 'error'
+                            }).then(() => {
+                                this.submitWeekReport(0)
+                            }).catch(() => {
+                            });
+                        }
+                    },
+                    error => {
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                    });
+                }
+            },
             // 提交按周填报
             // 提交按周填报
             submitWeekReport(isDraft) {
             submitWeekReport(isDraft) {
                 var zhi = this.zhoData
                 var zhi = this.zhoData
@@ -6899,7 +6938,7 @@
                         }
                         }
                         
                         
                     }
                     }
-                    if(overcorp != ''){
+                    if(this.user.companyId != 5978 && overcorp != ''){
                         overcorp = overcorp.substring(0,overcorp.length - 1)
                         overcorp = overcorp.substring(0,overcorp.length - 1)
                         this.$message({
                         this.$message({
                             message: this.$t('weekDay.date')+'[' + overcorp + ']'+this.$t('message.cannotexceedtotal'),
                             message: this.$t('weekDay.date')+'[' + overcorp + ']'+this.$t('message.cannotexceedtotal'),
@@ -7479,18 +7518,83 @@
                 this.isDraft = isDraft;
                 this.isDraft = isDraft;
                 this.$refs.workForm.validate(valid => {
                 this.$refs.workForm.validate(valid => {
                     if (valid) {
                     if (valid) {
-                if(this.totalReportHours < this.user.timeType.allday){
-                    this.$confirm('当日工时不足' + this.user.timeType.allday.toFixed(1) + '小时,是否确定提交?', '提示', {
-                        confirmButtonText: '确定',
-                        cancelButtonText: '取消',
-                        type: 'warning'
-                    }).then(() => {
-                        this.submitReportSon()
-                    }).catch(() => {
-                    });
-                }else{
-                    this.submitReportSon()
-                }
+                        if (!isDraft) {
+                            //针对苏州景昱,单独的检查逻辑
+                            if (this.user.companyId == 5978) {
+                                //调接口,先检查工时是否存在异常
+                                var totalTime = 0;
+                                for (var t=0;t<this.workForm.domains.length; t++) {
+                                    totalTime += parseFloat(this.workForm.domains[t].workingTime);
+                                }
+                                var array = [];
+                                if (this.isBatch) {
+                                    var startDate = new Date(this.workForm.createDate[0]);
+                                    var endDate = new Date(this.workForm.createDate[1]);
+                                    if (startDate > endDate) {
+                                        this.$message({
+                                            message: '开始日期不能大于结束日期',
+                                            type: "error"
+                                        });
+                                        return
+                                    } else {
+                                        while(true){
+                                            var workData = {date: util.formatDate.format(startDate, "yyyy-MM-dd"), workingTime: totalTime};
+                                            array.push(workData);
+                                            startDate.setDate(startDate.getDate() + 1);
+                                            if (startDate > endDate) {
+                                                break;
+                                            }
+                                        }
+                                    }
+                                } else {
+                                    var workData = {date: this.workForm.createDate, workingTime: totalTime};
+                                    array.push(workData)
+                                }
+                                this.submitingReport = true;
+                                var passUserId = this.user.id;
+                                if (this.isSubstitude) {
+                                    passUserId = this.targetUids;
+                                }
+                                this.http.post('/report/checkBeiSengCardTime', {userId:passUserId, dateWorkingTime:JSON.stringify(array)},
+                                res => {
+                                    this.submitingReport = false;
+                                    if (res.code == "ok") {
+                                        this.submitReportSon()
+                                    } else {
+                                        this.$confirm(res.msg, '提示', {
+                                            confirmButtonText: '忽略并提交',
+                                            cancelButtonText: '取消',
+                                            type: 'error'
+                                        }).then(() => {
+                                            this.submitReportSon()
+                                        }).catch(() => {
+                                        });
+                                    }
+                                },
+                                error => {
+                                    this.$message({
+                                        message: error,
+                                        type: "error"
+                                    });
+                                });
+                            } else {
+                                if(this.totalReportHours < this.user.timeType.allday){
+                                    this.$confirm('当日工时不足' + this.user.timeType.allday.toFixed(1) + '小时,是否确定提交?', '提示', {
+                                        confirmButtonText: '确定',
+                                        cancelButtonText: '取消',
+                                        type: 'warning'
+                                    }).then(() => {
+                                        this.submitReportSon()
+                                    }).catch(() => {
+                                    });
+                                }else{
+                                    this.submitReportSon()
+                                }
+                            }
+                        } else {
+                            //暂存,不需要检查工时是否超过考勤
+                            this.submitReportSon()
+                        }
                     }
                     }
                 });
                 });
             },
             },
@@ -7690,8 +7794,8 @@
                                 }
                                 }
                             }
                             }
                         }
                         }
-                        //针对凡己,不校验考勤时长
-                        if (this.user.companyId != 3918 && this.reportTimeType.type == 1 && this.workForm.time) {
+                        //针对凡己和景昱此处不校验考勤时长
+                        if (this.user.companyId != 3918 && this.user.companyId != 5978  && this.reportTimeType.type == 1 && this.workForm.time) {
                             if (this.workForm.time.workHours && totalTime > parseFloat(this.workForm.time.workHours)) {
                             if (this.workForm.time.workHours && totalTime > parseFloat(this.workForm.time.workHours)) {
                                 this.$message({
                                 this.$message({
                                         message: this.$t('message.Fillinthesumofworkinghours')+(totalTime)+"h"+this.$t('message.Cannotexceedthetotalworkinghoursofattendance')+"("+this.workForm.time.workHours.toFixed(1)+"h)",
                                         message: this.$t('message.Fillinthesumofworkinghours')+(totalTime)+"h"+this.$t('message.Cannotexceedthetotalworkinghoursofattendance')+"("+this.workForm.time.workHours.toFixed(1)+"h)",

+ 37 - 10
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -2086,16 +2086,43 @@ export default {
                         //暂存操作
                         //暂存操作
                         this.submitReportSon()
                         this.submitReportSon()
                     } else {
                     } else {
-                        //提交时,做工时时长不足的提醒
-                        if (this.totalReportHours < this.user.timeType.allday) {
-                            this.$dialog.confirm({
-                                title: '提示',
-                                message: '当日工时不足' + this.user.timeType.allday.toFixed(1) + '小时,是否确定提交?'
-                            }).then(() => {
-                                this.submitReportSon()
-                            }).catch(() => { })
+                        if (this.user.companyId == 5978) {
+                            //调接口,先检查工时是否存在异常
+                            var totalTime = 0;
+                            for (var t=0;t<this.form.domains.length; t++) {
+                                totalTime += parseFloat(this.form.domains[t].workingTime);
+                            }
+                            var array = [];
+                            var workData = {date: this.form.createDate, workingTime: totalTime};
+                            array.push(workData)
+                            this.flgLg = false
+                            var passUserId = this.user.id;
+                            this.$axios.post("/report/checkBeiSengCardTime", { userId:passUserId, dateWorkingTime:JSON.stringify(array)})
+                            .then(res => {
+                                this.flgLg = true
+                                if (res.code == "ok") {
+                                    this.submitReportSon()
+                                } else {
+                                    this.$dialog.confirm({
+                                        title: '提示',
+                                        message: res.msg + ',是否忽略并提交?'
+                                    }).then(() => {
+                                        this.submitReportSon()
+                                    }).catch(() => { })
+                                }
+                            }).catch(err => { this.$toast.clear(); });
                         } else {
                         } else {
-                            this.submitReportSon()
+                            //提交时,做工时时长不足的提醒
+                            if (this.totalReportHours < this.user.timeType.allday) {
+                                this.$dialog.confirm({
+                                    title: '提示',
+                                    message: '当日工时不足' + this.user.timeType.allday.toFixed(1) + '小时,是否确定提交?'
+                                }).then(() => {
+                                    this.submitReportSon()
+                                }).catch(() => { })
+                            } else {
+                                this.submitReportSon()
+                            }
                         }
                         }
                     }
                     }
                 }).catch((err) => {
                 }).catch((err) => {
@@ -2231,7 +2258,7 @@ export default {
                 }
                 }
             }
             }
             //针对凡己,不校验考勤时长
             //针对凡己,不校验考勤时长
-            if (this.user.companyId != 3918 && this.reportTimeType.type == 1 && this.report.time) {
+            if (this.user.companyId != 3918 && this.user.companyId != 5978 && this.reportTimeType.type == 1 && this.report.time) {
                 var totalTime = 0;
                 var totalTime = 0;
                 for (var t = 0; t < this.form.domains.length; t++) {
                 for (var t = 0; t < this.form.domains.length; t++) {
                     totalTime += parseFloat(this.form.domains[t].workingTime);
                     totalTime += parseFloat(this.form.domains[t].workingTime);

+ 40 - 3
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue

@@ -422,9 +422,14 @@
                     <van-button square block type="info" @click="submitReport(0)" native-type="submit" style="width:50%;float:right;">
                     <van-button square block type="info" @click="submitReport(0)" native-type="submit" style="width:50%;float:right;">
                         <div>提交</div>
                         <div>提交</div>
                     </van-button>
                     </van-button>
+                    
                 </div>
                 </div>
                 <div style="padding-bottom:10px;" v-if="!temporaryStorage">
                 <div style="padding-bottom:10px;" v-if="!temporaryStorage">
-                    <van-button square block type="info" @click="submitReport(0)" native-type="submit" style="width:100%;float:right;">
+                    <van-button v-if="this.user.companyId != 5978" square block type="info" @click="submitReport(0)" native-type="submit" style="width:100%;float:right;">
+                        <div>提交</div>
+                    </van-button>
+                    <!--景昱没有暂存功能,直接加在这里-->
+                    <van-button v-if="this.user.companyId == 5978" square block type="info" @click="checkDateWorkTime()" native-type="submit" style="width:100%;float:right;">
                         <div>提交</div>
                         <div>提交</div>
                     </van-button>
                     </van-button>
                 </div>
                 </div>
@@ -1915,7 +1920,39 @@
                             }]
                             }]
                 // console.log(this.currentForm);
                 // console.log(this.currentForm);
             },
             },
-
+            checkDateWorkTime() {
+                var array = [];
+                for(let m in this.form){
+                    let allhours = 0
+                    for(let n in this.form[m].domains){
+                        if(this.form[m].domains[n].projectId){
+                            allhours += this.form[m].domains[n].workingTime
+                        }
+                    }
+                    if (allhours) {
+                        var workData = {date: this.form[m].createDate, workingTime: allhours};
+                        array.push(workData);
+                    }
+                }
+                if (array.length > 0) {
+                    this.$axios.post("/report/checkBeiSengCardTime", { userId:this.user.id, dateWorkingTime:JSON.stringify(array)})
+                        .then(res => {
+                            this.flgLg = true
+                            if (res.code == "ok") {
+                                this.submitReport(0)
+                            } else {
+                                this.$dialog.confirm({
+                                    title: '提示',
+                                    message: res.msg + ',是否忽略并提交?'
+                                }).then(() => {
+                                    this.submitReport(0)
+                                }).catch(() => { })
+                            }
+                        }).catch(err => { this.$toast.clear(); });
+                } else {
+                    submitReport(0);
+                }
+            },
             // 提交日报
             // 提交日报
             submitReport(isDraft) {
             submitReport(isDraft) {
                 if(this.inbtn != 999) {
                 if(this.inbtn != 999) {
@@ -1993,7 +2030,7 @@
                     }
                     }
                 }
                 }
                 //针对凡己,不校验考勤时长
                 //针对凡己,不校验考勤时长
-                if(this.user.companyId != 3918 && (this.user.timeType.showDdCardtime == 1 || this.user.timeType.showCorpwxCardtime == 1) && this.reportTimeType.type == 1){
+                if(this.user.companyId != 3918 && this.user.companyId != 5978  && (this.user.timeType.showDdCardtime == 1 || this.user.timeType.showCorpwxCardtime == 1) && this.reportTimeType.type == 1){
                     let tips = ''
                     let tips = ''
                     for(let m in this.form){
                     for(let m in this.form){
                         let allhours = 0
                         let allhours = 0