ソースを参照

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

seyason 1 年間 前
コミット
8b8abc05d5
13 ファイル変更512 行追加105 行削除
  1. 26 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/BusinessOpportunityController.java
  2. 28 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/CustomController.java
  3. 1 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/ClueMapper.java
  4. 10 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/BusinessOpportunityService.java
  5. 11 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/CustomService.java
  6. 117 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/BusinessOpportunityServiceImpl.java
  7. 7 3
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ClueServiceImpl.java
  8. 117 4
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CustomServiceImpl.java
  9. 10 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  10. 4 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  11. 89 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  12. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/budgetReview.vue
  13. 91 94
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

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

@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
@@ -178,6 +179,31 @@ public class BusinessOpportunityController {
     }
 
 
+    // 上传
+    @RequestMapping("uploadFile")
+    public Object uploadFile(BusinessItemCustom bo, HttpServletRequest request, MultipartFile file) throws Exception {
+        return bOservice.uploadFile(bo, request, file);
+    }
+
+    //下载
+    @RequestMapping("downFile")
+    public Object downFile(UploadFile file, HttpServletRequest request, HttpServletResponse response) throws Exception {
+        return bOservice.downFile(file, request, response);
+    }
+
+    //删除
+    @RequestMapping("deleteFile")
+    public Object downFile(UploadFile file, HttpServletRequest request) throws Exception {
+        return bOservice.deleteFile(file, request);
+    }
+
+    //重命名
+    @RequestMapping("reFileName")
+    public Object reFileName(UploadFile uploadFile, HttpServletRequest request) throws Exception {
+        return bOservice.reFileName(uploadFile, request);
+    }
+
+
 
 
 }

+ 28 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/CustomController.java

@@ -3,6 +3,7 @@ package com.management.platform.controller;
 
 import com.management.platform.entity.Clue;
 import com.management.platform.entity.Custom;
+import com.management.platform.entity.UploadFile;
 import com.management.platform.entity.User;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.CustomService;
@@ -12,8 +13,10 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -115,7 +118,7 @@ public class CustomController {
 
     // 认领&转移线索
     @RequestMapping("claim")
-    public Object claim( Custom custom, HttpServletRequest request) {
+    public Object claim(Custom custom, HttpServletRequest request) {
         User user = userMapper.selectById(request.getHeader("Token"));
         HttpRespMsg msg = new HttpRespMsg();
         msg.setMsg("操作成功");
@@ -123,6 +126,30 @@ public class CustomController {
         return msg;
     }
 
+    // 上传
+    @RequestMapping("uploadFile")
+    public Object uploadFile(Custom custom, HttpServletRequest request, MultipartFile file) throws Exception {
+        return customService.uploadFile(custom, request, file);
+    }
+
+    //下载
+    @RequestMapping("downFile")
+    public Object downFile(UploadFile file, HttpServletRequest request, HttpServletResponse response) throws Exception {
+        return customService.downFile(file, request, response);
+    }
+
+    //删除
+    @RequestMapping("deleteFile")
+    public Object downFile(UploadFile file, HttpServletRequest request) throws Exception {
+        return customService.deleteFile(file, request);
+    }
+
+    //重命名
+    @RequestMapping("reFileName")
+    public Object reFileName(UploadFile uploadFile, HttpServletRequest request) throws Exception {
+        return customService.reFileName(uploadFile, request);
+    }
+
 
 }
 

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

@@ -33,5 +33,5 @@ public interface ClueMapper extends BaseMapper<Clue> {
             "(select `name` from sys_dict where code = 'CustomLevel' and id =  customer_level_id) customerLevelValue ," +
             "(select `name` from user where id = incharger_id ) inchargerName" +
             " from clue where id = #{id}")
-    Clue selectById2Info(Integer id);
+    Clue selectById2Info(@Param("id") Integer id);
 }

+ 10 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/BusinessOpportunityService.java

@@ -3,8 +3,10 @@ package com.management.platform.service;
 import com.management.platform.entity.*;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -38,4 +40,12 @@ public interface BusinessOpportunityService extends IService<BusinessOpportunity
     Object exportData(BusinessOpportunity bo, HttpServletRequest request) throws Exception;
 
     HttpRespMsg saveProduct(BusinessOpportunity bo, User user);
+
+    Object uploadFile(BusinessItemCustom bo, HttpServletRequest request, MultipartFile file);
+
+    Object downFile(UploadFile file, HttpServletRequest request, HttpServletResponse response);
+
+    Object deleteFile(UploadFile file, HttpServletRequest request);
+
+    Object reFileName(UploadFile uploadFile, HttpServletRequest request);
 }

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

