Kaynağa Gözat

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

Min 1 yıl önce
ebeveyn
işleme
f81e0ee6e2

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

@@ -1435,8 +1435,8 @@ public class ReportController {
         }
 
         HttpRespMsg httpRespMsg = reportService.editReport(reportList, createDate.length > 0 ? createDate[0] : null, targetUserList, hourCost, user.getCompanyId());
-        //【上海绎维】、【火石演示】、【博通容合】使用
-        if (company.getId() == 862 || company.getId() == 10 || company.getId() == 3344) {
+        //填报自动通过功能:【上海绎维】、【火石演示】、【博通容合】、【威派格】使用
+        if (company.getId() == 862 || company.getId() == 10 || company.getId() == 3344 || company.getId() == 936) {
             //项目审核人是提交人的情况,直接审核
             List<String> reportIds = new ArrayList<>();
             for (int i = 0; i<id.length; i++) {
@@ -1614,8 +1614,6 @@ public class ReportController {
     }
 
     /**
-     * 按某人某日期审批通过报告
-     * id 要通过的报告的用户id
      * reportIds 报告id
      */
     @RequestMapping("/approve")
@@ -1626,7 +1624,6 @@ public class ReportController {
 
     /**
      * 按某人某日期审批未通过报告 撤销通过报告
-     * id 要未通过的报告的用户id
      * date 日期 格式yyyy-mm-dd
      */
     @RequestMapping("/deny")
@@ -1776,6 +1773,12 @@ public class ReportController {
         return reportService.importData(companyId,withCheckIn, file, request);
     }
 
+    @RequestMapping("/importNewData")
+    public HttpRespMsg importNewData(Integer companyId,
+                                  MultipartFile file, HttpServletRequest request) {
+        return reportService.importNewData(companyId, file, request);
+    }
+
     @RequestMapping("/listImportByState")
     public HttpRespMsg listDeptImportByState(
                                       Integer projectId,

+ 32 - 16
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskGroupController.java

@@ -306,32 +306,48 @@ public class TaskGroupController {
         HttpRespMsg msg = new HttpRespMsg();
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
-        Department department = departmentMapper.selectById(user.getDepartmentId());
+        Department department = null;
+        Integer dpId = user.getDepartmentId();
+        if (dpId != null && dpId > 0) {
+            department = departmentMapper.selectById(dpId);
+        }
+
         Integer projectId = item.getProjectId();
         Project project = projectMapper.selectById(projectId);
         QueryWrapper<TaskGroup> queryWrapper = new QueryWrapper<TaskGroup>();
         queryWrapper.eq("project_id", projectId);
-        List<TaskGroup> list = taskGroupService.list(queryWrapper);
-        //处理审核人,如果就是自己,得换成项目经理
-        for (TaskGroup taskGroup : list) {
-            if (token.equals(taskGroup.getInchargerId())) {
-                taskGroup.setInchargerId(project.getInchargerId());
+        List<TaskGroup> list = new ArrayList<>();
+        List<GroupParticipator> groupParticipatorList = groupParticipatorMapper.selectList(new QueryWrapper<GroupParticipator>().eq("user_id", token));
+        if (groupParticipatorList.size() > 0) {
+            List<Integer> groupIds = groupParticipatorList.stream().map(GroupParticipator::getGroupId).collect(Collectors.toList());
+            QueryWrapper<TaskGroup> queryWrapper1 = new QueryWrapper<TaskGroup>().eq("project_id", item.getProjectId());
+            queryWrapper1.and(wrapper->wrapper.in("id", groupIds).or().eq("incharger_id", token));
+
+            list = taskGroupService.list(queryWrapper1);
+            //处理审核人,如果就是自己,得换成项目经理
+            for (TaskGroup taskGroup : list) {
+                if (token.equals(taskGroup.getInchargerId())) {
+                    taskGroup.setInchargerId(project.getInchargerId());
+                }
                 //如果项目经理也是自己,就换成自己所在部门负责人
-                if (token.equals(project.getInchargerId())) {
+                if (token.equals(project.getInchargerId()) && department != null) {
                     taskGroup.setInchargerId(department.getManagerId());
                 }
             }
-        }
-        List<String> collect = list.stream().map(TaskGroup::getInchargerId).collect(Collectors.toList());
-        if (collect.size() > 0) {
-            userMapper.selectList(new QueryWrapper<User>().in("id", collect)).forEach(u->{
-                list.stream().forEach(g->{
-                    if (u.getId().equals(g.getInchargerId())) {
-                        g.setInchargerName(u.getName());
-                    }
+            List<String> collect = list.stream().map(TaskGroup::getInchargerId).collect(Collectors.toList());
+            if (collect.size() > 0) {
+                final List<TaskGroup> list1 = list;
+                userMapper.selectList(new QueryWrapper<User>().in("id", collect)).forEach(u->{
+                    list1.stream().forEach(g->{
+                        if (u.getId().equals(g.getInchargerId())) {
+                            g.setInchargerName(u.getName());
+                        }
+                    });
                 });
-            });
+            }
+
         }
+
         msg.data = list;
         return msg;
     }

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

@@ -68,6 +68,9 @@ public interface ReportService extends IService<Report> {
 
     HttpRespMsg importData(Integer companyId, Integer withCheckIn, MultipartFile file, HttpServletRequest request);
 
+    //新版导入日报,采用项目在行上的模式
+    HttpRespMsg importNewData(Integer companyId, MultipartFile file, HttpServletRequest request);
+
     HttpRespMsg saveProjectTime(Integer companyId, List<Report> reportList, JSONArray userReportArray);
 
     HttpRespMsg listDeptImportByState(String leaderId,

+ 357 - 21
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -4378,6 +4378,331 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         return msg;
     }
 
+    @Override
+    public HttpRespMsg importNewData(Integer companyId, MultipartFile multipartFile, HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+        TimeType timeType = timeTypeMapper.selectById(user.getCompanyId());
+        //对于存在预算成本的公司,暂不支持导入工时
+        Company company = companyMapper.selectById(companyId);
+        if (company.getPackageProject() == 1) {
+            Integer alarmSettingCnt = projectBasecostSettingMapper.selectCount(new QueryWrapper<ProjectBasecostSetting>().eq("company_id", companyId).eq("alarm_type", 1));
+            if (alarmSettingCnt > 0) {
+                //msg.setError("已设置工时预警类型的成本预算,暂不支持导入工时");
+                msg.setError(MessageUtils.message("report.warningType"));
+                return msg;
+            }
+        }
+        //然后处理文件
+        String fileName = multipartFile.getOriginalFilename();
+        File file = new File(fileName == null ? "file" : fileName);
+        InputStream inputStream = null;
+        OutputStream outputStream = null;
+        try {
+            inputStream = multipartFile.getInputStream();
+            outputStream = new FileOutputStream(file);
+            byte[] buffer = new byte[4096];
+            int temp = 0;
+            while ((temp = inputStream.read(buffer, 0, 4096)) != -1) {
+                outputStream.write(buffer, 0, temp);
+            }
+            inputStream.close();
+            outputStream.close();
+            //然后解析表格
+            Workbook workbook = WorkbookFactory.create(new FileInputStream(file));
+
+            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/M/d");
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/M/d");
+            //获取公司全部成员
+            List<User> allUserList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
+
+            Sheet sheet = workbook.getSheetAt(0);
+            //由于第一行需要指明列对应的标题
+            int rowNum = sheet.getLastRowNum();
+            if (rowNum == 0) {
+                //msg.setError("请填写工时数据");
+                msg.setError(MessageUtils.message("report.data"));
+                return msg;
+            }
+            List<String> projectList = new ArrayList<>();
+            List<String> subProjectList = new ArrayList<>();
+            List<Project> allProjectList = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", companyId));
+            List<SubProject> allSubProjectList = subProjectMapper.selectList(new QueryWrapper<SubProject>().eq("company_id", companyId));
+            List<Report> reportList = new ArrayList<>();
+
+
+            List<String> userNameList=new ArrayList<>();
+            for (int rowIndex = 0; rowIndex <= rowNum; rowIndex++) {
+                Row row = sheet.getRow(rowIndex);
+                if (row == null) {
+                    continue;
+                }
+                if (ExcelUtil.isRowEmpty(row)) {
+                    continue;
+                }
+                String username = row.getCell(1).getStringCellValue().trim();
+
+                if (rowIndex == 0) {
+                    if(username.equals("员工")){
+                        continue;
+                    }
+                }
+                if(!userNameList.contains(username)&&!username.equals("")){
+                    userNameList.add(username);
+                }
+            }
+            //下标从0开始
+            HttpRespMsg respMsg=new HttpRespMsg();
+            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1&&userNameList.size()>0){
+                respMsg = wxCorpInfoService.getBatchSearchUserInfo(wxCorpInfo, userNameList,null);
+                if(respMsg.code.equals("0")){
+                    msg.setError("姓名为["+String.valueOf(respMsg.data)+"]的人员存在重复,请使用工号!");
+                    return msg;
+                }
+            }
+            List<User> targetUserList= (List<User>) respMsg.data;
+            int dataCount = 0;
+
+            for (int rowIndex = 0; rowIndex <= rowNum; rowIndex++) {
+                Row row = sheet.getRow(rowIndex);
+                if (row == null) {
+                    continue;
+                }
+                if (ExcelUtil.isRowEmpty(row)) {
+                    continue;
+                }
+                if (rowIndex > 0) {
+                    dataCount++;
+                    //数据行
+                    if (row.getCell(0) == null) {
+                        //msg.setError("第"+dataCount+"行缺少日期");
+                        msg.setError(MessageUtils.message("data.NullErrorByRow",dataCount));
+                        return msg;
+                    }
+                    boolean isDateFormat = row.getCell(0).getCellTypeEnum() == CellType.NUMERIC;
+                    String reportDate = isDateFormat?sdf.format(row.getCell(0).getDateCellValue()):row.getCell(0).getStringCellValue();
+                    if (StringUtils.isEmpty(reportDate)) {
+                        //msg.setError("第"+dataCount+"行缺少日期");
+                        msg.setError(MessageUtils.message("data.NullErrorByRow",dataCount));
+                        return msg;
+                    }
+                    for (int i=1;i<=7;i++) {
+                        if (row.getCell(i) != null) {
+                            row.getCell(i).setCellType(CellType.STRING);
+                        }
+                    }
+                    String username = row.getCell(1) != null?row.getCell(1).getStringCellValue().trim():null;
+                    if (StringUtils.isEmpty(username)) {
+                        msg.setError("员工姓名不能为空");
+                        return msg;
+                    }
+                    //检查人员是否存在
+                    Optional<User> any;
+                    if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                        Optional<User> optional = targetUserList.stream().filter(tl -> tl.getName().equals(username)).findFirst();
+                        any = allUserList.stream().filter(u -> u.getName().equals(username)||(u.getJobNumber()!=null&&u.getJobNumber().equals(username))||(optional.isPresent()&&u.getCorpwxUserid()!=null&&u.getCorpwxUserid().equals(optional.get().getCorpwxUserid()))).findAny();
+                    }else {
+                        any = allUserList.stream().filter(u -> u.getName().equals(username)||(u.getJobNumber()!=null&&u.getJobNumber().equals(username))).findAny();
+                    }
+                    if (!any.isPresent()) {
+                        //msg.setError("人员["+username+"]不存在,请先在组织结构中添加或者通过钉钉同步导入");
+                        msg.setError(MessageUtils.message("staff.peopleNullAndAdd",username));
+                        return msg;
+                    }
+                    User reportCreator = any.get();
+
+
+                    String pCode = row.getCell(3)==null?null:row.getCell(3).getStringCellValue();
+                    String pName = row.getCell(4)==null?null:row.getCell(4).getStringCellValue();
+                    Project project = null;
+                    if (StringUtils.isEmpty(pCode) && StringUtils.isEmpty(pName)) {
+                        msg.setError("项目编码和名称至少填写一项");
+                        return msg;
+                    } else if (!StringUtils.isEmpty(pCode)) {
+                        //优先按编码匹配
+                        Optional<Project> first = allProjectList.stream().filter(p -> pCode.equals(p.getProjectCode())).findFirst();
+                        if (first.isPresent()) {
+                            project = first.get();
+                        }
+                    } else if (!StringUtils.isEmpty(pName)) {
+                        Optional<Project> first = allProjectList.stream().filter(p -> pName.equals(p.getProjectName())).findFirst();
+                        if (first.isPresent()) {
+                            project = first.get();
+                        }
+                    }
+                    if (project == null) {
+                        msg.setError(MessageUtils.message("project.noExist","编码:"+pCode+"/名称:"+pName));
+                        return msg;
+                    }
+                    //检查子项目是否填写是否存在
+                    String subPName = row.getCell(5) == null?null:row.getCell(5).getStringCellValue();
+                    Integer projectId = project.getId();
+                    Integer subProjectId = null;
+                    if (!StringUtils.isEmpty(subPName)) {
+                        Optional<SubProject> first = allSubProjectList.stream().filter(sub -> subPName.equals(sub.getName()) && sub.getProjectId().equals(projectId)).findFirst();
+                        if (first.isPresent()) {
+                            subProjectId = first.get().getId();
+                        }
+                        if (subProjectId == null) {
+                            msg.setError("子项目:"+subPName+"在项目["+pCode+"/"+pName+"]下不存在,请检查");
+                            return msg;
+                        }
+                    }
+                    //解析任务分组
+                    String taskGroupName = row.getCell(6)==null?null:row.getCell(6).getStringCellValue();
+                    Integer groupId = null;
+                    if (!StringUtils.isEmpty(taskGroupName)) {
+                        List<TaskGroup> taskGroupList = taskGroupMapper.selectList(new QueryWrapper<TaskGroup>().eq("project_id", projectId).eq("name", taskGroupName));
+                        if (taskGroupList.size() > 0) {
+                            TaskGroup taskGroup = taskGroupList.get(0);
+                            groupId = taskGroup.getId();
+                        } else {
+                            msg.setError("任务分组:"+taskGroupName+"在项目["+pCode+"/"+pName+"]下不存在,请检查");
+                            return msg;
+                        }
+                    }
+
+                    String stringCellValue = row.getCell(7)==null?null:row.getCell(7).getStringCellValue();
+                    double time = 0;
+                    if (!StringUtils.isEmpty(stringCellValue)) {
+                        time = Double.parseDouble(stringCellValue);
+                        if (time > 0) {
+                            Report report = new Report();
+                            report.setCompanyId(companyId);
+                            report.setCreatorId(reportCreator.getId());
+                            report.setDeptId(reportCreator.getDepartmentId());
+                            report.setProjectId(project.getId());
+                            //子项目
+                            report.setSubProjectId(subProjectId);
+                            report.setGroupId(groupId);
+                            report.setReportTimeType(1);
+                            report.setWorkingTime(time);
+                            report.setMultiWorktime(timeType.getMultiWorktime());
+                            report.setFillUserid(user.getId());
+                            if (timeType.getNeedDeptAudit() == 0) {
+                                report.setState(1);//导入的直接算审核通过
+                            } else {
+                                report.setState(-1);//待部门上级审核员审核
+                                report.setDepartmentAuditState(1);//部门已审核,到上层领导审核
+                            }
+                            report.setCreateDate(LocalDate.parse(reportDate, dtf));
+                            report.setCost(reportCreator.getCost()==null?new BigDecimal(0) : reportCreator.getCost().multiply(new BigDecimal(time)));
+                            reportList.add(report);
+                        } else if (time < 0) {
+                            msg.setError(MessageUtils.message("report.negativeError",username));
+                            return msg;
+                        }
+                    }
+                }
+            }
+
+            if (reportList.size() > 0) {
+                //依赖于对是否需要部门审核的判断,如果不需要则认为导入的就是审核通过的,重新导入就直接覆盖之前的。
+                reportMapper.deleteUserSameDayReport(companyId, reportList, timeType.getNeedDeptAudit());
+                if (timeType.getNeedDeptAudit() == 1) {
+                    //如果需要导入审核,则对审核通过的进行排除
+                    List<Map> passReports = reportMapper.getSameDayPassReport(companyId, reportList);
+                    StringBuilder sb = new StringBuilder();
+                    if (passReports.size() > 0) {
+                        //统计成功条数,需要去掉没有覆盖的
+                        dataCount -= passReports.size();
+                        passReports.forEach(map->{
+                            String creatorId = (String)map.get("creator_id");
+                            String createDate = sdf.format(map.get("create_date"));//yyyy/M/d格式
+                            String userName = allUserList.stream().filter(u->u.getId().equals(creatorId)).findFirst().get().getName();
+                            sb.append(createDate).append("-").append(userName).append(",");
+                            for (int i=0;i<reportList.size(); i++) {
+                                Report one = reportList.get(i);
+                                if (LocalDate.parse(createDate, dtf).isEqual(one.getCreateDate())
+                                        &&creatorId.equals(one.getCreatorId())) {
+                                    reportList.remove(i);
+                                    i--;
+                                }
+                            }
+                        });
+                        String str = sb.toString();
+                        str = str.substring(0, str.length()-1);
+                        //msg.msg = "跳过以下已审核数据:"+str+"。";
+                        msg.msg = MessageUtils.message("finance.skipData",str);
+                    }
+                }
+
+                //存储
+                if (reportList.size() == 0) {
+                    //全部是重复的,本次没有需要导入的
+                    //msg.setError("本次数据全部已审核通过,无法导入。");
+                    msg.setError(MessageUtils.message("finance.importErrorByAllAdopt"));
+                    return msg;
+                } else {
+                    reportService.saveBatch(reportList);
+                    msg.data = dataCount;
+                    String originName = fileName;
+                    //定义一个独立的文件夹
+                    String importFolder = "report_import";
+                    File dir = new File(path, importFolder);
+                    if (!dir.exists()) {
+                        dir.mkdir();
+                    }
+
+                    System.out.println("fileName=="+originName);
+                    String[] names = originName.split("\\.");
+                    String destFileName = names[0] + "_"+System.currentTimeMillis()+"."+names[1];
+                    File destFile = new File(dir, destFileName);
+                    FileUtils.copyFile(file, destFile);
+                    ReportImportLog log = new ReportImportLog();
+                    log.setCompanyId(user.getCompanyId());
+                    log.setFileName(originName);
+                    log.setServerName(importFolder+"/"+destFileName);
+                    log.setUserId(user.getId());
+                    log.setUserName(user.getName());
+                    reportImportLogMapper.insert(log);
+                }
+            } else {
+                //msg.setError("工时数据不能为空");
+                msg.setError(MessageUtils.message("report.dataNullError"));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            //msg.setError("文件处理出错");
+            msg.setError(MessageUtils.message("file.error"));
+            return msg;
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+            //msg.setError("数据格式有误或存在空数据 导入失败");
+            msg.setError(MessageUtils.message("file.dataFormatError"));
+            return msg;
+        }catch (InvalidFormatException e) {
+            e.printStackTrace();
+            //msg.setError("文件格式错误,如果安装了加密软件需要先解密再上传");
+            msg.setError(MessageUtils.message("file.FormatErrorAndDecrypt"));
+            return msg;
+        }catch (EncryptedDocumentException e) {
+            e.printStackTrace();
+            //msg.setError("文件加密状态,需要先解除加密状态再上传");
+            msg.setError(MessageUtils.message("file.encryption"));
+            return msg;
+        } catch (Exception e) {
+            e.printStackTrace();
+            //msg.setError("发生其他错误:"+e.getMessage());
+            msg.setError(MessageUtils.message("other.errorByParameter",e.getMessage()));
+            return msg;
+        } finally {
+            //关闭流
+            try {
+                if (outputStream != null && inputStream != null) {
+                    outputStream.close();
+                    inputStream.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            file.delete();
+        }
+        return msg;
+    }
+
 
     private void fillDeptUser(List<DepartmentVO> list, List<HashMap> userList) {
         list.forEach(l->{
@@ -6633,32 +6958,43 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             if (collect.size() > 0) {
                 projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", collect));
                 //获取项目的任务分组列表
-                List<TaskGroup> taskGroups = taskGroupMapper.selectList(new QueryWrapper<TaskGroup>().in("project_id", collect));
-                //获取负责人的用户集合
-                List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", taskGroups.stream().map(TaskGroup::getInchargerId).collect(Collectors.toList())));
-                reportList.forEach(r->{
-                    r.setTaskGroups(taskGroups.stream().filter(tg->tg.getProjectId().equals(r.getProjectId())).collect(Collectors.toList()));
-                    for (TaskGroup gp : r.getTaskGroups()) {
-                        if (!StringUtils.isEmpty(gp.getInchargerId()) ) {
-                            if (gp.getInchargerId().equals(userId)) {
-                                //自己担任任务分组的负责人,自己的审核人是项目经理
-                                gp.setInchargerId(projectMapper.selectById(r.getProjectId()).getInchargerId());
-                                //如果自己就是项目经理,审核人变成自己的部门负责人
+                //需要是他参与的任务分组
+                List<GroupParticipator> groupParticipatorList = groupParticipatorMapper.selectList(new QueryWrapper<GroupParticipator>().eq("user_id", userId));
+                List<Integer> joinGroupList = groupParticipatorList.stream().map(GroupParticipator::getGroupId).collect(Collectors.toList());
+                if (joinGroupList.size() > 0) {
+                    List<TaskGroup> taskGroups = taskGroupMapper.selectList(new QueryWrapper<TaskGroup>().in("project_id", collect).in("id", joinGroupList));
+                    //获取负责人的用户集合
+                    List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", taskGroups.stream().map(TaskGroup::getInchargerId).collect(Collectors.toList())));
+                    reportList.forEach(r->{
+                        r.setTaskGroups(taskGroups.stream().filter(tg->tg.getProjectId().equals(r.getProjectId())).collect(Collectors.toList()));
+                        for (TaskGroup gp : r.getTaskGroups()) {
+                            if (!StringUtils.isEmpty(gp.getInchargerId()) ) {
                                 if (gp.getInchargerId().equals(userId)) {
-                                    gp.setInchargerId(departmentMapper.selectById(user.getDepartmentId()).getManagerId());
+                                    //自己担任任务分组的负责人,自己的审核人是项目经理
+                                    gp.setInchargerId(projectMapper.selectById(r.getProjectId()).getInchargerId());
+                                    //如果自己就是项目经理,审核人变成自己的部门负责人
+                                    if (gp.getInchargerId().equals(userId)) {
+                                        Integer dpId = user.getDepartmentId();
+                                        if (dpId != null && dpId > 0) {
+                                            Department department = departmentMapper.selectById(dpId);
+                                            if (department != null) {
+                                                gp.setInchargerId(department.getManagerId());
+                                            }
+                                        }
+                                    }
+                                    //不存在的话,加上项目经理
+                                    if (!userList.stream().anyMatch(u->u.getId().equals(gp.getInchargerId()))) {
+                                        userList.add(userMapper.selectById(gp.getInchargerId()));
+                                    }
                                 }
-                                //不存在的话,加上项目经理
-                                if (!userList.stream().anyMatch(u->u.getId().equals(gp.getInchargerId()))) {
-                                    userList.add(userMapper.selectById(gp.getInchargerId()));
+                                Optional<User> first = userList.stream().filter(u -> u.getId().equals(gp.getInchargerId())).findFirst();
+                                if (first.isPresent()) {
+                                    gp.setInchargerName(first.get().getName());
                                 }
                             }
-                            Optional<User> first = userList.stream().filter(u -> u.getId().equals(gp.getInchargerId())).findFirst();
-                            if (first.isPresent()) {
-                                gp.setInchargerName(first.get().getName());
-                            }
                         }
-                    }
-                });
+                    });
+                }
             }
 
             reportMap.put("projectList", projectList);

+ 1 - 0
fhKeeper/formulahousekeeper/timesheet/src/i18n/en.json

@@ -928,6 +928,7 @@
   "instructions": "(Note: The system administrator is not limited by the filling time when filling out the daily report for the employee)",
   "missingfill": "Daily reminder missed filling on the day",
   "missingfills": "Daily reminder missed yesterday",
+  "lastDayOfWeek": "Remind on the last day of current week",
   "morningtime": "morning time",
   "owntimeframe": "Choose your own time frame",
   "personneltoset": "Don't remind people settings",

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

@@ -937,6 +937,7 @@
   "remindermethod": "请选择提醒方式",
   "missingfill": "每日提醒当天漏填",
   "missingfills": "每日提醒昨天漏填",
+  "lastDayOfWeek": "每周最后一个工作日",
   "remindertext": "提醒文本",
   "personneltoset": "不提醒人员设置",
   "addTian": "添加",

+ 75 - 3
fhKeeper/formulahousekeeper/timesheet/src/views/expense/expense.vue

@@ -252,13 +252,20 @@
               <el-form-item v-if="currentClick == '2-1'">
                 <el-button @click="exportDocument()" size="small">单据导出</el-button>
               </el-form-item>
+              <el-form-item v-if="currentClick == '2-1'">
+                <el-button @click="documentIssuance(1)" size="small">发放</el-button>
+              </el-form-item>
+              <el-form-item v-if="currentClick == '2-1'">
+                <el-button @click="documentIssuance(0)" size="small">取消发放</el-button>
+              </el-form-item>
               <!-- <span>审核模式:{{ auditTypeItem.auditType }}</span> -->
             </div>
           </el-form>
         </div>
         <el-divider ></el-divider>
         <!--列表-->
-          <el-table ref="tab" :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight - currentClickNum" style="width: 100%;" :summary-method="getSummaries" show-summary>
+          <el-table ref="tab" :data="list" @selection-change="handleSelectionChange" highlight-current-row v-loading="listLoading" :height="tableHeight - currentClickNum" style="width: 100%;" :summary-method="getSummaries" show-summary>
+              <el-table-column type="selection" width="55"></el-table-column>
               <el-table-column prop="code" :label="$t('ticketnumber')"></el-table-column>
               <el-table-column prop="totalAmount" :label="$t('amountof')+ '('+$t('yuan')+')'" align="center">
                 <template slot-scope="scope" >
@@ -301,6 +308,11 @@
                   <span style="font-size:12px;">{{scope.row.denyReason}}</span>
                 </template>
               </el-table-column> -->
+              <el-table-column prop="sendState" label="发放状态" width="80">
+                <template slot-scope="scope">
+                  <span :style="`color: ${scope.row.sendState == 0 ? '#FFA500' : ''}`">{{ scope.row.sendState == 1 ? '已发放' : '未发放' }}</span>
+                </template>
+              </el-table-column>
               <el-table-column fixed="right" :label="$t('operation')" :width="isAuditList?220:160">
                   <template slot-scope="scope" >
                       <div v-if="!isAuditList">
@@ -928,6 +940,7 @@ export default {
       // 详情弹出框
       detailDialog: false,
       detaExpenseMainTypeName: '',
+      multipleSelection: [],
     };
   },
   computed: {
@@ -2019,11 +2032,11 @@ export default {
         const { columns, data } = param;
         const sums = [];
         columns.forEach((column, index) => {
-          if (index === 0) {
+          if (index === 1) {
             sums[index] = '本页金额合计';//this.$t('other.totals');
             return;
           }
-          if(index === 1) {
+          if(index === 2) {
             const values = data.map(item => Number(item[column.property]));
             if (!values.every(value => isNaN(value))) {
               sums[index] = values.reduce((prev, curr) => {
@@ -2098,6 +2111,65 @@ export default {
             });
         });
       },
+      // 单据发放
+      documentIssuance(type) {
+        const newList = this.multipleSelection.filter(item => item.status == 1 || item.status == 2);
+        const unissueds = this.multipleSelection.filter(item => item.status != 1 && item.status != 2 && item.sendState == 0).map(item => item.id);
+        const Issueds = this.multipleSelection.filter(item => item.status != 1 && item.status != 2 && item.sendState == 1).map(item => item.id);
+
+        const showMessage = (msg, messageType) => {
+          this.$message({
+            message: msg,
+            type: messageType
+          });
+        };
+        
+        if (newList.length > 0) {
+          showMessage('存在待审核或已驳回的单据', 'warning');
+          return;
+        }
+
+        if (type == 1 && unissueds.length == 0) {
+          showMessage('请选择未发放的单据', 'warning');
+          return;
+        }
+
+        if (type == 0 && Issueds.length == 0) {
+          showMessage('请选择已发放的单据', 'warning');
+          return;
+        }
+
+        this.callingInterface(type, type == 1 ? unissueds : Issueds);
+      },
+      callingInterface(type, ids) {
+        this.http.post('/expense-sheet/editSendExpense', {
+          expenseIds: ids.join(','),
+          sendState: type
+        },
+        res => {
+            if (res.code == "ok") {
+                this.$message({
+                  message: '操作成功',
+                  type: "success"
+                });
+                this.getList()
+            } else {
+                this.$message({
+                  message: res.msg,
+                  type: "error"
+                });
+            }
+        },
+        error => {
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+      },
+      handleSelectionChange(val) {
+        this.multipleSelection = val;
+      },
       // 打印
       print() {
         // let printContent = this.$refs.printContent;

+ 1 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue

@@ -209,6 +209,7 @@
                         <el-select v-model="timeType.alertType" :placeholder="$t('remindermethod')">
                             <el-option :label="$t('missingfill')" :value="0"></el-option>
                             <el-option :label="$t('missingfills')" :value="1"></el-option>
+                            <el-option :label="$t('lastDayOfWeek')" :value="2"></el-option>
                         </el-select>
                     </el-form-item>
                     <el-form-item :label="$t('remindertext')" prop="alertMsg" style="width: 50%;margin-left:10px;">

+ 2 - 2
fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue

@@ -367,7 +367,7 @@
                           <span style="float: right; color: #8492a6; font-size: 13px">{{ item.jobNumber }}</span>
                         </el-option>
                     </el-select>
-                    <selectCat :size="'medium'" :widthStr="'360'" v-if="user.userNameNeedTranslate == '1'" :subject="users" :subjectId="depForm.otherManagerIds" :distinction="'4'" @selectCal="selectCal"></selectCat>
+                    <selectCat :size="'medium'" :widthStr="'360'" v-if="user.userNameNeedTranslate == '1' && departmentVisible" :subject="users" :subjectId="depForm.otherManagerIds" :distinction="'4'" @selectCal="selectCal"></selectCat>
                 </el-form-item>
                 <!-- 直属领导 -->
                 <el-form-item :label="$t('leadership')" prop="reportAuditUserid" v-if="user.timeType.needDeptAudit">
@@ -2981,12 +2981,12 @@ export default {
             }
           } else {
             this.$set(that.depForm, 'otherManagerIds', [])
-
           }
           // console.log('点击编辑的时候', that.depData)
           // if(that.depData.reportAuditUserid != null && that.depData.reportAuditUserid != "null" && that.depData.reportAuditUserid.length > 0) {
           //     that.depForm.reportAuditUserid = that.depData.reportAuditUserid
           // }
+          console.log(that.depForm, '<===== 最后的值')
           that.depTitle = this.$t('editorialdepartment');
         }
         that.departmentVisible = true;

Dosya farkı çok büyük olduğundan ihmal edildi
+ 5 - 4
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue


+ 15 - 10
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/weeklyCustomization.vue

@@ -24,9 +24,9 @@
                             </el-select>
                         </template>
                     </el-table-column>
-                    <el-table-column label="分" width="180">
+                    <el-table-column label="分" width="180">
                         <template slot-scope="scope">
-                            <el-select v-model="scope.row.groupId" size="small" placeholder="请选择分"
+                            <el-select v-model="scope.row.groupId" size="small" placeholder="请选择分"
                                 @change="changeGroup(scope.row.groupId, scope.row.taskGroups, scope.$index)"
                                 :disabled="scope.row.state == 1 || scope.row.state == 0 || !scope.row.canFill">
                                 <el-option v-for="item in scope.row.taskGroups" :key="item.id" :label="item.name"
@@ -67,7 +67,7 @@
                                     <el-link type="primary" :underline="false" class="el-icon-circle-plus-outline"
                                         @click="insertRow(scope.$index)"></el-link>
                                     <el-link type="primary" :underline="false" class="el-icon-delete"
-                                        @click="deleteRow(scope.$index)"></el-link>
+                                        @click="deleteRow(scope.$index)" v-if="!scope.row.isDelete"></el-link>
                                 </span>
                             </div>
                         </template>
@@ -236,7 +236,7 @@ export default {
             let newArr = groupList.filter(item => item.id == groupId)
             if (!newArr[0].inchargerId) {
                 this.$message({
-                    message: `【${newArr[0].name}】分未设置审批人,请联系该项目管理人员`,
+                    message: `【${newArr[0].name}】分未设置审批人,请联系该项目管理人员`,
                     type: "error"
                 });
                 return
@@ -255,10 +255,14 @@ export default {
             const { dateList, projectList, sumTimeList, cardTimeList } = data;
             const weekTableData = dateList.flatMap(date => {
                 const { weekDayTxt, date: dateTime, reportList, canFill } = date;
-                const reports = reportList.map(report => ({ ...report, weekDayTxt, dateTime, canFill }));
-                return reports.length > 0 ? reports : [{ weekDayTxt, dateTime, canFill }];
+                const reports = reportList.map(report => ({ ...report, weekDayTxt, dateTime, canFill}));
+                return reports.length > 0 ? reports : [{ weekDayTxt, dateTime, canFill}];
+            });
+            let sumSet = new Set();
+            weekTableData.forEach(obj => {
+                obj.isDelete = sumSet.has(obj.dateTime) ? false : true;
+                sumSet.add(obj.dateTime);
             });
-
             this.weekTableData = weekTableData;
             console.log(weekTableData, '<========== weekTableData')
         },
@@ -273,7 +277,7 @@ export default {
             let { data } = await this.getData('/task-group/listProjectGroupAndAuditor', { projectId, isSubstitude: isSubstitude ? 1 : 0 })
             if (data.length == 0) {
                 this.$message({
-                    message: '分未设置,请联系该项目管理人员',
+                    message: '分未设置,请联系该项目管理人员',
                     type: "error"
                 });
             } else if (data.length == 1) {
@@ -282,7 +286,7 @@ export default {
                 this.$set(this.weekTableData[index], 'projectAuditorName', data[0].inchargerName)
                 if (!data[0].inchargerId) {
                     this.$message({
-                        message: `【${data[0].name}】分未设置审批人,请联系该项目管理人员`,
+                        message: `【${data[0].name}】分未设置审批人,请联系该项目管理人员`,
                         type: "error"
                     });
                 }
@@ -302,7 +306,8 @@ export default {
                 groupId: '',
                 groupList: [],
                 approverList: [],
-                canFill: 1
+                canFill: 1,
+                isDelete: false
             })
         },
         // 删除一行