@@ -2,10 +2,13 @@ package com.management.platform.service;
 
 import com.management.platform.entity.Custom;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.UploadFile;
 import com.management.platform.entity.User;
 import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -35,4 +38,12 @@ public interface CustomService extends IService<Custom> {
     HttpRespMsg getList(Custom custom, HttpServletRequest request);
 
     HttpRespMsg getDeleteList(Custom custom, HttpServletRequest request);
+
+    Object uploadFile(Custom custom, HttpServletRequest request, MultipartFile file);
+
+    Object downFile(UploadFile file, HttpServletRequest request, HttpServletResponse response);
+
+    Object deleteFile(UploadFile file, HttpServletRequest request);
+
+    Object reFileName(UploadFile uploadFile, HttpServletRequest request);
 }

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

@@ -11,18 +11,27 @@ import com.management.platform.mapper.*;
 import com.management.platform.service.BusinessOpportunityService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.service.WxCorpInfoService;
+import com.management.platform.util.FileUtil;
 import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
 import java.math.BigDecimal;
+import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.UUID;
 
 /**
  * <p>
@@ -224,6 +233,114 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
         return msg;
     }
 
+    @Value(value = "${upload.file}")
+    private String filePath;
+    @Override
+    public Object uploadFile(BusinessItemCustom bo, HttpServletRequest request, MultipartFile file) {
+        User user = userMapper.selectById(request.getHeader("token"));
+        if (!file.isEmpty()) { // 检查上传的文件是否为空
+            try {
+                // 获取上传文件的原始文件名
+                String originalFilename = file.getOriginalFilename();
+
+                // 创建文件存储目录
+                File uploadDir = new File(filePath);
+                if (!uploadDir.exists()) {
+                    uploadDir.mkdirs();
+
+                }
+                UploadFile uf = new UploadFile();
+                uf.setName(originalFilename);
+                String realName = "";
+                int pos = originalFilename.lastIndexOf(".");
+                String suffix = originalFilename.substring(pos).toLowerCase();
+                //用uuid替换原始的文件名
+                String purFName = UUID.randomUUID().toString().replaceAll("-", "");
+                realName = purFName + suffix;
+
+
+                uf.setPath(filePath + realName);
+                uf.setCode("business");
+                uf.setItemId(bo.getId());
+                uf.setRealName(realName);
+                uf.setCreateTime(new Date());
+                uf.setCreateId(user.getId());
+                uploadFileMapper.insert(uf);
+                // 构建上传文件的目标路径
+                String filePath1 = filePath + realName;
+
+                // 在服务器上创建文件
+                File dest = new File(filePath1);
+
+                // 将上传的文件保存到目标路径
+                file.transferTo(dest);
+
+                // 文件上传成功的响应消息
+                HttpRespMsg msg = new HttpRespMsg();
+                msg.setMsg("上传成功");
+                return msg;
+            } catch (IOException e) {
+                e.printStackTrace();
+                // 文件上传失败的响应消息
+                HttpRespMsg msg = new HttpRespMsg();
+                msg.setError("上传成功失败");
+                return msg;
+            }
+        } else {
+            // 文件为空的响应消息
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError("请选择上传文件");
+            return msg;
+        }    }
+
+    @Override
+    public Object downFile(UploadFile file, HttpServletRequest request, HttpServletResponse response) {
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            ServletOutputStream os = response.getOutputStream();
+            UploadFile uploadFile = uploadFileMapper.selectById(file.getId());
+            if (uploadFile == null ){
+                msg.setError("文件未找到");
+                return msg;
+            }
+
+            File uploadFile1 = new File(uploadFile.getPath());
+            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(uploadFile.getName(), "UTF-8"));
+            response.setContentType("application/octet-stream");
+            // 读取文件的字节流
+            os.write(FileUtil.readFileByBytes(uploadFile1));
+            os.flush();
+
+        } catch (IOException e) {
+            msg.setError(MessageUtils.message("file.error"));
+            e.printStackTrace();
+        }
+        return msg;
+    }
+
+    @Override
+    public Object deleteFile(UploadFile file, HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            UploadFile uploadFile = uploadFileMapper.selectById(file.getId());
+            uploadFileMapper.deleteById(uploadFile.getId());
+            String realName = uploadFile.getRealName();
+            File file1 = new File(path + realName);
+            file1.delete();
+            msg.setMsg("删除成功");
+        } catch (Exception e) {
+            e.printStackTrace();
+            msg.setError("删除失败");
+        }
+        return msg;
+    }
+
+    @Override
+    public Object reFileName(UploadFile uploadFile, HttpServletRequest request) {
+        return uploadFileMapper.update(null, new UpdateWrapper<UploadFile>().eq("id", uploadFile.getId()).set("name", uploadFile.getName()));
+
+    }
+
     private BusinessOpportunity setNull(BusinessOpportunity bo) {
         if (bo.getPlate1() == "") {
             bo.setPlate1(null);

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

@@ -306,7 +306,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
                 realName = purFName + suffix;
 
 
-                uf.setPath(filePath + originalFilename);
+                uf.setPath(filePath + realName);
                 uf.setCode("clue");
                 uf.setItemId(clue.getId());
                 uf.setRealName(realName);
@@ -370,9 +370,13 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
         try {
             ServletOutputStream os = response.getOutputStream();
             UploadFile uploadFile = uploadFileMapper.selectById(file.getId());
+            if (uploadFile == null ){
+                msg.setError("文件未找到");
+                return msg;
+            }
 
-            File uploadFile1 = new File(path + uploadFile.getRealName());
-            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
+            File uploadFile1 = new File(uploadFile.getPath());
+            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(uploadFile.getName(), "UTF-8"));
             response.setContentType("application/octet-stream");
             // 读取文件的字节流
             os.write(FileUtil.readFileByBytes(uploadFile1));

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

@@ -7,16 +7,22 @@ import com.management.platform.mapper.*;
 import com.management.platform.service.CustomService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.service.SysFunctionService;
+import com.management.platform.util.FileUtil;
 import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.*;
 
 /**
  * <p>
@@ -260,6 +266,113 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
     }
 
 
+    @Value(value = "${upload.file}")
+    private String filePath;
+    @Override
+    public Object uploadFile(Custom custom, HttpServletRequest request, MultipartFile file) {
+        User user = userMapper.selectById(request.getHeader("token"));
+        if (!file.isEmpty()) { // 检查上传的文件是否为空
+            try {
+                // 获取上传文件的原始文件名
+                String originalFilename = file.getOriginalFilename();
+
+                // 创建文件存储目录
+                File uploadDir = new File(filePath);
+                if (!uploadDir.exists()) {
+                    uploadDir.mkdirs();
+
+                }
+                UploadFile uf = new UploadFile();
+                uf.setName(originalFilename);
+                String realName = "";
+                int pos = originalFilename.lastIndexOf(".");
+                String suffix = originalFilename.substring(pos).toLowerCase();
+                //用uuid替换原始的文件名
+                String purFName = UUID.randomUUID().toString().replaceAll("-", "");
+                realName = purFName + suffix;
+
+
+                uf.setPath(filePath + realName);
+                uf.setCode("custom");
+                uf.setItemId(custom.getId());
+                uf.setRealName(realName);
+                uf.setCreateTime(new Date());
+                uf.setCreateId(user.getId());
+                uploadFileMapper.insert(uf);
+                // 构建上传文件的目标路径
+                String filePath1 = filePath + realName;
+
+                // 在服务器上创建文件
+                File dest = new File(filePath1);
+
+                // 将上传的文件保存到目标路径
+                file.transferTo(dest);
+
+                // 文件上传成功的响应消息
+                HttpRespMsg msg = new HttpRespMsg();
+                msg.setMsg("上传成功");
+                return msg;
+            } catch (IOException e) {
+                e.printStackTrace();
+                // 文件上传失败的响应消息
+                HttpRespMsg msg = new HttpRespMsg();
+                msg.setError("上传成功失败");
+                return msg;
+            }
+        } else {
+            // 文件为空的响应消息
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError("请选择上传文件");
+            return msg;
+        }
+    }
+
+    @Override
+    public Object downFile(UploadFile file, HttpServletRequest request, HttpServletResponse response) {
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            ServletOutputStream os = response.getOutputStream();
+            UploadFile uploadFile = uploadFileMapper.selectById(file.getId());
+            if (uploadFile == null ){
+                msg.setError("文件未找到");
+                return msg;
+            }
+
+            File uploadFile1 = new File(uploadFile.getPath());
+            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(uploadFile.getName(), "UTF-8"));
+            response.setContentType("application/octet-stream");
+            // 读取文件的字节流
+            os.write(FileUtil.readFileByBytes(uploadFile1));
+            os.flush();
+
+        } catch (IOException e) {
+            msg.setError(MessageUtils.message("file.error"));
+            e.printStackTrace();
+        }
+        return msg;    }
+
+    @Override
+    public Object deleteFile(UploadFile file, HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            UploadFile uploadFile = uploadFileMapper.selectById(file.getId());
+            uploadFileMapper.deleteById(uploadFile.getId());
+            String realName = uploadFile.getRealName();
+            File file1 = new File(uploadFile.getPath());
+            file1.delete();
+            msg.setMsg("删除成功");
+        } catch (Exception e) {
+            e.printStackTrace();
+            msg.setError("删除失败");
+        }
+        return msg;    }
+
+    @Override
+    public Object reFileName(UploadFile uploadFile, HttpServletRequest request) {
+        return uploadFileMapper.update(null, new UpdateWrapper<UploadFile>().eq("id", uploadFile.getId()).set("name", uploadFile.getName()));
+    }
+
+
     private Custom setNull(Custom clue) {
         if (clue.getPlate1() == "") {
             clue.setPlate1(null);

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

@@ -1993,6 +1993,16 @@ public class ReportController {
         return reportService.getUserDailyWorkTime(request, startDate, endDate);
     }
 
+    @RequestMapping("/getUserDailyWorkTimeReminder")
+    public HttpRespMsg getUserDailyWorkTimeReminder(HttpServletRequest request, String startDate, String endDate) throws Exception{
+        return reportService.getUserDailyWorkTimeReminder(request, startDate, endDate);
+    }
+
+    @RequestMapping("/exportUserDailyWorkTimeReminder")
+    public HttpRespMsg exportUserDailyWorkTimeReminder(HttpServletRequest request, String startDate, String endDate) throws Exception{
+        return reportService.exportUserDailyWorkTimeReminder(request, startDate, endDate);
+    }
+
     @RequestMapping("/getNoReportUserList")
     public HttpRespMsg getNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId) {
         return reportService.getNoReportUserList(request, startDate, endDate,noReportDeptId);

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

@@ -153,4 +153,8 @@ public interface ReportService extends IService<Report> {
     HttpRespMsg getDetailReportById(Integer reportId, HttpServletRequest request);
 
     HttpRespMsg changeReminder(HttpServletRequest request) throws Exception;
+
+    HttpRespMsg getUserDailyWorkTimeReminder(HttpServletRequest request, String startDate, String endDate) throws Exception;
+
+    HttpRespMsg exportUserDailyWorkTimeReminder(HttpServletRequest request, String startDate, String endDate) throws Exception;
 }

+ 89 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -4399,11 +4399,13 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             String date = new SimpleDateFormat("yyyy-MM-dd").format((Date)data.get("createDate"));
             map.put("workingTime", data.get("workingTime"));
             map.put("createDate", date);
+            map.put("cardTime", 0);
             //针对景昱 5978 校验填报工时是否超过考勤
             if(user.getCompanyId().equals(5978)){
                 map.put("exceedCardTime",0);
                 Optional<UserFvTime> first = userFvTimeList.stream().filter(u -> u.getWorkDate().isEqual(LocalDate.parse(date, df)) && u.getUserId().equals(id)).findFirst();
                 if(first.isPresent()){
+                    map.put("cardTime",first.get().getWorkHours());
                     if(first.get().getWorkHours()!=null){
                         Optional<User> optional = userList.stream().filter(u -> u.getId().equals(id)).findFirst();
                         User targetUser = optional.get();
@@ -4438,7 +4440,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 lastUserData.name = name;
                 lastUserData.departmentName = departmentName;
                 lastUserData.corpwxUserId = corpwxUserId;
-                lastUserData.corpwxDeptId = departmentName;
+                lastUserData.corpwxDeptId = String.valueOf(corpwxDeptId);
                 lastUserData.worktimeList = new ArrayList<>();
                 lastUserData.worktimeList.add(map);
                 userMonthWorks.add(lastUserData);
@@ -8999,4 +9001,90 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         }
         return msg;
     }
+
+    @Override
+    public HttpRespMsg getUserDailyWorkTimeReminder(HttpServletRequest request, String startDate, String endDate) throws Exception {
+        HttpRespMsg msg=new HttpRespMsg();
+        DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        HttpRespMsg userDailyWorkTime = getUserDailyWorkTime(request, startDate, endDate);
+        List<UserFvTime> userFvTimeList = userFvTimeMapper.selectList(new LambdaQueryWrapper<UserFvTime>().between(UserFvTime::getWorkDate, startDate, endDate));
+        Map<String, Object> objectMap = (Map<String, Object>) userDailyWorkTime.getData();
+        List<UserMonthWork > mapList = (List<UserMonthWork >) objectMap.get("list");
+        List<LocalDate> days = getDays(LocalDate.parse(startDate, df), LocalDate.parse(endDate, df));
+        List<Map<String, Object>> result=new ArrayList<>();
+        mapList.forEach(m->{
+            List<Map<String, Object>> worktimeList = (List<Map<String, Object>>) m.worktimeList;
+            for (LocalDate date : days) {
+                boolean match = worktimeList.stream().anyMatch(www -> www.get("createDate").equals(date.format(df)));
+                if(!match){
+                    Map<String,Object> ww=new HashMap<>();
+                    ww.put("createDate",date.format(df));
+                    ww.put("exceedCardTime",0);
+                    ww.put("workingTime",0);
+//                    ww.put("name",m.name);
+//                    ww.put("corpwxDeptId",m.corpwxDeptId);
+//                    ww.put("corpwxUserId",m.corpwxUserId);
+//                    ww.put("departmentName",m.departmentName);
+//                    ww.put("userId",m.userId);
+                    worktimeList.add(ww);
+                }
+                if(worktimeList.size()>0){
+                    worktimeList.forEach(w->{
+                        w.put("cardTime",0);
+                        Optional<UserFvTime> first = userFvTimeList.stream().filter(u -> u.getWorkDate().isEqual(date) && u.getUserId().equals(m.userId)).findFirst();
+                        if(first.isPresent()){
+                            w.put("cardTime",first.get().getWorkHours());
+                        }
+                        w.put("name",m.name);
+                        w.put("corpwxDeptId",m.corpwxDeptId);
+                        w.put("corpwxUserId",m.corpwxUserId);
+                        w.put("departmentName",m.departmentName);
+                        w.put("userId",m.userId);
+                    });
+                }
+            }
+            result.addAll(worktimeList);
+        });
+        Map<String,Object> map=new HashMap<>();
+        map.put("list",result);
+        msg.setData(map);
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg exportUserDailyWorkTimeReminder(HttpServletRequest request, String startDate, String endDate) throws Exception {
+        HttpRespMsg timeReminder = getUserDailyWorkTimeReminder(request, startDate, endDate);
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, companyId));
+        Map<String, Object> data = (Map<String, Object>) timeReminder.getData();
+        List<Map<String, Object>> mapList = (List<Map<String, Object>>) data.get("list");
+        List<List<String>> dataList=new ArrayList<>();
+        List<String> titleList=new ArrayList<>();
+        titleList.add("日期");
+        titleList.add("姓名");
+        titleList.add("部门");
+        titleList.add("填报工时");
+        titleList.add("考勤工时");
+        titleList.add("是否异常");
+        titleList.add("催办");
+        dataList.add(titleList);
+        for (Map<String, Object> map : mapList) {
+            List<String> item=new ArrayList<>();
+            item.add(String.valueOf(map.get("createDate")));
+            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                item.add("$userName="+String.valueOf(map.get("corpwxUserId"))+"$");
+                item.add("$departmentName="+String.valueOf(map.get("corpwxDeptId"))+"$");
+            }else {
+                item.add(String.valueOf(map.get("name")));
+                item.add(String.valueOf(map.get("departmentName")));
+            }
+            item.add(String.valueOf(map.get("workingTime")));
+            item.add(String.valueOf(map.get("cardTime")));
+            item.add(Integer.valueOf(String.valueOf(map.get("exceedCardTime")))==0?"否":"是");
+            item.add(Integer.valueOf(String.valueOf(map.get("exceedCardTime")))==0?"":"变更提醒");
+            dataList.add(item);
+        }
+        String fileName="工时异常表"+System.currentTimeMillis();
+        return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,fileName,dataList,path);
+    }
 }

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/project/budgetReview.vue

@@ -369,7 +369,7 @@ export default {
             const { projectId, dateRange, checkUserId, status } = this.screeningConditionForm;
             const params = {
                 ...(projectId && { projectId }),
-                ...(dateRange && { startTime: dateRange[0], endTime: dateRange[1] }),
+                ...(dateRange && { startDate: dateRange[0], endDate: dateRange[1] }),
                 ...(checkUserId && { checkUserId }),
                 ...(status && { status }),
             };

+ 91 - 94
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -1627,7 +1627,7 @@
           <el-alert style="position:absolute;bottom:0;z-index:10;" v-if="isMore" :title="$t('message.noMoreData')" type="success" center show-icon></el-alert>
         </el-tab-pane>
 
-        <el-tab-pane v-if="user.companyId==5978" :label="'工时填报明细'" name="third">
+        <el-tab-pane v-if="user.companyId==5978" :label="'工时异常明细'" name="third">
           <div class="selectworktime_export" style="margin-top:10px;">
             <!-- <div class="selectworktime_export_l">
               <el-date-picker
@@ -1665,7 +1665,7 @@
               >
               <el-link
               type="primary"
-              @click="exportMembWorkHours()"
+              @click="exportMembWorkHoursReminder()"
               >{{$t('export.exportData')}}</el-link
              >
             </div>
@@ -1682,113 +1682,50 @@
             v-loading="tbload"
             :lazy="true"
           >
-            <el-table-column width="75" type="index" fixed="left" :label="$t('headerTop.serialNumber')">
+            <el-table-column width="180" type="index" fixed="left" :label="'日期'">
               <template slot-scope="scope">
-                {{ scope.$index + 1 }}
+                {{ scope.row.createDate}}
               </template>
             </el-table-column>
 
-            <el-table-column width="105" prop="name" fixed="left" :label="$t('lable.name')">
+            <el-table-column width="160" prop="name" fixed="left" :label="$t('lable.name')">
                 <template slot-scope="scope">
-                    <span :style="scope.row.worktimeList.length==0?'color:red':''">
-                        <span v-if="user.userNameNeedTranslate == 1"><ww-open-data type='userName' :openid='scope.row.name'></ww-open-data></span>
-                        <span v-if="user.userNameNeedTranslate != 1">{{scope.row.name}}</span>
+                    <span v-if="user.userNameNeedTranslate == 1"><ww-open-data type='userName' :openid='scope.row.name'></ww-open-data></span>
+                    <span v-if="user.userNameNeedTranslate != 1">{{scope.row.name}}</span>
                         <!-- {{scope.row.name}} -->
-                    </span>
                 </template>
             </el-table-column>
-            <el-table-column prop="departmentName" fixed="left" :label="$t('lable.department')">
+            <el-table-column prop="departmentName" width="170" fixed="left" :label="$t('lable.department')">
                 <template slot-scope="scope">
                     <span v-if="user.userNameNeedTranslate == 1"><ww-open-data type='departmentName' :openid='scope.row.departmentName'></ww-open-data></span>
                     <span v-if="user.userNameNeedTranslate != 1">{{scope.row.departmentName}}</span>
                 </template>
             </el-table-column>
-            <el-table-column
-              min-width="105"
-              v-for="(item, index) in pickDateArray"
-              :key="index"
-              :label="item.label"
-              align="center"
-            >
+
+            <el-table-column width="160" type="index" fixed="left" :label="'填报工时'">
               <template slot-scope="scope">
-                <div
-                  style="color: red"
-                  v-if="
-                    scope.row.worktimeList.filter(
-                      (w) =>
-                        w.createDate==item.date
-                    ).length > 0 &&
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    )[0].workingTime < reportTimeType.allday
-                  "
-                >
-                  {{
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    )[0].workingTime.toFixed(1)
-                  }}
-                </div>
-                <div
-                  style="color: #20a0ff"
-                  v-if="
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    ).length > 0 &&
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    )[0].workingTime > reportTimeType.allday
-                  "
-                >
-                  {{
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    )[0].workingTime.toFixed(1)
-                  }}
-                </div>
-                <div
-                  v-if="
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    ).length > 0 &&
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    )[0].workingTime == reportTimeType.allday
-                  "
-                >
-                  {{
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    )[0].workingTime
-                  }}
-                </div>
-                <div
-                  v-if="
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    ).length == 0
-                  "
-                >
-                  0
-                </div>
-                <div
-                  v-if="
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    ).length > 0 &&
-                    typeof scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    )[0].workingTime == 'string'
-                  "
-                >
-                  {{
-                    scope.row.worktimeList.filter(
-                      (w) =>w.createDate==item.date
-                    )[0].workingTime
-                  }}
-                </div>
+                {{ scope.row.workingTime}}
+              </template>
+            </el-table-column>
+
+            <el-table-column width="160" type="index" fixed="left" :label="'考勤工时'">
+              <template slot-scope="scope">
+                {{ scope.row.cardTime}}
               </template>
             </el-table-column>
+
+            <el-table-column width="160" type="index" fixed="left" :label="'是否异常'">
+              <template slot-scope="scope">
+                {{ scope.row.exceedCardTime==0?'否':'是'}}
+              </template>
+            </el-table-column>
+
+            <el-table-column width="160" type="index" fixed="left" :label="'催办'">
+              <template slot-scope="scope">
+                {{ scope.row.exceedCardTime==0?'':'变更提醒'}}
+              </template>
+            </el-table-column>
+
           </el-table>
           <el-alert style="position:absolute;bottom:0;z-index:10;" v-if="isFlag" :title="$t('message.loading')+'...'" type="success" center :closable="false" show-icon></el-alert>
           <el-alert style="position:absolute;bottom:0;z-index:10;" v-if="isMore" :title="$t('message.noMoreData')" type="warning" center show-icon></el-alert>
@@ -3887,8 +3824,10 @@
     handleClick(t,e){
       if (t.name == "second") {
         this.showMonthNotWorkTime()
-      }else{
+      }else if(t.name == "first"){
         this.showMonthWorkTime(t.name)
+      }else if(t.name == "third"){
+        this.showMonthWorkTimeReminder()
       }
     },
     //导出员工每日填报工时数
@@ -3914,6 +3853,28 @@
         }
       );
     },
+    exportMembWorkHoursReminder() {   
+      this.http.post(
+        "/report/exportUserDailyWorkTimeReminder",
+        {
+          // month: this.date,
+          startDate: this.WorktimeDatepickValueForMonth[0],
+          endDate: this.WorktimeDatepickValueForMonth[1],
+        },
+        (res) => {
+          if (res.code == "ok") {
+            let url = res.data;
+            this.downloadByA('工时异常表.xlsx', url);
+          }
+        },
+        (error) => {
+          this.$message({
+            message: error,
+            type: "error",
+          });
+        }
+      );
+    },
     exportMembNotWorkHours() {
       
       this.http.post(
@@ -4020,6 +3981,42 @@
         }
       );
     },
+    showMonthWorkTimeReminder() {
+      this.monthTotalPage = 0,
+        this.tbload = true
+        let parameter={}
+        parameter={
+            startDate: this.WorktimeDatepickValueForMonth[0],
+            endDate: this.WorktimeDatepickValueForMonth[1],
+        }
+      this.http.post(
+        "/report/getUserDailyWorkTimeReminder",
+        parameter,
+        (res) => {
+          if (res.code == "ok") {
+            this.tbload = false;
+            this.monthWorkData = res.data.list;
+            this.monthTotal = res.data.list.length
+            if (this.monthWorkData.length > 50) {
+                this.monthWorkDataS = this.monthWorkData.slice(0,50);
+            }else{
+                this.monthWorkDataS = this.monthWorkData
+            }
+            this.searchScreen(0)
+            this.$nextTick(function(){
+                this.$refs.hasworkTbl.doLayout();
+            });
+          }
+        },
+        (error) => {
+            this.tbload = false
+          this.$message({
+            message: error,
+            type: "error",
+          });
+        }
+      );
+    },
     // tableListener(){
     //   let that = this;
     //   let dom = that.$refs.hasworkTbl.bodyWrapper;