Parcourir la source

财务核算模块设置无项目人员的分摊比例,工时成本统计中部门支持多层级

seyason il y a 3 ans
Parent
commit
9b542bfbf0
55 fichiers modifiés avec 1752 ajouts et 344 suppressions
  1. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AuditWorkflowTimeSettingController.java
  2. 3 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/DepartmentController.java
  3. 18 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ExpenseItemController.java
  4. 9 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FinanceController.java
  5. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FinanceProjectsController.java
  6. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java
  7. 39 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectPercentageController.java
  8. 2 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  9. 10 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SubProjectController.java
  10. 31 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserCorpwxTimeController.java
  11. 35 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Finance.java
  12. 63 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/FinanceProjects.java
  13. 48 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectPercentage.java
  14. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectSumItem.java
  15. 4 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SubProject.java
  16. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeType.java
  17. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/DepartmentMasterVO.java
  18. 5 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ExpenseItemMapper.java
  19. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/FinanceProjectsMapper.java
  20. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectPercentageMapper.java
  21. 7 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  22. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/DepartmentService.java
  23. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/FinanceProjectsService.java
  24. 4 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/FinanceService.java
  25. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectPercentageService.java
  26. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java
  27. 45 19
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java
  28. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceProjectsServiceImpl.java
  29. 384 19
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceServiceImpl.java
  30. 115 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectPercentageServiceImpl.java
  31. 62 16
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  32. 34 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  33. 26 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ExpenseItemMapper.xml
  34. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/FinanceProjectsMapper.xml
  35. 4 3
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml
  36. 18 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectPercentageMapper.xml
  37. 38 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  38. 3 15
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SubProjectMapper.xml
  39. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TimeTypeMapper.xml
  40. BIN
      fhKeeper/formulahousekeeper/management-platform/员工工时导入模板 (14).xlsx
  41. BIN
      fhKeeper/formulahousekeeper/management-platform/项目导入模板.xlsx
  42. 10 10
      fhKeeper/formulahousekeeper/timesheet/config/index.js
  43. 65 16
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue
  44. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/desktop/detail.vue
  45. 2 15
      fhKeeper/formulahousekeeper/timesheet/src/views/expense/expense.vue
  46. 56 108
      fhKeeper/formulahousekeeper/timesheet/src/views/project/cost.vue
  47. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/detail.vue
  48. 27 23
      fhKeeper/formulahousekeeper/timesheet/src/views/project/detailDep.vue
  49. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/earning.vue
  50. 346 24
      fhKeeper/formulahousekeeper/timesheet/src/views/project/finance.vue
  51. 4 4
      fhKeeper/formulahousekeeper/timesheet/src/views/project/summary.vue
  52. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/simplereport/list.vue
  53. 28 21
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  54. 28 7
      fhKeeper/formulahousekeeper/timesheet/src/views/workflow/report.vue
  55. 10 10
      fhKeeper/formulahousekeeper/timesheet_h5/vue.config.js

+ 20 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AuditWorkflowTimeSettingController.java

@@ -6,8 +6,10 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.AuditWorkflowTimeSetting;
 import com.management.platform.entity.Department;
+import com.management.platform.entity.Report;
 import com.management.platform.mapper.AuditWorkflowTimeSettingMapper;
 import com.management.platform.mapper.DepartmentMapper;
+import com.management.platform.mapper.ReportMapper;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.util.HttpRespMsg;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -38,6 +40,8 @@ public class AuditWorkflowTimeSettingController {
     UserMapper userMapper;
     @Resource
     DepartmentMapper departmentMapper;
+    @Resource
+    ReportMapper reportMapper;
 
 
     @RequestMapping("/add")
@@ -81,6 +85,22 @@ public class AuditWorkflowTimeSettingController {
         return new HttpRespMsg();
     }
 
+    @RequestMapping("/checkNodeInUse")
+    public HttpRespMsg checkNodeInUse(String auditDeptId, Integer deptId) {
+        String token = request.getHeader("TOKEN");
+        Integer companyId = userMapper.selectById(token).getCompanyId();
+        HttpRespMsg msg = new HttpRespMsg();
+        List<AuditWorkflowTimeSetting> targetNode = auditWorkflowTimeSettingMapper.selectList(new QueryWrapper<AuditWorkflowTimeSetting>().eq("dept_id", deptId).eq("audit_dept_id", auditDeptId));
+        if (targetNode.size() > 0) {
+            //要删除的部门节点是存在的,需要检测是否有待审核的走到这个流程点了
+            long num = reportMapper.selectCount(new QueryWrapper<Report>().eq("state", 0).eq("is_dept_audit", 1).eq("audit_deptid", auditDeptId));
+            if (num > 0) {
+                msg.setError("当前部门存在待审核报告,无法操作!");
+            }
+        }
+
+        return msg;
+    }
 
     @RequestMapping("/get")
     public HttpRespMsg get(Integer deptId) {

+ 3 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/DepartmentController.java

@@ -83,11 +83,11 @@ public class DepartmentController {
     }
 
     /**
-     * 获取顶级项目及其统计
+     * 获取部门的统计工时成本
      */
     @RequestMapping("/departmentStatistic")
-    public HttpRespMsg getDepartmentStatistics(String startDate, String endDate, HttpServletRequest request) {
-        return departmentService.getDepartmentStatistics(startDate, endDate, request);
+    public HttpRespMsg getDepartmentStatistics(Integer parentDeptId, String startDate, String endDate, HttpServletRequest request) {
+        return departmentService.getDepartmentStatistics(parentDeptId, startDate, endDate, request);
     }
 
     /**

+ 18 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ExpenseItemController.java

@@ -1,10 +1,18 @@
 package com.management.platform.controller;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.ExpenseItem;
+import com.management.platform.entity.vo.ExpenseItemVO;
+import com.management.platform.mapper.ExpenseItemMapper;
+import com.management.platform.util.HttpRespMsg;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.annotation.Resource;
+import java.util.List;
+
 /**
  * <p>
  *  前端控制器
@@ -17,5 +25,15 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/expense-item")
 public class ExpenseItemController {
 
+    @Resource
+    private ExpenseItemMapper expenseItemMapper;
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(Integer projectId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        List<ExpenseItemVO> userExpenseDetail = expenseItemMapper.getUserExpenseDetail(projectId);
+        msg.data = userExpenseDetail;
+        return msg;
+    }
 }
 

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

@@ -49,6 +49,11 @@ public class FinanceController {
         return financeService.getByMonth(companyId, yearMonth);
     }
 
+    @RequestMapping("/getProjects")
+    public HttpRespMsg getProjects(Integer companyId, String yearMonth) {
+        return financeService.getProjects(companyId, yearMonth);
+    }
+
     @RequestMapping("/importData")
     public HttpRespMsg importData(Integer companyId, String yearMonth,
                                   Boolean syncUserCost, Boolean syncHistoryReport,
@@ -57,14 +62,14 @@ public class FinanceController {
     }
 
     @RequestMapping("/exportData")
-    public HttpRespMsg exportData(@RequestParam String date, HttpServletRequest request) {
-        return financeService.exportData(date, request);
+    public HttpRespMsg exportData(@RequestParam String date, Boolean assignNoProUser,HttpServletRequest request) {
+        return financeService.exportData(date, assignNoProUser, request);
     }
 
     //按照项目分配财务成本
     @RequestMapping("/getTimeCost")
-    public HttpRespMsg getTimeCost(String yearMonth, HttpServletRequest request) {
-        return financeService.getTimeCost(yearMonth, request);
+    public HttpRespMsg getTimeCost(String yearMonth, Boolean assignNoProUser,HttpServletRequest request) {
+        return financeService.getTimeCost(yearMonth, assignNoProUser,request);
     }
 
     @RequestMapping("/getNoProjectUsers")

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FinanceProjectsController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-26
+ */
+@RestController
+@RequestMapping("/finance-projects")
+public class FinanceProjectsController {
+
+}
+

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java

@@ -129,8 +129,8 @@ public class ProjectController {
      * 导出查询者所在公司每个项目的工时成本
      */
     @RequestMapping("/exportTimeCost")
-    public HttpRespMsg exportTimeCost(String startDate, String endDate, Integer projectId, String userId) {
-        return projectService.exportTimeCost(startDate, endDate, projectId, userId, request);
+    public HttpRespMsg exportTimeCost(String startDate, String endDate, Integer projectId, String userId, Boolean projectSum) {
+        return projectService.exportTimeCost(startDate, endDate, projectId, userId, projectSum, request);
     }
 
     /**

+ 39 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectPercentageController.java

@@ -0,0 +1,39 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.service.ProjectPercentageService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-26
+ */
+@RestController
+@RequestMapping("/project-percentage")
+public class ProjectPercentageController {
+
+    @Resource
+    private ProjectPercentageService projectPercentageService;
+
+    @RequestMapping("/saveMonthSetting")
+    public HttpRespMsg saveMonthSetting(String projectCols, String userSettings, String ymonth) {
+        return projectPercentageService.saveMonthSetting(projectCols, userSettings, ymonth);
+    }
+
+    @RequestMapping("/getMonthSetting")
+    public HttpRespMsg getMonthSetting(String ymonth) {
+        return projectPercentageService.getMonthSetting(ymonth);
+    }
+
+
+}
+

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

@@ -295,9 +295,7 @@ public class ReportController {
             List<Department> allDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", user.getCompanyId()));
 
             for (int i = 0; i < id.length; i++) {
-                System.out.println("==@@"+createDate[i]+", "+createDate[i].contains("@"));
                 if (createDate[i].contains("@")) {
-                    DateTimeFormatter ddtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                     DateTimeFormatter mdFormatter = DateTimeFormatter.ofPattern("MM-dd");
                     System.out.println("============这是批量填报=");
                     //这是批量填报的情况,日期有范围
@@ -430,8 +428,8 @@ public class ReportController {
                                 .setProjectId(projectId[i])
                                 .setSubProjectId(subProjectId[i] == 0?null:subProjectId[i])
                                 .setReportTimeType(reportTimeType[i])
-                                .setMultiWorktime(multiWorktime[i])
-                                .setContent(content[i])
+                                .setMultiWorktime(multiWorktime.length > 0?multiWorktime[i]:0)
+                                .setContent(content.length > 0?content[i]:"-")
                                 .setDegreeId(degreeId.length > 0?degreeId[i]:null)
                                 .setStage(stage!=null && stage.length > 0  && !StringUtil.isEmpty(stage[i])?stage[i]:null)
                                 .setState(draft==0?0:3)
@@ -479,7 +477,6 @@ public class ReportController {
                     } else {
                         //批量代填的情况
                         for (User subsUser : targetUserList) {
-                            System.out.println("生成日报FOR=="+subsUser.getName()+", "+subsUser.getCost().toString());
                             Report report = new Report()
                                     .setId(id[i] == -1 ? null : id[i])
                                     .setProjectId(projectId[i])
@@ -572,7 +569,6 @@ public class ReportController {
                         .setCost(hourCost.multiply(new BigDecimal(workingTime)))
                         .setTimeType(timeType);
             } else if (report.getReportTimeType() == 1|| report.getReportTimeType() == 3) {
-                System.out.println("hourCost="+hourCost+", workingTime="+workingTime);
                 report.setWorkingTime(workingTime)
                         .setCost(hourCost.multiply(new BigDecimal(workingTime)));
             } else if (report.getReportTimeType() == 2) {

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

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.ProjectTimer;
 import com.management.platform.entity.SubProject;
 import com.management.platform.mapper.ProjectTimerMapper;
+import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.ProjectService;
 import com.management.platform.service.SubProjectService;
 import com.management.platform.util.HttpRespMsg;
@@ -32,6 +33,10 @@ public class SubProjectController {
     private SubProjectService subProjectService;
     @Resource
     private ProjectTimerMapper projectTimerMapper;
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private UserMapper userMapper;
 
     /**
      * 获取子项目列表
@@ -51,6 +56,11 @@ public class SubProjectController {
      */
     @RequestMapping("/saveOrUpdate")
     public HttpRespMsg saveOrUpdate(SubProject item) {
+        if (item.getId() == null) {
+            //赋予公司id
+            Integer companyId = userMapper.selectById(request.getHeader("TOKEN")).getCompanyId();
+            item.setCompanyId(companyId);
+        }
         subProjectService.saveOrUpdate(item);
         if (item.getId() != null) {
             //修改相关表

+ 31 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserCorpwxTimeController.java

@@ -20,6 +20,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -94,6 +95,7 @@ public class UserCorpwxTimeController {
                 }
             }).collect(Collectors.toList());
         }
+        DateTimeFormatter standFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
         HashMap item = new HashMap();
         item.put("list", list);
         if (list.size() > 0) {
@@ -106,16 +108,43 @@ public class UserCorpwxTimeController {
             //员工参与的项目
             List<Participation> participationList = participationMapper.selectList(new QueryWrapper<Participation>().in("user_id", userIdList));
             List<String> names = new ArrayList<>();
+            LocalDate localStart = LocalDate.parse(startDate, standFormatter);
+            LocalDate localEnd = LocalDate.parse(endDate, standFormatter);
             if (participationList.size() > 0) {
                 List<Integer> collect = participationList.stream().map(Participation::getProjectId).collect(Collectors.toList());
                 List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", collect).orderByAsc("id"));
-                names = projectList.stream().map(Project::getProjectName).collect(Collectors.toList());
+
+                names = projectList.stream().filter(p->{
+                    if (p.getPlanStartDate() != null) {
+                        if (p.getPlanStartDate().isAfter(localEnd)) {
+                            return false;
+                        }
+                    }
+                    if (p.getPlanEndDate() != null) {
+                        if (p.getPlanEndDate().isBefore(localStart)) {
+                            return false;
+                        }
+                    }
+                    return true;
+                }).map(Project::getProjectName).collect(Collectors.toList());
 
             }
             //添加公共项目
             List<Project> publicProjects = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", user.getCompanyId()));
             if (publicProjects.size() > 0) {
-                List<String> collect = publicProjects.stream().map(Project::getProjectName).collect(Collectors.toList());
+                List<String> collect = publicProjects.stream().filter(p->{
+                    if (p.getPlanStartDate() != null) {
+                        if (p.getPlanStartDate().isAfter(localEnd)) {
+                            return false;
+                        }
+                    }
+                    if (p.getPlanEndDate() != null) {
+                        if (p.getPlanEndDate().isBefore(localStart)) {
+                            return false;
+                        }
+                    }
+                    return true;
+                }).map(Project::getProjectName).collect(Collectors.toList());
                 names.addAll(collect);
             }
             item.put("projects", names);

+ 35 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Finance.java

@@ -143,9 +143,44 @@ public class Finance extends Model<Finance> {
     @TableField(exist = false)
     private BigDecimal hourCost;
 
+    @TableField(exist = false)
+    private Integer hasReport;
+
     @Override
     protected Serializable pkVal() {
         return this.id;
     }
 
+    //按比例折算后的各项收入
+    public static Finance getByPercent(Finance from, double percent) {
+        Finance target = new Finance();
+        BigDecimal per = new BigDecimal(percent).divide(new BigDecimal(100));
+        target.setTotalCost(from.getTotalCost().multiply(per));
+        target.setMonthCost(from.getMonthCost().multiply(per));
+        target.setBonus(from.getBonus().multiply(per));
+        target.setAllowance(from.getAllowance().multiply(per));
+        target.setInsuranceOld(from.getInsuranceOld().multiply(per));
+        target.setInsuranceMedical(from.getInsuranceMedical().multiply(per));
+        target.setInsuranceLosejob(from.getInsuranceLosejob().multiply(per));
+        target.setInsuranceInjury(from.getInsuranceInjury().multiply(per));
+        target.setHouseFund(from.getHouseFund().multiply(per));
+        if (from.getCustomField1() != null) {
+            target.setCustomField1(from.getCustomField1().multiply(per));
+        } else {
+            target.setCustomField1(new BigDecimal(0));
+        }
+        if (from.getCustomField2() != null) {
+            target.setCustomField2(from.getCustomField2().multiply(per));
+        } else {
+            target.setCustomField2(new BigDecimal(0));
+        }
+        if (from.getCustomField3() != null) {
+            target.setCustomField3(from.getCustomField3().multiply(per));
+        } else {
+            target.setCustomField3(new BigDecimal(0));
+        }
+
+        return target;
+    }
+
 }

+ 63 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/FinanceProjects.java

@@ -0,0 +1,63 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class FinanceProjects extends Model<FinanceProjects> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 年月
+     */
+    @TableField("ymonth")
+    private String ymonth;
+
+    /**
+     * 项目id
+     */
+    @TableField("project_id")
+    private Integer projectId;
+
+    /**
+     * 项目名称
+     */
+    @TableField("project_name")
+    private String projectName;
+
+    /**
+     * 项目编号
+     */
+    @TableField("project_code")
+    private String projectCode;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 48 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectPercentage.java

@@ -0,0 +1,48 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ProjectPercentage extends Model<ProjectPercentage> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @TableField("company_id")
+    private Integer companyId;
+
+    @TableField("data")
+    private String data;
+
+    /**
+     * 所属年月
+     */
+    @TableField("ymonth")
+    private String ymonth;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectSumItem.java

@@ -4,6 +4,8 @@ import java.math.BigDecimal;
 
 public class ProjectSumItem {
     public String project;
+    public String projectCode;
+    public Integer projectId;
     public double workingTime;
     public BigDecimal cost;
     //工资

+ 4 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SubProject.java

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2021-03-17
+ * @since 2022-02-28
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -39,6 +39,9 @@ public class SubProject extends Model<SubProject> {
     @TableField("project_id")
     private Integer projectId;
 
+    @TableField("company_id")
+    private Integer companyId;
+
 
     @Override
     protected Serializable pkVal() {

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

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2022-01-05
+ * @since 2022-02-24
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -126,6 +126,12 @@ public class TimeType extends Model<TimeType> {
     @TableField("need_dept_audit")
     private Integer needDeptAudit;
 
+    /**
+     * 是否开启自定义审批流
+     */
+    @TableField("report_workflow")
+    private Integer reportWorkflow;
+
 
     @Override
     protected Serializable pkVal() {

+ 1 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/DepartmentMasterVO.java

@@ -13,4 +13,5 @@ import java.math.BigDecimal;
 public class DepartmentMasterVO extends Department {
     private Double costTime;
     private BigDecimal costMoney;
+    private boolean hasSubDept;
 }

+ 5 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ExpenseItemMapper.java

@@ -2,6 +2,10 @@ package com.management.platform.mapper;
 
 import com.management.platform.entity.ExpenseItem;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.vo.ExpenseItemVO;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -12,5 +16,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  * @since 2021-05-17
  */
 public interface ExpenseItemMapper extends BaseMapper<ExpenseItem> {
-
+    List<ExpenseItemVO> getUserExpenseDetail(Integer projectId);
 }

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/FinanceProjectsMapper.java

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.FinanceProjects;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-26
+ */
+public interface FinanceProjectsMapper extends BaseMapper<FinanceProjects> {
+
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectPercentageMapper.java

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.ProjectPercentage;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-26
+ */
+public interface ProjectPercentageMapper extends BaseMapper<ProjectPercentage> {
+
+}

+ 7 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java

@@ -25,6 +25,10 @@ public interface ReportMapper extends BaseMapper<Report> {
                                                      @Param("endDate") String endDate,
                                                      @Param("projectId") Integer projectId
                                                  );
+    List<HashMap<String, Object>> getPMOReportByDate(@Param("startDate") String startDate,
+                                                     @Param("companyId") Integer companyId,
+                                                     @Param("userId") String userId,
+                                                     @Param("endDate") String endDate);
 
     //按当前人员获取本人报告
     List<Map<String, Object>> getReportByDate(@Param("date") String date, @Param("id") String id);
@@ -82,4 +86,7 @@ public interface ReportMapper extends BaseMapper<Report> {
                                                      @Param("departmentIdList") List<Integer> departmentIdList,
                                                      @Param("projectId") Integer projectId
                                                      );
+    List<Map<String, Object>> selectFillReportUserList(Integer companyId, String startDate, String endDate);
+
+    List<Map<String, Object>> getMonthReportProjectList(Integer companyId, String startDate, String endDate);
 }

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/DepartmentService.java

@@ -25,7 +25,7 @@ public interface DepartmentService extends IService<Department> {
 
     HttpRespMsg getDepartmentList(HttpServletRequest request);
 
-    HttpRespMsg getDepartmentStatistics(String startDate, String endDate, HttpServletRequest request);
+    HttpRespMsg getDepartmentStatistics(Integer parentDeptId, String startDate, String endDate, HttpServletRequest request);
 
     HttpRespMsg getUserStatistics(String startDate, String endDate, Integer departmentId, HttpServletRequest request);
 

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/FinanceProjectsService.java

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.FinanceProjects;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-26
+ */
+public interface FinanceProjectsService extends IService<FinanceProjects> {
+
+}

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

@@ -21,9 +21,11 @@ public interface FinanceService extends IService<Finance> {
 
     HttpRespMsg importData(Integer companyId, String yearMonth, Boolean syncUserCost, Boolean syncHistoryReport, MultipartFile multipartFile, HttpServletRequest request);
 
-    HttpRespMsg exportData(String date, HttpServletRequest request);
+    HttpRespMsg exportData(String date, Boolean assignNoProUser, HttpServletRequest request);
 
-    HttpRespMsg getTimeCost(String yearMonth, HttpServletRequest request);
+    HttpRespMsg getTimeCost(String yearMonth, Boolean assignNoProUser, HttpServletRequest request);
 
     HttpRespMsg getNoProjectUsers(String yearMonth, HttpServletRequest request);
+
+    HttpRespMsg getProjects(Integer companyId, String yearMonth);
 }

+ 20 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectPercentageService.java

@@ -0,0 +1,20 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.ProjectPercentage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.util.HttpRespMsg;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-26
+ */
+public interface ProjectPercentageService extends IService<ProjectPercentage> {
+
+    HttpRespMsg saveMonthSetting(String projectCols, String userSettings, String ymonth);
+
+    HttpRespMsg getMonthSetting(String ymonth);
+}

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java

@@ -45,7 +45,7 @@ public interface ProjectService extends IService<Project> {
 
     HttpRespMsg getAllMembCost(String startDate, String endDate, Integer projectId, HttpServletRequest request);
 
-    HttpRespMsg exportTimeCost(String startDate, String endDate, Integer projectId,String userId, HttpServletRequest request);
+    HttpRespMsg exportTimeCost(String startDate, String endDate, Integer projectId,String userId, Boolean projectSum, HttpServletRequest request);
 
     HttpRespMsg updateProgress(Integer id, Integer progress, HttpServletRequest request);
 

+ 45 - 19
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java

@@ -250,25 +250,38 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
 
     //获取某个项目下的统计
     @Override
-    public HttpRespMsg getDepartmentStatistics(String startDate, String endDate, HttpServletRequest request) {
+    public HttpRespMsg getDepartmentStatistics(Integer parentDeptId, String startDate, String endDate, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
-            List<Department> masterList = departmentMapper.selectList(new QueryWrapper<Department>()
-                    .eq("company_id", companyId).isNull("superior_id"));
+            QueryWrapper<Department> queryWrapper = new QueryWrapper<Department>()
+                    .eq("company_id", companyId);
+            if (parentDeptId == null) {
+                queryWrapper.isNull("superior_id");
+            } else {
+                queryWrapper.eq("superior_id", parentDeptId);
+            }
+            //获取第一级部门
+            List<Department> masterList = departmentMapper.selectList(queryWrapper);
             Map<String, Object> resultMap = new HashMap<>();
             List<DepartmentMasterVO> list = new ArrayList<>();
             BigDecimal totalCostMoney = new BigDecimal(0);
+            List<Department> allDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", companyId));
             for (Department department : masterList) {
                 DepartmentMasterVO departmentMasterVO = new DepartmentMasterVO();
                 BeanUtils.copyProperties(department, departmentMasterVO);
                 Map<String, Object> map = departmentMapper.getCostByDepartment(
-                        getBranchDepartment(department.getDepartmentId(), companyId), startDate, endDate);
+                        getBranchDepartment(department.getDepartmentId(), allDeptList), startDate, endDate);
                 Double time = map == null ? new Double(0) : (Double) map.get("time");
                 BigDecimal money = map == null ? new BigDecimal(0) : (BigDecimal) map.get("money");
                 totalCostMoney = totalCostMoney.add(money);
                 departmentMasterVO.setCostTime(time);
                 departmentMasterVO.setCostMoney(money);
+                //检查是否有子部门
+                if (allDeptList.stream().anyMatch(dept->department.getDepartmentId().equals(dept.getSuperiorId()))) {
+                    System.out.println("@@@@@@@@有子部门===");
+                    departmentMasterVO.setHasSubDept(true);
+                }
                 list.add(departmentMasterVO);
             }
             resultMap.put("totalCostMoney", totalCostMoney);
@@ -295,7 +308,8 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                 if (departmentMapper.selectCount(new QueryWrapper<Department>()
                         .eq("department_id", departmentId)
                         .eq("company_id", companyId)) == 1) {
-                    deptIds = getBranchDepartment(departmentId, companyId);
+                    List<Department> allDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", companyId));
+                    deptIds = getBranchDepartment(departmentId, allDeptList);
                 } else {
                     httpRespMsg.setError("部门不存在或无查看权限");
                     return httpRespMsg;
@@ -541,24 +555,36 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
         });
     }
 
-    //获取某个部门所有子部门id
-    private List<Integer> getBranchDepartment(Integer departmentId, Integer companyId) {
-        List<Department> departmentList = departmentMapper.selectList(new QueryWrapper<Department>()
-                .eq("company_id", companyId));
+    private List<Integer> getBranchDepartment(Integer departmentId, List<Department> departmentList) {
         List<Integer> list = new ArrayList<>();
         list.add(departmentId);
-        for (int i = 0; i < list.size(); i++) {
-            Integer targetId = list.get(i);
-            for (int j = 0; j < departmentList.size(); j++) {
-                Integer superiorId = departmentList.get(j).getSuperiorId();
-                if (superiorId == null) {
-                    departmentList.remove(j--);
-                } else if (superiorId.equals(targetId)) {
-                    list.add(departmentList.get(j).getDepartmentId());
-                    departmentList.remove(j--);
-                }
+        //搜到子部门进行添加
+        for (Department department : departmentList) {
+            if (departmentId.equals(department.getSuperiorId())) {
+                list.addAll(getBranchDepartment(department.getDepartmentId(), departmentList));
             }
         }
         return list;
     }
+
+    //获取某个部门所有子部门id
+//    private List<Integer> getBranchDepartment(Integer departmentId, Integer companyId) {
+//        List<Department> departmentList = departmentMapper.selectList(new QueryWrapper<Department>()
+//                .eq("company_id", companyId));
+//        List<Integer> list = new ArrayList<>();
+//        list.add(departmentId);
+//        for (int i = 0; i < list.size(); i++) {
+//            Integer targetId = list.get(i);
+//            for (int j = 0; j < departmentList.size(); j++) {
+//                Integer superiorId = departmentList.get(j).getSuperiorId();
+//                if (superiorId == null) {
+//                    departmentList.remove(j--);
+//                } else if (superiorId.equals(targetId)) {
+//                    list.add(departmentList.get(j).getDepartmentId());
+//                    departmentList.remove(j--);
+//                }
+//            }
+//        }
+//        return list;
+//    }
 }

+ 20 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceProjectsServiceImpl.java

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.FinanceProjects;
+import com.management.platform.mapper.FinanceProjectsMapper;
+import com.management.platform.service.FinanceProjectsService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-26
+ */
+@Service
+public class FinanceProjectsServiceImpl extends ServiceImpl<FinanceProjectsMapper, FinanceProjects> implements FinanceProjectsService {
+
+}

+ 384 - 19
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceServiceImpl.java

@@ -1,5 +1,7 @@
 package com.management.platform.service.impl;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.*;
 import com.management.platform.mapper.*;
@@ -64,6 +66,10 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
     private UserService userService;
     @Resource
     private FinanceTblcuscolMapper financeTblcuscolMapper;
+    @Resource
+    private FinanceProjectsMapper financeProjectsMapper;
+    @Resource
+    private ProjectPercentageMapper projectPercentageMapper;
 
     @Resource
     private ProjectMapper projectMapper;
@@ -74,6 +80,28 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
     public HttpRespMsg getByMonth(Integer companyId, String yearMonth) {
         HttpRespMsg msg = new HttpRespMsg();
         List<Finance> financeList = financeMapper.selectList(new QueryWrapper<Finance>().eq("company_id", companyId).eq("ymonth", yearMonth));
+
+        //当前月是否有项目日报数据
+        List<Map<String, Object>> userList = reportMapper.selectFillReportUserList(companyId, yearMonth+"-01", yearMonth+"-31");
+
+        financeList.forEach(f->{
+            if (f.getHasReport() == null) {
+                boolean has = false;
+                for (Map<String, Object> map : userList) {
+                    if (f.getUserId().equals(map.get("creatorId"))) {
+                        has = true;
+                        break;
+                    }
+                }
+                if (has) {
+                    f.setHasReport(1);
+                } else {
+                    f.setHasReport(0);
+                }
+            }
+
+        });
+
         msg.data = financeList;
         return msg;
     }
@@ -391,7 +419,7 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
     }
 
     @Override
-    public HttpRespMsg exportData(String yearMonth, HttpServletRequest request) {
+    public HttpRespMsg exportData(String yearMonth, Boolean assignNoProUser, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
@@ -443,6 +471,7 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
 
             List<Map<String, Object>> projectTimeList = reportMapper.getRealProjectTime(startDate, endDate, companyId);
 
+
             //计算每个项目的时间和成本
             ProjectSumItem item = new ProjectSumItem();
             List<ProjectSumItem> pList = new ArrayList<ProjectSumItem>();
@@ -461,11 +490,66 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                     userTime.get(creatorId).workingTime = userTime.get(creatorId).workingTime.add(new BigDecimal((Double)map.get("workingTime")));
                 }
             }
-
             List<Finance> finances = financeMapper.selectList(new QueryWrapper<Finance>().eq("company_id", companyId).eq("ymonth", yearMonth));
-            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
+            List<Finance> noProjectUser = new ArrayList<>();
+            //计算无项目的人员
+            for (Finance f : finances) {
+                boolean has = false;
+                for (Map<String, Object> map : projectTimeList) {
+                    String creatorId = (String) map.get("creatorId");
+                    if (creatorId.equals(f.getUserId())) {
+                        has = true;
+                        break;
+                    }
+                }
+                if (!has) {
+                    noProjectUser.add(f);
+                }
+            }
 
+            ProjectPercentage percentage = null;
+            List<FinanceProjects> financeProjects = financeProjectsMapper.selectList(new QueryWrapper<FinanceProjects>().eq("company_id", companyId).eq("ymonth", yearMonth));
+            //无项目工时人员的分配比例设置
+            List<Map> noPUserDataList = new ArrayList<>();
+            if (assignNoProUser != null && assignNoProUser && noProjectUser.size() > 0) {
+                //检查是否已经设置好分配规则
+                percentage = projectPercentageMapper.selectOne(new QueryWrapper<ProjectPercentage>().eq("company_id", companyId).eq("ymonth", yearMonth));
+                if (percentage == null) {
+                    httpRespMsg.setError("请先设置无项目工时人员的分配比例");
+                    return httpRespMsg;
+                } else {
+                    //获取设置的项目
+                    String data = percentage.getData();
+                    JSONArray parse = JSONArray.parseArray(data);
+                    //获取到无项目人员配置的项目
+                    financeProjects.forEach(f->{
+                        for (int i = 0; i < parse.size(); i++) {
+                            JSONObject json = parse.getJSONObject(i);
+                            String userId = json.getString("id");
+                            String username = json.getString("name");
+                            //获取各个项目的分配比例值
+                            HashMap userCostMap = new HashMap();
+                            userCostMap.put("creatorId", userId);
+                            userCostMap.put("workingTime", 0.0f);
+                            double percent = json.getDouble(f.getProjectId()+"");
+                            Finance finance = noProjectUser.stream().filter(no -> no.getUserId().equals(userId)).findFirst().get();
+//                            BigDecimal curProjectCost = finance.getTotalCost().multiply(new BigDecimal(percent)).divide(new BigDecimal(100));
+                            userCostMap.put("finance", finance);
+                            userCostMap.put("percent", percent);
+                            userCostMap.put("project", f.getProjectId());
+                            userCostMap.put("projectId", f.getProjectId());
+                            userCostMap.put("projectCode", f.getProjectCode());
+                            noPUserDataList.add(userCostMap);
+                        }
+                    });
+
+                }
+            }
+
+            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
             for (Map<String, Object> map : projectTimeList) {
+                Integer projectId = (Integer) map.get("projectId");
+                String curProjectCode = (String) map.get("projectCode");
                 String curProject = (String) map.get("project");
                 String creatorId = (String) map.get("creatorId");
                 Optional<Finance> first = finances.stream().filter(f -> f.getUserId().equals(creatorId)).findFirst();
@@ -532,6 +616,8 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                     item = new ProjectSumItem();
                     pList.add(item);
                     item.project = curProject;
+                    item.projectId = projectId;
+                    item.projectCode = curProjectCode;
                     item.workingTime = workingTime;
                     item.cost = cost;
                     item.salary = salary;
@@ -568,6 +654,83 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                 }
             }
 
+            //加上待分摊的无工时项目,如果当前项目列表没有的话
+            if (assignNoProUser != null && assignNoProUser) {
+                List<FinanceProjects> notInFPList = new ArrayList<FinanceProjects>();
+                financeProjects.forEach(f->{
+                    if (!projectTimeList.stream().anyMatch(map->((Integer)map.get("projectId")).equals(f.getProjectId()))) {
+                        notInFPList.add(f);
+                    }
+                });
+                if (notInFPList.size() > 0) {
+                    //添加进去
+                    notInFPList.forEach(np->{
+                        ProjectSumItem npItem = new ProjectSumItem();
+                        npItem.project = np.getProjectName();
+                        npItem.projectCode = np.getProjectCode();
+                        npItem.projectId = np.getProjectId();
+                        //初始设置为0
+                        npItem.cost = new BigDecimal(0);
+                        npItem.salary = new BigDecimal(0);
+                        npItem.bonus = new BigDecimal(0);
+                        npItem.allowance = new BigDecimal(0);
+                        npItem.old = new BigDecimal(0);
+                        npItem.medical = new BigDecimal(0);
+                        npItem.loseJob = new BigDecimal(0);
+                        npItem.injury = new BigDecimal(0);
+                        npItem.house = new BigDecimal(0);
+                        npItem.field1 = new BigDecimal(0);
+                        npItem.field2 = new BigDecimal(0);
+                        npItem.field3 = new BigDecimal(0);
+                        pList.add(npItem);
+                    });
+                }
+                //按比例分配
+                for (ProjectSumItem p : pList) {
+                    List<Map> filterUserList = noPUserDataList.stream().filter(map->((Integer)map.get("projectId")).equals(p.projectId)).collect(Collectors.toList());
+                    for (Map f : filterUserList) {
+                        String curUserId = (String)f.get("creatorId");
+                        double percent = (double)f.get("percent");
+                        Finance finance = (Finance)f.get("finance");
+                        System.out.println(finance.getTotalCost());
+                        //各项收入按比例计算,累加到当前项目上
+                        Finance newFinance = Finance.getByPercent(finance, percent);
+                        p.cost = p.cost.add(newFinance.getTotalCost());
+                        p.salary = p.salary.add(newFinance.getMonthCost());
+                        p.bonus = p.bonus.add(newFinance.getBonus());
+                        p.allowance = p.allowance.add(newFinance.getAllowance());
+                        p.old = p.old.add(newFinance.getInsuranceOld());
+                        p.medical = p.medical.add(newFinance.getInsuranceMedical());
+                        p.loseJob = p.loseJob.add(newFinance.getInsuranceLosejob());
+                        p.injury = p.injury.add(newFinance.getInsuranceInjury());
+                        p.house = p.house.add(newFinance.getHouseFund());
+//                    item.other = item.other.add(other);
+                        p.field1 = p.field1.add(newFinance.getCustomField1());
+                        p.field2 = p.field2.add(newFinance.getCustomField2());
+                        p.field3 = p.field3.add(newFinance.getCustomField3());
+
+                        //叠加到总计的各项成本上
+                        totalMoneyCost = totalMoneyCost.add(newFinance.getTotalCost());
+                        totalSalary = totalSalary.add(newFinance.getMonthCost());
+                        totalBonus = totalBonus.add(newFinance.getBonus());
+                        totalAllowance = totalAllowance.add(newFinance.getAllowance());
+                        totalOld = totalOld.add(newFinance.getInsuranceOld());
+                        totalMedical = totalMedical.add(newFinance.getInsuranceMedical());
+                        totalLoseJob = totalLoseJob.add(newFinance.getInsuranceLosejob());
+                        totalInjury = totalInjury.add((newFinance.getInsuranceInjury()));
+                        totalHouse = totalHouse.add(newFinance.getHouseFund());
+                        if (totalField1 != null) {
+                            totalField1 = totalField1.add(newFinance.getCustomField1());
+                        }
+                        if (totalField2 != null) {
+                            totalField2 = totalField2.add(newFinance.getCustomField2());
+                        }
+                        if (totalField3 != null) {
+                            totalField3 = totalField3.add(newFinance.getCustomField3());
+                        }
+                    }
+                }
+            }
 
             //整体四舍五入处理
             totalMoneyCost = totalMoneyCost.setScale(2, BigDecimal.ROUND_HALF_UP);
@@ -589,6 +752,55 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
             if (totalField3 != null) {
                 totalField3 = totalField3.setScale(2, BigDecimal.ROUND_HALF_UP);
             }
+
+
+//            if (assignNoProUser != null && assignNoProUser) {
+                //按比例分摊
+                
+                //均摊各项成本到项目
+//                for (Finance npu : noProjectUser) {
+//                    pList.forEach(p->{
+//                        p.cost = p.cost.add(npu.getTotalCost().divide(new BigDecimal(pList.size())));
+//                        p.salary = p.salary.add(npu.getMonthCost().divide(new BigDecimal(pList.size())));
+//                        p.bonus = p.bonus.add(npu.getBonus().divide(new BigDecimal(pList.size())));
+//                        p.allowance = p.allowance.add(npu.getAllowance().divide(new BigDecimal(pList.size())));
+//                        p.old = p.old.add(npu.getInsuranceOld().divide(new BigDecimal(pList.size())));
+//                        p.medical = p.medical.add(npu.getInsuranceMedical().divide(new BigDecimal(pList.size())));
+//                        p.loseJob = p.loseJob.add(npu.getInsuranceLosejob().divide(new BigDecimal(pList.size())));
+//                        p.injury = p.injury.add(npu.getInsuranceInjury().divide(new BigDecimal(pList.size())));
+//                        p.house = p.house.add(npu.getHouseFund().divide(new BigDecimal(pList.size())));
+//                        //处理自定义字段的数据累加
+//                        if (npu.getCustomField1() != null) {
+//                            p.field1 = p.field1.add(npu.getCustomField1().divide(new BigDecimal(pList.size())));
+//                        }
+//                        if (npu.getCustomField2() != null) {
+//                            p.field2 = p.field2.add(npu.getCustomField2().divide(new BigDecimal(pList.size())));
+//                        }
+//                        if (npu.getCustomField3() != null) {
+//                            p.field3 = p.field3.add(npu.getCustomField3().divide(new BigDecimal(pList.size())));
+//                        }
+//                    });
+//                    totalMoneyCost = totalMoneyCost.add(npu.getTotalCost());
+//                    totalSalary = totalSalary.add(npu.getMonthCost());
+//                    totalBonus = totalBonus.add(npu.getBonus());
+//                    totalAllowance = totalAllowance.add(npu.getAllowance());
+//                    totalOld = totalOld.add(npu.getInsuranceOld());
+//                    totalMedical = totalMedical.add(npu.getInsuranceMedical());
+//                    totalLoseJob = totalLoseJob.add(npu.getInsuranceLosejob());
+//                    totalInjury = totalInjury.add(npu.getInsuranceInjury());
+//                    totalHouse = totalHouse.add(npu.getHouseFund());
+////                totalOther = totalOther.add(other);
+//                    if (totalField1 != null && npu.getCustomField1() != null) {
+//                        totalField1 = totalField1.add(npu.getTotalCost());
+//                    }
+//                    if (totalField2 != null && npu.getCustomField2() != null) {
+//                        totalField2 = totalField2.add(npu.getCustomField2());
+//                    }
+//                    if (totalField3 != null && npu.getCustomField3() != null) {
+//                        totalField3 = totalField3.add(npu.getCustomField3());
+//                    }
+//                }
+//            }
             pList.forEach(p->{
                 p.cost = p.cost.setScale(2, BigDecimal.ROUND_HALF_UP);
                 p.salary = p.salary.setScale(2, BigDecimal.ROUND_HALF_UP);
@@ -684,8 +896,62 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                         allList.add(membRowData);
                     }
                 }
-            });
 
+                //无项目人员成本
+                if (assignNoProUser != null && assignNoProUser) {
+                    for (Finance npu : noProjectUser) {
+                        List<String> membRowData = new ArrayList<String>();
+                        membRowData.add("");
+                        Double workingTime = new Double(0);
+                        Finance userFinance = npu;
+                        Optional<Map> op = noPUserDataList.stream().filter(map->((Integer)map.get("projectId")).equals(p.projectId) && ((String)map.get("creatorId")).equals(npu.getUserId())).findFirst();
+                        if (op.isPresent()) {
+                            Map percentMap = op.get();
+                            double percent = (double)percentMap.get("percent");
+                            if (percent > 0) {
+                                //各项收入按比例计算,累加到当前项目上
+                                Finance newFinance = Finance.getByPercent(npu, percent);
+
+                                BigDecimal cost = newFinance.getTotalCost();
+                                BigDecimal salary = newFinance.getMonthCost();
+                                BigDecimal bonus = newFinance.getBonus();
+                                BigDecimal allowance = newFinance.getAllowance();
+                                BigDecimal old = newFinance.getInsuranceOld();
+                                BigDecimal medical = newFinance.getInsuranceMedical();
+                                BigDecimal loseJob = newFinance.getInsuranceLosejob();
+                                BigDecimal injury = newFinance.getInsuranceInjury();
+                                BigDecimal house = newFinance.getHouseFund();
+                                BigDecimal field1 = newFinance.getCustomField1() == null? new BigDecimal(0):newFinance.getCustomField1();
+                                BigDecimal field2 = newFinance.getCustomField2() == null? new BigDecimal(0):newFinance.getCustomField2();
+                                BigDecimal field3 = newFinance.getCustomField3() == null? new BigDecimal(0):newFinance.getCustomField3();
+
+                                membRowData.add(npu.getName());
+                                membRowData.add(workingTime+"");
+                                membRowData.add(salary.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                membRowData.add(bonus.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                membRowData.add(allowance.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                membRowData.add(old.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                membRowData.add(medical.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                membRowData.add(loseJob.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                membRowData.add(injury.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                membRowData.add(house.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                //自定义字段
+                                if (cusColList.size() > 0) {
+                                    membRowData.add(field1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                }
+                                if (cusColList.size() > 1) {
+                                    membRowData.add(field2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                }
+                                if (cusColList.size() > 2) {
+                                    membRowData.add(field3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                }
+                                membRowData.add(cost.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
+                                allList.add(membRowData);
+                            }
+                        }
+                    }
+                }
+            });
 
             //合计
             List<String> sumRow = new ArrayList<String>();
@@ -721,7 +987,7 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
     }
 
     @Override
-    public HttpRespMsg getTimeCost(String yearMonth, HttpServletRequest request) {
+    public HttpRespMsg getTimeCost(String yearMonth, Boolean assignNoProUser, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
@@ -752,16 +1018,24 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                     userTime.put(creatorId, d);
                 }
             }
-            Set<String> strings = userTime.keySet();
-            Iterator<String> iterator = strings.iterator();
-            while (iterator.hasNext()) {
-                String next = iterator.next();
-                System.out.println(next+": "+userTime.get(next));
-            }
             List<Finance> finances = financeMapper.selectList(new QueryWrapper<Finance>().eq("company_id", companyId).eq("ymonth", yearMonth));
-            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
             //未投入项目的人员
             ProjectSumItem noProjectItem = new ProjectSumItem();
+            List<Finance> noProjectUser = new ArrayList<>();
+            //计算无项目的人员
+            for (Finance f : finances) {
+                boolean has = false;
+                for (Map<String, Object> map : projectTimeList) {
+                    String creatorId = (String) map.get("creatorId");
+                    if (creatorId.equals(f.getUserId())) {
+                        has = true;
+                        break;
+                    }
+                }
+                if (!has) {
+                    noProjectUser.add(f);
+                }
+            }
 
             finances.forEach(f->{
                 String uid = f.getUserId();
@@ -773,10 +1047,8 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                         noProjectItem.project = "无项目";
                         noProjectItem.workingTime = 0;
                         noProjectItem.cost = new BigDecimal(0);
-
                     }
                     noProjectItem.cost = noProjectItem.cost.add(f.getTotalCost());
-
                 } else {
                     BigDecimal avgHourCost = f.getTotalCost().divide(b,6, BigDecimal.ROUND_HALF_UP);
                     f.setHourCost(avgHourCost);
@@ -785,6 +1057,7 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
 
 
             for (Map<String, Object> map : projectTimeList) {
+                Integer projectId = (Integer) map.get("projectId");
                 String curProject = (String) map.get("project");
                 String creatorId = (String) map.get("creatorId");
                 Optional<Finance> first = finances.stream().filter(f -> f.getUserId().equals(creatorId)).findFirst();
@@ -802,17 +1075,89 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                 } else {
                     item = new ProjectSumItem();
                     pList.add(item);
+                    item.projectId = projectId;
                     item.project = curProject;
                     item.workingTime = workingTime;
                     item.cost = cost;
                 }
                 totalMoneyCost = totalMoneyCost.add(cost);
             }
-//            //存在无项目的人员,加入总成本
-//            if (noProjectItem.project != null){
-//                totalMoneyCost = totalMoneyCost.add(noProjectItem.cost);
-//                pList.add(noProjectItem);
-//            }
+
+
+            //加上待分摊的无工时项目,如果当前项目列表没有的话
+            if (assignNoProUser != null && assignNoProUser && noProjectItem.project != null) {
+                List<FinanceProjects> financeProjects = financeProjectsMapper.selectList(new QueryWrapper<FinanceProjects>().eq("company_id", companyId).eq("ymonth", yearMonth));
+
+                //检查是否已经设置好分配规则
+                ProjectPercentage percentage = projectPercentageMapper.selectOne(new QueryWrapper<ProjectPercentage>().eq("company_id", companyId).eq("ymonth", yearMonth));
+                List<Map> noPUserDataList = new ArrayList<>();
+                //构造各个项目的分配比例
+                if (percentage == null) {
+                    httpRespMsg.setError("请先设置无项目工时人员的分配比例");
+                    return httpRespMsg;
+                } else {
+                    //获取设置的项目
+                    String data = percentage.getData();
+                    JSONArray parse = JSONArray.parseArray(data);
+                    //获取到无项目人员配置的项目
+                    financeProjects.forEach(f->{
+                        for (int i = 0; i < parse.size(); i++) {
+                            JSONObject json = parse.getJSONObject(i);
+                            String userId = json.getString("id");
+                            String username = json.getString("name");
+                            //获取各个项目的分配比例值
+                            HashMap userCostMap = new HashMap();
+                            userCostMap.put("creatorId", userId);
+                            userCostMap.put("workingTime", 0.0f);
+                            double percent = json.getDouble(f.getProjectId()+"");
+                            Finance finance = noProjectUser.stream().filter(no -> no.getUserId().equals(userId)).findFirst().get();
+//                            BigDecimal curProjectCost = finance.getTotalCost().multiply(new BigDecimal(percent)).divide(new BigDecimal(100));
+                            userCostMap.put("finance", finance);
+                            userCostMap.put("percent", percent);
+                            userCostMap.put("project", f.getProjectId());
+                            userCostMap.put("projectId", f.getProjectId());
+                            userCostMap.put("projectCode", f.getProjectCode());
+                            noPUserDataList.add(userCostMap);
+                        }
+                    });
+                }
+
+
+                List<FinanceProjects> notInFPList = new ArrayList<FinanceProjects>();
+                financeProjects.forEach(f->{
+                    if (!projectTimeList.stream().anyMatch(map->((Integer)map.get("projectId")).equals(f.getProjectId()))) {
+                        notInFPList.add(f);
+                    }
+                });
+                if (notInFPList.size() > 0) {
+                    //添加进去
+                    notInFPList.forEach(np->{
+                        ProjectSumItem npItem = new ProjectSumItem();
+                        npItem.project = np.getProjectName();
+                        npItem.projectCode = np.getProjectCode();
+                        npItem.projectId = np.getProjectId();
+                        //初始设置为0
+                        npItem.cost = new BigDecimal(0);
+                        pList.add(npItem);
+                    });
+                }
+                //按比例分配
+                for (ProjectSumItem p : pList) {
+                    List<Map> filterUserList = noPUserDataList.stream().filter(map->((Integer)map.get("projectId")).equals(p.projectId)).collect(Collectors.toList());
+                    System.out.println(p.project+", 找到匹配人员=="+filterUserList.size());
+                    for (Map f : filterUserList) {
+                        String curUserId = (String)f.get("creatorId");
+                        double percent = (double)f.get("percent");
+                        Finance finance = (Finance)f.get("finance");
+                        //各项收入按比例计算,累加到当前项目上
+                        Finance newFinance = Finance.getByPercent(finance, percent);
+                        System.out.println("比例=="+newFinance.getTotalCost());
+                        p.cost = p.cost.add(newFinance.getTotalCost());
+                        //叠加到总计的各项成本上
+                        totalMoneyCost = totalMoneyCost.add(newFinance.getTotalCost());
+                    }
+                }
+            }
 
             //整体四舍五入处理
             totalMoneyCost = totalMoneyCost.setScale(2, BigDecimal.ROUND_HALF_UP);
@@ -864,4 +1209,24 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
     }
 
 
+    public HttpRespMsg getProjects(Integer companyId, String yearMonth) {
+        HttpRespMsg msg = new HttpRespMsg();
+        //如果没有记录,默认返回全部的
+        List<FinanceProjects> list = financeProjectsMapper.selectList(new QueryWrapper<FinanceProjects>().eq("company_id", companyId).eq("ymonth", yearMonth));
+        List<Project> allProjects = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", companyId));
+        if (list.size() == 0) {
+            allProjects.forEach(a->{
+                FinanceProjects item = new FinanceProjects();
+                item.setProjectId(a.getId());
+                item.setProjectCode(a.getProjectCode());
+                item.setProjectName(a.getProjectName());
+                list.add(item);
+            });
+        }
+        HashMap map = new HashMap();
+        map.put("allProjectList", allProjects);
+        map.put("financeProjects", list);
+        msg.data = map;
+        return msg;
+    }
 }

+ 115 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectPercentageServiceImpl.java

@@ -0,0 +1,115 @@
+package com.management.platform.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.FinanceProjects;
+import com.management.platform.entity.Project;
+import com.management.platform.entity.ProjectPercentage;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.ProjectMapper;
+import com.management.platform.mapper.ProjectPercentageMapper;
+import com.management.platform.mapper.ReportMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.FinanceProjectsService;
+import com.management.platform.service.ProjectPercentageService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-26
+ */
+@Service
+public class ProjectPercentageServiceImpl extends ServiceImpl<ProjectPercentageMapper, ProjectPercentage> implements ProjectPercentageService {
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private FinanceProjectsService financeProjectsService;
+    @Resource
+    private ProjectPercentageMapper projectPercentageMapper;
+    @Resource
+    private ProjectMapper projectMapper;
+    @Resource
+    private ReportMapper reportMapper;
+
+    @Override
+    public HttpRespMsg saveMonthSetting(String projectCols, String userSettings, String ymonth) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        List<FinanceProjects> financeProjects = JSONArray.parseArray(projectCols, FinanceProjects.class);
+        financeProjects.forEach(f->{
+            f.setCompanyId(user.getCompanyId());
+            f.setYmonth(ymonth);
+        });
+        financeProjectsService.remove(new QueryWrapper<FinanceProjects>().eq("company_id", user.getCompanyId()));
+        financeProjectsService.saveBatch(financeProjects);
+
+        ProjectPercentage projectPercentage = projectPercentageMapper.selectOne(new QueryWrapper<ProjectPercentage>().eq("company_id", user.getCompanyId())
+                .eq("ymonth", ymonth));
+        if (projectPercentage == null) {
+            projectPercentage = new ProjectPercentage();
+            projectPercentage.setCompanyId(user.getCompanyId());
+            projectPercentage.setData(userSettings);
+            projectPercentage.setYmonth(ymonth);
+            projectPercentageMapper.insert(projectPercentage);
+        } else {
+            projectPercentage.setCompanyId(user.getCompanyId());
+            projectPercentage.setData(userSettings);
+            projectPercentage.setYmonth(ymonth);
+            projectPercentageMapper.updateById(projectPercentage);
+        }
+
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg getMonthSetting(String ymonth) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        Integer companyId = user.getCompanyId();
+        List<Project> allProjects = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", companyId));
+
+        List<FinanceProjects> flist = financeProjectsService.list(new QueryWrapper<FinanceProjects>().eq("company_id", user.getCompanyId()));
+        ProjectPercentage projectPercentage = projectPercentageMapper.selectOne(new QueryWrapper<ProjectPercentage>().eq("company_id", user.getCompanyId())
+                .eq("ymonth", ymonth));
+
+        if (flist.size() == 0) {
+            //默认加载当月已填日报的项目
+            List<Map<String, Object>> monthReportProjectList = reportMapper.getMonthReportProjectList(companyId, ymonth + "-01", ymonth + "-31");
+            monthReportProjectList.forEach(a->{
+                FinanceProjects item = new FinanceProjects();
+                item.setProjectId((Integer)a.get("id"));
+                item.setProjectCode((String)a.get("projectCode"));
+                item.setProjectName((String)a.get("projectName"));
+                flist.add(item);
+            });
+        }
+
+        HashMap map = new HashMap();
+        map.put("financeProjects", flist);
+        map.put("allProjectList", allProjects);
+        if (projectPercentage != null) {
+            map.put("userCostSetting", JSONArray.parseArray(projectPercentage.getData()));
+        } else {
+            map.put("userCostSetting", new JSONArray());
+        }
+
+        msg.data = map;
+        return msg;
+    }
+}

+ 62 - 16
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -61,8 +61,12 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     @Resource
     private ReportMapper reportMapper;
     @Resource
+    private SubProjectMapper subProjectMapper;
+    @Resource
     private ParticipationMapper participationMapper;
     @Resource
+    private FinanceProjectsMapper financeProjectsMapper;
+    @Resource
     private ProjectTimerMapper projectTimerMapper;
     @Resource
     private TaskMapper taskMapper;
@@ -371,6 +375,12 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
 
                         }
                     }
+
+                    //更新关联表中的项目名称和编号
+                    FinanceProjects fp = new FinanceProjects();
+                    fp.setProjectName(p.getProjectName());
+                    fp.setProjectCode(p.getProjectCode());
+                    financeProjectsMapper.update(fp, new QueryWrapper<FinanceProjects>().eq("project_id", p.getId()));
                 }
             }
         }
@@ -546,7 +556,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
 
     //导出查询者所在公司每个项目的工时成本,包括项目人员明细统计
     @Override
-    public HttpRespMsg exportTimeCost(String startDate, String endDate,Integer projectId, String userId, HttpServletRequest request) {
+    public HttpRespMsg exportTimeCost(String startDate, String endDate,Integer projectId, String userId, Boolean projectSum, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
@@ -554,8 +564,10 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             List<Map<String, Object>> list = projectMapper.getTimeCost(companyId, startDate, endDate, projectId, userId);
             BigDecimal totalMoneyCost = BigDecimal.valueOf(0);
             List<String> headList = new ArrayList<String>();
-            headList.add("项目");
+            headList.add("项目编号");
+            headList.add("项目名称");
             headList.add("人员");
+            headList.add("部门");
             headList.add("工时(h)");
             headList.add("成本(元)");
             List<List<String>> allList = new ArrayList<List<String>>();
@@ -572,30 +584,44 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 }
                 totalCostTime += (Double)map.get("cost");
                 List<String> rowData = new ArrayList<String>();
+                rowData.add((String)map.get("projectCode"));
                 rowData.add((String)map.get("project"));
                 rowData.add("");
+                rowData.add("");
                 rowData.add(((Double)map.get("cost")).toString());
                 rowData.add(((BigDecimal)map.get("costMoney")).toString());
-                allList.add(rowData);
+                if (projectSum != null && projectSum == true) {
+                    allList.add(rowData);
+                }
+
                 //统计每个项目中的人员时间成本投入
                 int curProjectId = (Integer)map.get("id");
                 List<Map<String, Object>> membList = projectMapper.getProjectCost(startDate, endDate, curProjectId, userId);
                 map.put("membList", membList);
                 for (Map<String, Object> membMap : membList) {
                     List<String> membRowData = new ArrayList<String>();
-                    membRowData.add("");
+                    if (projectSum == null || projectSum == false) {
+                        membRowData.add((String)map.get("projectCode"));
+                        membRowData.add((String)map.get("project"));
+                    } else {
+                        membRowData.add("");
+                        membRowData.add("");
+                    }
+
                     membRowData.add((String)membMap.get("name"));
+                    membRowData.add((String)membMap.get("departmentName"));
                     membRowData.add(((Double)membMap.get("cost")).toString());
                     membRowData.add(((BigDecimal)membMap.get("costMoney")).toString());
                     allList.add(membRowData);
                 }
             }
-            String total = totalMoneyCost.toString();
             //合计
             List<String> sumRow = new ArrayList<String>();
             sumRow.add("合计");
             sumRow.add("");
-            sumRow.add(""+totalCostTime);
+            sumRow.add("");
+            sumRow.add("");
+            sumRow.add(""+new BigDecimal(totalCostTime).setScale(1, BigDecimal.ROUND_HALF_UP));
             sumRow.add(totalMoneyCost.toString());
             allList.add(sumRow);
             //生成excel文件导出
@@ -1471,16 +1497,18 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 //项目编号	项目名称 参与人 负责人 级别 开始日期 截止日期 合同金额
                 XSSFCell codeCell = row.getCell(0);
                 XSSFCell nameCell = row.getCell(1);
-                XSSFCell participatorCell = row.getCell(2);
-                XSSFCell inchargerCell = row.getCell(3);
-                XSSFCell levelCell = row.getCell(4);
-                XSSFCell startDateCell = row.getCell(5);
-                XSSFCell endDateCell = row.getCell(6);
-                XSSFCell amountCell = row.getCell(7);
-                XSSFCell isPublicCell = row.getCell(8);
+                XSSFCell subNameCell = row.getCell(2);
+                XSSFCell participatorCell = row.getCell(3);
+                XSSFCell inchargerCell = row.getCell(4);
+                XSSFCell levelCell = row.getCell(5);
+                XSSFCell startDateCell = row.getCell(6);
+                XSSFCell endDateCell = row.getCell(7);
+                XSSFCell amountCell = row.getCell(8);
+                XSSFCell isPublicCell = row.getCell(9);
 
                 if (codeCell != null)codeCell.setCellType(CellType.STRING);
                 if (nameCell != null)nameCell.setCellType(CellType.STRING);
+                if (subNameCell != null)subNameCell.setCellType(CellType.STRING);
                 if (participatorCell != null)participatorCell.setCellType(CellType.STRING);
                 if (inchargerCell != null)inchargerCell.setCellType(CellType.STRING);
                 if (levelCell != null)levelCell.setCellType(CellType.STRING);
@@ -1496,6 +1524,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 if (codeCell != null) {
                     String code = codeCell.getStringCellValue().trim().replaceAll("\\u00a0", "");
                     if (code.equals("项目编号") && rowIndex == 0) {
+                        //检查是否有子项目列
+                        if (!subNameCell.getStringCellValue().trim().startsWith("子项目")) {
+                            msg.setError("缺少子项目列,请下载最新模板");
+                            return msg;
+                        }
                         //跳过第一行标题
                         continue;
                     }
@@ -1514,6 +1547,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 project.setCreatorId(userId);
                 project.setCreatorName(user.getName());
                 project.setProjectName(name);
+
                 //处理人员
                 if (inchargerCell != null) {
                     String inchargerName = inchargerCell.getStringCellValue();
@@ -1550,6 +1584,21 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     project.setIsPublic("是".equals(isPublicCell.getStringCellValue())?1:0);
                 }
                 projectMapper.insert(project);
+                //处理子项目
+                if (subNameCell != null) {
+                    //兼容中英文逗号
+                    String[] subNames = subNameCell.getStringCellValue().trim().split(",|,");
+                    if (subNames != null) {
+                        for (String s : subNames) {
+                            if (!StringUtils.isEmpty(s)) {
+                                SubProject sp = new SubProject();
+                                sp.setName(s);
+                                sp.setProjectId(project.getId());
+                                subProjectMapper.insert(sp);
+                            }
+                        }
+                    }
+                }
                 //参与人
                 if (participatorCell != null) {
                     String part = participatorCell.getStringCellValue();
@@ -1569,10 +1618,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                         }
                     }
                 }
-
             }
-            //批量插入
-            //projectService.saveOrUpdateBatch(projectList);
         } catch (IOException e) {
             e.printStackTrace();
             msg.setError("文件处理出错");

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

@@ -1919,7 +1919,9 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             //由于第一行需要指明列对应的标题
             int rowNum = sheet.getLastRowNum();
             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<>();
             int projectNameStartIndex = (withCheckIn==null?2:6);
 
@@ -1936,13 +1938,25 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     int pIndex = projectNameStartIndex;
                     boolean projectNotExists = false;
                     String neProjectName = null;
+                    boolean subPNotExists = false;
+                    String neSubPName = null;
                     while(pIndex < row.getLastCellNum() && row.getCell(pIndex).getCellTypeEnum() != CellType._NONE &&  row.getCell(pIndex).getCellTypeEnum() != CellType.BLANK) {
                         row.getCell(pIndex).setCellType(CellType.STRING);
                         String stringCellValue = row.getCell(pIndex).getStringCellValue().trim();
-                        projectList.add(stringCellValue);
-                        if (!allProjectList.stream().filter(p->p.getProjectName().equals(stringCellValue)).findAny().isPresent()) {
+                        final String projectName = stringCellValue.contains("/")?stringCellValue.split("/")[0].trim():stringCellValue;
+                        projectList.add(projectName);
+                        String subProject = stringCellValue.contains("/")?stringCellValue.split("/")[1].trim():"";
+
+                        subProjectList.add(subProject);
+                        if (!allProjectList.stream().filter(p->p.getProjectName().equals(projectName)).findAny().isPresent()) {
                             projectNotExists = true;
-                            neProjectName = stringCellValue;
+                            neProjectName = projectName;
+                            break;
+                        }
+                        //检查子项目是否存在
+                        if (!StringUtils.isEmpty(subProject) && !allSubProjectList.stream().anyMatch(subp->subp.getName().equals(subProject))) {
+                            subPNotExists = true;
+                            neSubPName = subProject;
                             break;
                         }
                         pIndex++;
@@ -1952,6 +1966,11 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         msg.setError("项目["+neProjectName+"]不存在,请先在项目管理中添加或导入。");
                         return msg;
                     }
+                    if (subPNotExists) {
+                        //返回错误提示
+                        msg.setError("子项目["+neSubPName+"]不存在,请先在项目管理中添加或导入。");
+                        return msg;
+                    }
                 } else {
                     //数据行
                     for (int i=1;i<projectNameStartIndex+projectList.size(); i++) {
@@ -1976,7 +1995,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         double time = 0;
                         String pName = projectList.get(i-projectNameStartIndex);
                         Project project = allProjectList.stream().filter(p -> p.getProjectName().equals(pName)).findFirst().get();
-
+                        String subPName = subProjectList.get(i-projectNameStartIndex);
                         if (!StringUtils.isEmpty(stringCellValue)) {
                             time = Double.parseDouble(stringCellValue);
                             if (time > 0) {
@@ -1985,6 +2004,14 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                 report.setCompanyId(companyId);
                                 report.setCreatorId(reportCreator.getId());
                                 report.setProjectId(project.getId());
+                                //子项目
+                                if (!StringUtils.isEmpty(subPName)) {
+                                    Optional<SubProject> first = allSubProjectList.stream()
+                                            .filter(sub -> sub.getProjectId().equals(project.getId()) && sub.getName().equals(subPName)).findFirst();
+                                    if (first.isPresent()) {
+                                        report.setSubProjectId(first.get().getId());
+                                    }
+                                }
                                 report.setReportTimeType(1);
                                 report.setWorkingTime(time);
                                 report.setMultiWorktime(timeType.getMultiWorktime());
@@ -2145,6 +2172,9 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             if (user.getRole() == 0) {
                 //普通员工只能看自己的
                 allReportByDate = reportMapper.getAllReportByDate(startDate, null, user.getId(), endDate, projectId);
+            }else if (user.getRole() == 5) {
+                //项目管理员,看自己创建的项目相关的日报
+                allReportByDate = reportMapper.getPMOReportByDate(startDate, null, user.getId(), endDate);
             } else {
                 //管理员看公司所有人的
                 allReportByDate = reportMapper.getAllReportByDate(startDate, user.getCompanyId(), null, endDate, projectId);

+ 26 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ExpenseItemMapper.xml

@@ -18,9 +18,35 @@
         <result column="pic" property="pic" />
     </resultMap>
 
+    <resultMap id="UserBaseResultMap" type="com.management.platform.entity.vo.ExpenseItemVO">
+        <id column="id" property="id" />
+        <result column="expense_id" property="expenseId" />
+        <result column="project_id" property="projectId" />
+        <result column="happen_date" property="happenDate" />
+        <result column="invoice_type" property="invoiceType" />
+        <result column="invoice_no" property="invoiceNo" />
+        <result column="tax_percent" property="taxPercent" />
+        <result column="tax_value" property="taxValue" />
+        <result column="amount" property="amount" />
+        <result column="remark" property="remark" />
+        <result column="expense_type" property="expenseType" />
+        <result column="pic" property="pic" />
+        <result column="username" property="username" />
+        <result column="department_name" property="departmentName" />
+    </resultMap>
+
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
         id, expense_id, project_id, happen_date, invoice_type, invoice_no, tax_percent, tax_value, amount, remark, expense_type, pic
     </sql>
 
+    <select id="getUserExpenseDetail" resultMap="UserBaseResultMap">
+        select a.id, a.expense_id, a.project_id, a.happen_date, a.invoice_type, a.tax_percent, a.tax_value, a.amount, a.remark, a.expense_type, a.pic,
+        user.name as username, department.department_name
+        from expense_item a left join expense_sheet b on a.expense_id = b.id
+        left join user on user.id = b.owner_id
+        left join department on department.department_id = user.department_id
+        where a.project_id = #{projectId}
+    </select>
+
 </mapper>

+ 20 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/FinanceProjectsMapper.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.management.platform.mapper.FinanceProjectsMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.FinanceProjects">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="ymonth" property="ymonth" />
+        <result column="project_id" property="projectId" />
+        <result column="project_name" property="projectName" />
+        <result column="project_code" property="projectCode" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, ymonth, project_id, project_name, project_code
+    </sql>
+
+</mapper>

+ 4 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml

@@ -90,7 +90,7 @@
 
     <!--获取查询者所在公司每个项目的工时成本-->
     <select id="getTimeCost" resultType="java.util.Map">
-        SELECT a.id, a.project_name AS project, SUM(b.working_time) AS cost, SUM(b.cost) AS costMoney
+        SELECT a.id, a.project_code as projectCode, a.project_name AS project, SUM(b.working_time) AS cost, SUM(b.cost) AS costMoney
         FROM project AS a
         LEFT JOIN report AS b ON b.project_id = a.id
         JOIN user AS c ON b.creator_id = c.id
@@ -139,9 +139,10 @@
 
     <!--获取某个项目每个人分别需要的工时-->
     <select id="getProjectCost" resultType="java.util.Map">
-        SELECT b.id as creatorId, b.name, SUM(a.working_time) AS cost, SUM(a.cost) AS costMoney
+        SELECT b.id as creatorId, b.name,department.department_name as departmentName, SUM(a.working_time) AS cost, SUM(a.cost) AS costMoney
         FROM report AS a
         JOIN user AS b ON a.creator_id = b.id
+        left join department on department.department_id = b.department_id
         WHERE a.project_id = #{projectId}
         AND a.state = 1
         <if test="startDate != null and endDate != null">
@@ -186,7 +187,7 @@
     </select>
     <!--分页获取项目成本 -->
     <select id="getAllProjectCost" resultMap="BaseResultMap">
-        SELECT project_code, project_name,
+        SELECT id, project_code, project_name,
         (SELECT IFNULL(SUM(cost),0) FROM report WHERE state = 1 AND project_id = project.id) AS fee_man,
         (SELECT IFNULL(SUM(amount),0) FROM expense_item , expense_sheet WHERE project_id = project.id AND  expense_sheet.id = expense_item.`expense_id` AND expense_sheet.type = 0 and expense_sheet.status = 0) AS fee_normal,
         (SELECT IFNULL(SUM(amount),0) FROM expense_item , expense_sheet WHERE project_id = project.id AND  expense_sheet.id = expense_item.`expense_id` AND expense_sheet.type = 1 and expense_sheet.status = 0) AS fee_travel,

+ 18 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectPercentageMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.management.platform.mapper.ProjectPercentageMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ProjectPercentage">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="data" property="data" />
+        <result column="ymonth" property="ymonth" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, data, ymonth
+    </sql>
+
+</mapper>

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

@@ -73,6 +73,31 @@
         ORDER BY a.creator_id, a.create_date desc
     </select>
 
+    <select id="getPMOReportByDate" resultType="java.util.Map">
+        SELECT c.name, b.project_name AS project, a.working_time AS duration, a.content, a.create_time AS time, a.create_date as createDate,
+        a.state, a.time_type as timeType, a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,
+        a.end_time as endTime, d.name as subProjectName,a.task_id as taskId, task.name as taskName, a.is_overtime as isOvertime,a.progress as progress,
+        a.department_audit_state as departmentAuditState, a.pic_str as picStr, multi_worktime as multiWorktime
+        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName
+        FROM report AS a
+        JOIN project AS b ON a.project_id=b.id
+        LEFT JOIN user AS c ON a.creator_id=c.id
+        left join sub_project as d on d.id = a.sub_project_id
+        left join task on task.id = a.task_id
+        left join report_extra_degree on report_extra_degree.id = a.degree_id
+        WHERE a.state = 1
+        <if test="startDate != null and startDate != ''">
+            AND a.create_date between #{startDate} and #{endDate}
+        </if>
+        <if test="companyId != null">
+            AND c.company_id = #{companyId}
+        </if>
+        <if test="userId != null">
+            AND b.creator_id = #{userId}
+        </if>
+        ORDER BY a.creator_id, a.create_date desc
+    </select>
+
     <!--根据员工id,日期获取当天全部报告信息-->
     <select id="getReportByDate" resultType="java.util.Map">
         SELECT a.id, a.project_id as projectId,b.project_name AS project, a.working_time AS time, a.content, a.state, a.time_type as timeType, a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,
@@ -327,7 +352,7 @@
     </select>
 
     <select id="getRealProjectTime" resultType="java.util.Map">
-        SELECT project.project_name as project,report.creator_id AS creatorId,sum(working_time) as workingTime, SUM(cost) as cost
+        SELECT project.id as projectId, project.project_code as projectCode, project.project_name as project,report.creator_id AS creatorId,sum(working_time) as workingTime, SUM(cost) as cost
         FROM report
         left join project on project.id = report.project_id
         WHERE report.creator_id IN
@@ -378,4 +403,16 @@
     AND create_date BETWEEN #{startDate} and #{endDate}
     </select>
 
+    <select id="selectFillReportUserList" resultType="java.util.HashMap">
+        select distinct creator_id as creatorId from report
+            where company_id = #{companyId} and create_date between #{startDate} and #{endDate}
+    </select>
+
+    <select id="getMonthReportProjectList" resultType="java.util.HashMap">
+        select distinct project_id as id, project.project_code as projectCode,
+        project.project_name as projectName from report
+        left join project on project.id = report.project_id
+            where report.company_id = #{companyId} and report.create_date between #{startDate} and #{endDate}
+    </select>
+
 </mapper>

+ 3 - 15
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SubProjectMapper.xml

@@ -7,24 +7,12 @@
         <id column="id" property="id" />
         <result column="name" property="name" />
         <result column="project_id" property="projectId" />
+        <result column="company_id" property="companyId" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, name, project_id
+        id, name, project_id, company_id
     </sql>
-    <!--获取某个项目内子项目的工时成本统计-->
-    <select id="getTimeCost" resultType="java.util.Map">
-        SELECT a.id, a.name AS name, SUM(b.working_time) AS cost, SUM(b.working_time * c.cost) AS costMoney
-        FROM sub_project AS a
-        LEFT JOIN report AS b ON b.sub_project_id = a.id
-        JOIN user AS c ON b.creator_id = c.id
-        WHERE a.project_id = #{projectId}
-        <if test="startDate != null and endDate != null">
-            AND b.create_date between #{startDate} and #{endDate}
-        </if>
-        AND b.state = 1
-        GROUP BY a.id
-        ORDER BY a.id ASC
-    </select>
+
 </mapper>

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

@@ -21,11 +21,12 @@
         <result column="alert_msg" property="alertMsg" />
         <result column="sync_corpwx_time" property="syncCorpwxTime" />
         <result column="need_dept_audit" property="needDeptAudit" />
+        <result column="report_workflow" property="reportWorkflow" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        company_id, allday, am, pm, month_days, hour_cost_input_type, type, pay_overtime, alert_time, multi_worktime, fix_monthcost, fill_months, custom_degree_active, custom_degree_name, alert_msg, sync_corpwx_time, need_dept_audit
+        company_id, allday, am, pm, month_days, hour_cost_input_type, type, pay_overtime, alert_time, multi_worktime, fix_monthcost, fill_months, custom_degree_active, custom_degree_name, alert_msg, sync_corpwx_time, need_dept_audit, report_workflow
     </sql>
 
 </mapper>

BIN
fhKeeper/formulahousekeeper/management-platform/员工工时导入模板 (14).xlsx


BIN
fhKeeper/formulahousekeeper/management-platform/项目导入模板.xlsx


+ 10 - 10
fhKeeper/formulahousekeeper/timesheet/config/index.js

@@ -4,19 +4,19 @@ var path = require('path')
 // var ip = '192.168.2.36'
 
  
-var ip = '47.100.37.243' 
+// var ip = '47.100.37.243' 
 // var ip = '192.168.2.136'
 
-// var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
+var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
 
-// for (var i in ifaces) {
-//     for (var j in ifaces[i]) {
-//         var val = ifaces[i][j]
-//         if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
-//             ip = val.address
-//         }
-//     }
-// }
+for (var i in ifaces) {
+    for (var j in ifaces[i]) {
+        var val = ifaces[i][j]
+        if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
+            ip = val.address
+        }
+    }
+}
 
 module.exports = {
   build: {

+ 65 - 16
fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue

@@ -152,9 +152,9 @@
                         {{(scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing).toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column  label="明细"  width="100" align="right">
+                <el-table-column  label="费用明细"  width="100" align="right">
                   <template slot-scope="scope">
-                        <el-link type="primary" :underline="false" @click="showDetail(scope.row)">明细</el-link>
+                        <el-link type="primary" :underline="false" @click="showDetail(scope.row)">报销明细</el-link>
                     </template>
                 </el-table-column>
             </el-table>
@@ -370,36 +370,47 @@
             </div>
         </el-dialog>
 
-        <el-dialog title="项目费用明细" show-summary v-if="detailVisible" :visible.sync="detailVisible" :close-on-click-modal="false" customClass="customWidth" width="800px">
+        <el-dialog :title="curProject.projectName+'-报销费用明细'" show-summary=true v-if="detailVisible" :summary-method="getSummaries" :visible.sync="detailVisible" :close-on-click-modal="false" customClass="customWidth" width="1000px">
         <el-table  :key="ins" border :data="detailList" highlight-current-row v-loading="detailListLoading" :height="500" style="width: 100%;">
-                <el-table-column  prop="username" label="员工姓名"  width="120"></el-table-column>
+                <el-table-column  prop="username" label="员工姓名"  ></el-table-column>
                 <el-table-column  prop="departmentName" label="所在部门" ></el-table-column>
-                <el-table-column  prop="feeType" label="所在部门" ></el-table-column>
-                <el-table-column prop="feeMan" label="人工成本"  width="100"  align="right">
+                <el-table-column  prop="happenDate" label="费用日期" ></el-table-column>
+                <el-table-column prop="invoiceType" label="费用类型"    >
                   <template slot-scope="scope">
-                        {{scope.row.feeMan==null?0:scope.row.feeMan.toFixed(2)}}
+                        {{feeType[scope.row.invoiceType]}}
                     </template>
                 </el-table-column>
-                <el-table-column prop="feeNormal" label="一般费用"  width="100" align="right">
+                <el-table-column prop="expenseType" label="票据类型"  >
+                  
+                </el-table-column>
+                <el-table-column prop="amount" label="金额(含税)"   align="right">
                   <template slot-scope="scope">
-                        {{scope.row.feeNormal==null?0:scope.row.feeNormal.toFixed(2)}}
+                        {{scope.row.amount.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column prop="feeTravel" label="差旅费用"  width="100" align="right">
+                <el-table-column prop="amount" label="税额"   align="right">
                   <template slot-scope="scope">
-                        {{scope.row.feeTravel==null?0:scope.row.feeTravel.toFixed(2)}}
+                        {{scope.row.taxValue == null?'0.00':scope.row.taxValue.toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column prop="feeOutsourcing" label="外包费用"  width="100" align="right">
+                <el-table-column prop="amount" label="金额(不含税)"   align="right">
                   <template slot-scope="scope">
-                        {{scope.row.feeOutsourcing==null?0:scope.row.feeOutsourcing.toFixed(2)}}
+                        {{(scope.row.amount-scope.row.taxValue).toFixed(2)}}
                     </template>
                 </el-table-column>
-                <el-table-column  label="总费用"  width="100" align="right">
+                <!-- <el-table-column prop="pic" label="凭证"  >
                   <template slot-scope="scope">
-                        {{(scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing).toFixed(2)}}
+                        <span v-if="scope.row.pic">
+                        <div class="tups">
+                          <viewer :images="scope.row.pic">
+                            <img ref="imgsa" v-for="src in scope.row.pic" :src="src.url" :key="src.title">
+                        </viewer>
+                        </div>
+                      </span>
+                      <span v-else>-</span>
                     </template>
-                </el-table-column>
+                </el-table-column> -->
+               
             </el-table>
         </el-dialog>
   </section>
@@ -412,6 +423,8 @@ export default {
   props: {},
   data() {
     return {
+      curProject:{},
+      feeType:['一般费用', '差旅费用', '外包费用'],
       detailListLoading: false,
       detailList:[],
       detailVisible: false,
@@ -494,7 +507,43 @@ export default {
       }
   },
   methods: {
+    getSummaries(param) {
+        const { columns, data } = param;
+        const sums = [];
+        columns.forEach((column, index) => {
+          if (index === 0) {
+            sums[index] = '合计';
+            return;
+          }
+          if(index === 5) {
+            const values = data.map(item => Number(item[column.property]));
+            if (!values.every(value => isNaN(value))) {
+              sums[index] = values.reduce((prev, curr) => {
+                const value = Number(curr);
+                if (!isNaN(value)) {
+                  return prev + curr;
+                } else {
+                  return prev;
+                }
+              }, 0);
+              var zhi = +sums[index] + 0
+              var sl = zhi.toFixed(2)
+              sl += ' 元';
+            } else {
+              sums[index] = 'N/A';
+            }
+          } else {
+            sums[index] = 'N/A';
+          }
+          
+        });
+
+        console.log(sums, 123)
+        this.$nextTick(()=>{ this.$refs.tab.doLayout()})
+        return sums;
+      },
     showDetail(row) {
+      this.curProject = row;
       this.detailListLoading = true;
       this.detailVisible = true;
       this.http.post('/expense-item/list', {projectId: row.id},

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/desktop/detail.vue

@@ -198,7 +198,7 @@ export default {
           }
         ]
       };
-      myChart.setOption(option);
+      myChart.setOption(option,{notMerge: true});
     },
 
     getSrcList(index) {

+ 2 - 15
fhKeeper/formulahousekeeper/timesheet/src/views/expense/expense.vue

@@ -21,7 +21,7 @@
               <el-menu-item index="1-2"><p @click="ssl(1)">差旅费用填报</p></el-menu-item>
               <el-menu-item index="1-3"><p @click="ssl(2)">外包费用填报</p></el-menu-item>
           </el-submenu>
-          <el-submenu index="2" v-if="user.role == 1 || user.role == 2 || user.role == 4 || user.role == 6 ">
+          <el-submenu index="2" v-if="user.role == 1 || user.role == 2 || user.role == 4 || user.role == 5 || user.role == 6 ">
             <template slot="title">
               <i class="iconfont firerock-iconbaoxiaodan"></i>
               <span>{{user.role == 0?"我的报销凭证":"报销凭证列表"}}</span>
@@ -34,19 +34,6 @@
               <span slot="title">{{user.role == 0?"我的报销凭证":"报销凭证列表"}}</span>
             </el-menu-item>
           </el-menu>
-           <!-- <el-menu
-          default-active="2"
-          class="el-menu-vertical-demo"
-          @select="bills"
-          background-color="#ffffff"
-          text-color="#666666"
-          active-text-color="#20A0FF"
-          style="width:100%">
-            <el-menu-item index="2" @select="bills">
-              <i class="iconfont firerock-iconbaoxiaodan"></i>
-              <span slot="title">报销凭证列表</span>
-            </el-menu-item>
-          </el-menu> -->
       </el-col>
     </div>
      <!-- 侧边栏点击事件 -->
@@ -369,7 +356,7 @@
                 <span v-else>{{scope.row.expenseType}}</span>
               </template>
             </el-table-column>
-            <el-table-column prop="amount" label="费用金额(元)" width="172">
+            <el-table-column prop="amount" label="费用金额(含税:元)" width="172">
               <template slot-scope="scope">
                 <el-input size="small"  v-if="!flg" :id="'am'+scope.$index" v-model="scope.row.amount" @change="kan" @keyup.native="restrictNumber('am'+scope.$index)"></el-input>
                 <span v-else>¥{{scope.row.amount}}</span>

+ 56 - 108
fhKeeper/formulahousekeeper/timesheet/src/views/project/cost.vue

@@ -31,6 +31,12 @@
         <div :style="'width:'+widthHtval+'px;position: relative; height:'+containerHeight+'px;'">
              <div id="container" :style="'height:'+containerHeight+'px;width:100%'"></div>
         </div>
+        <div style="position:fixed;top:120px;left:500px;" v-show="radio=='部门' && parentDeptId != null">
+            <!-- <el-cascader v-model="departmentId" placeholder="全部一级部门" style="width: 180px;" @change="getList"
+                        :options="option" :props="{ checkStrictly: true }" :show-all-levels="false"></el-cascader> -->
+            
+            <el-button @click="backToParentDept">返回上级</el-button>
+        </div>
         <div style="position:fixed;top:120px;right:150px;"><el-button @click="showExportDialog">报表导出</el-button></div>
 
         <!--导出报表条件选择 -->
@@ -74,6 +80,9 @@
                         </span> 
                     </el-select>
                 </el-form-item>
+                <el-form-item v-if="radio == '项目' || radio == '部门'">
+                    <el-checkbox v-model="exportParam.projectSum" >含单个项目数据汇总</el-checkbox>
+                </el-form-item>
             </el-form>
             <div slot="footer" class="dialog-footer">
                 <el-button type="primary" @click="exportProjectData" style="width:100%;" >导出</el-button>
@@ -87,6 +96,8 @@
     export default {
         data() {
             return {
+                parentDeptStack:[],
+                parentDeptId:null,
                 hasReportUserList:[],
                 projectList:[],
                 exportParam:{projectId:null,dateRange:[],userId: null},
@@ -211,6 +222,11 @@
                         param.userId = this.exportParam.userId;
                     }
                 }
+                if (this.exportParam.projectSum != null) {
+                    if(this.radio == '项目' || this.radio == '部门'){
+                        param.projectSum = this.exportParam.projectSum;
+                    }
+                }
                 this.http.post(url, param,
                     res => {
                         this.listLoading = false;
@@ -405,9 +421,21 @@
                 // },100);
                 // this.jieliu()
             },
+            backToParentDept() {
+                if (this.radio == '部门') {
+                    if (this.parentDeptStack.length > 0) {
+                        this.parentDeptStack.pop();
+                        if (this.parentDeptStack.length > 0) {
+                            this.parentDeptId = this.parentDeptStack[this.parentDeptStack.length -1];
+                        } else {
+                            this.parentDeptId = null;
+                        }
+                        this.jieliu();
+                    }
+                }
+            },
             // 脱离出来的方法
             jieliu() {
-                console.log('触发了')
                 sessionStorage.radio = this.radio;
                 var _this = this;
                 var param = {};
@@ -421,6 +449,7 @@
                     url = this.port.project.listCost;
                 } else if (this.radio=='部门') {
                     url = this.port.project.depCost;
+                    param.parentDeptId = this.parentDeptId;
                 } else if (this.radio=='人员') {
                     this.getUserCostList();
                     return;
@@ -430,22 +459,14 @@
                 this.http.post(url, param,
                 res => {
                     if (res.code == "ok") {
-                        // 测试写的
-                            // var shujuy = res.data.costList
-                            // var arrsa = []
-                            // for(var i=0; i<30; i++) {
-                            //     arrsa.push(shujuy[0])
-                            // }
-                            // console.log(arrsa)
-                            // res.data.costList = arrsa
-                            for(var i in res.data.costList) {
-                                if(i>20) {
-                                    // this.widthHtval = +this.widthHtval + 2
-                                    this.widthHtval = +this.widthHtval + 40
-                                } else {
-                                    this.widthHtval = document.body.clientWidth - 230
-                                }
+                        for(var i in res.data.costList) {
+                            if(i>20) {
+                                // this.widthHtval = +this.widthHtval + 2
+                                this.widthHtval = +this.widthHtval + 40
+                            } else {
+                                this.widthHtval = document.body.clientWidth - 230
                             }
+                        }
                             
                         // 测试写的
                         var xList = []
@@ -468,7 +489,8 @@
                                     yList.push({
                                         "value": list[i].costMoney.toFixed(2) || list[i].costMoney,
                                         "id": list[i].departmentId,
-                                        "cost": list[i].costTime
+                                        "cost": list[i].costTime,
+                                        "hasSubDept": list[i].hasSubDept
                                     });
                                 }
                             }
@@ -485,35 +507,7 @@
                                 });
                             }
                         }
-                        // var xList = [], yList = [], list = res.data.costList, 
-                        // totalMoneyCost = ((this.radio=='项目' || this.radio=='人员')?res.data.totalMoneyCost:res.data.totalCostMoney);
-                        // for(var i in list) {
-                        //     if(this.radio=='项目' || this.radio == '人员') {
-                        //         xList.push(this.radio=='项目'?list[i].project:list[i].name);
-                        //         yList.push({
-                        //             "value": list[i].costMoney.toFixed(2),
-                        //             "id": list[i].id || i,
-                        //             "cost": list[i].cost
-                        //         });
-                        //     } 
-                        //     // else if(this.radio=='研究'){
-                        //     //     xList.push(list[i].name)
-                        //     //     yList.push({
-                        //     //         "value": list[i].costMoney.toFixed(2),
-                        //     //         // "id": list[i].id,
-                        //     //         "id": i,
-                        //     //         "cost": list[i].cost
-                        //     //     })
-                        //     // } 
-                        //     else {
-                        //         xList.push(list[i].departmentName);
-                        //         yList.push({
-                        //             "value": list[i].costMoney.toFixed(2),
-                        //             "id": list[i].departmentId,
-                        //             "cost": list[i].costTime
-                        //         });
-                        //     }
-                        // }
+                        
                         
                         var myChart = echarts.init(document.getElementById("container"));
                         myChart.resize({
@@ -640,62 +634,7 @@
                                 }]
                             };
                         }
-                        // var option = {
-                        //     title: {
-                        //         text: '工时成本总计' + totalMoneyCost.toFixed(2) + '元',
-                        //         left:'left',
-                        //     },
-                        //     // 工具箱
-                        //     toolbox: {
-                        //         show: true,
-                        //         feature:{
-                                   
-                        //             saveAsImage:{
-                        //                 show:true
-                        //             },
-                        //             restore:{
-                        //                 show:true
-                        //             },
-                        //             // dataView:{
-                        //             //     show:true
-                        //             // },
-                        //             // dataZoom:{
-                        //             //     show:true
-                        //             // },
-                        //             magicType:{
-                        //                 type:['line','bar']
-                        //             },
-                                     
-                        //         }
-                        //     },
-                        //     tooltip:{
-                        //         trigger:'axis',
-                        //         formatter: function (params,ticket,callback) {
-                        //             var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.value 
-                        //             + "元 <br/>工作时长"+" : " + params[0].data.cost + "小时";
-                        //             _this.params = params;
-                        //             return res;
-                        //         }
-                        //     },
-                        //     xAxis: {
-                        //         data: xList,
-                        //         axisLabel: {
-                        //             interval:0,rotate:20
-                        //         }
-                        //     },
-                        //     yAxis: [{
-                        //         type : 'value',
-                        //         axisLabel: {
-                        //             formatter:'{value} (元)'
-                        //         }
-                        //     }],
-                        //     series: [{
-                        //         name: '工作成本(元)',
-                        //         type: 'bar',
-                        //         barMaxWidth: 30,
-                        //         data: yList,
-                        //     }]
-                        // };
+                        
                         myChart.setOption(option,{notMerge: true});
                         myChart.getZr().on('click', params => {
                             const pointInPixel = [params.offsetX, params.offsetY];
@@ -714,13 +653,22 @@
                                         _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name);
                                     }
                                 } else if (_this.radio=='部门') {
-                                    if (_this.dateRange != null) {
-                                        _this.$router.push("/costDep/" + _this.params[0].data.id + "/" + _this.params[0].name
-                                            +"?startDate="+_this.dateRange[0]+"&endDate="+_this.dateRange[1]);
+                                    if (_this.params[0].data.hasSubDept) {
+                                        if (_this.parentDeptId != _this.params[0].data.id) {
+                                            _this.parentDeptId = _this.params[0].data.id;
+                                            _this.parentDeptStack.push(_this.parentDeptId);
+                                            console.log('@@@===@@=========');
+                                            _this.jieliu();
+                                        }
+                                        // _this.jieliu();
                                     } else {
-                                        _this.$router.push("/costDep/" + _this.params[0].data.id + "/" + _this.params[0].name);
+                                        if (_this.dateRange != null) {
+                                            _this.$router.push("/costDep/" + _this.params[0].data.id + "/" + _this.params[0].name
+                                                +"?startDate="+_this.dateRange[0]+"&endDate="+_this.dateRange[1]);
+                                        } else {
+                                            _this.$router.push("/costDep/" + _this.params[0].data.id + "/" + _this.params[0].name);
+                                        }
                                     }
-                                    
                                 }
                             }
                         });
@@ -774,7 +722,7 @@
             window.addEventListener("resize", function() {
                 _this.myChart.resize();
             });
-
+            this.getDepartment();
             this.getMyProjectList();
             this.getUsers()
             this.jutishez()

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

@@ -138,7 +138,7 @@
                                 data: yList,
                             }]
                         };
-                        myChart.setOption(option);
+                        myChart.setOption(option,{notMerge: true});
                     } else {
                         this.$message({
                         message: res.msg,

+ 27 - 23
fhKeeper/formulahousekeeper/timesheet/src/views/project/detailDep.vue

@@ -9,7 +9,7 @@
                 <el-form-item class="divLine"></el-form-item>
                 <el-form-item style="width: 500px">
                     <!-- <div class="dipali"> -->
-                        <span class="workName">{{detailName}}</span>
+                        <!-- <span class="workName">{{detailName}}</span> -->
                         <el-cascader v-model="departmentId" placeholder="请选择部门" style="width: 180px;margin-left:10px;" @change="getList"
                         :options="option" :props="{ checkStrictly: true }" :show-all-levels="false"></el-cascader>
                     <!-- </div> -->
@@ -63,12 +63,13 @@
                 res => {
                     if (res.code == "ok") {
                         var list = res.data , array = [];
-                        for(var i in list) {
-                            if(list[i].id == this.detailId) {
-                                array.push(list[i])
-                            }
-                        }
-                        this.option = this.changeArr(array);
+
+                        // for(var i in list) {
+                        //     if(list[i].id == this.detailId) {
+                        //         array.push(list[i])
+                        //     }
+                        // }
+                        this.option = this.changeArr(list);
                     } else {
                         this.$message({
                             message: res.msg,
@@ -103,7 +104,7 @@
                 return arr;
             },
 
-            //获取项目列表
+            //获取部门人员工时统计
             getList() {
                 this.listLoading = true;
                 this.http.post(this.port.project.userCost, {
@@ -118,7 +119,6 @@
                         var xList = [] , yList = [] , list = res.data.list, array = [] , series = [];
                         if (list.length > 0) {
                             this.cost = res.data.totalCostMoney;
-                            var num = list[0].project.length;
                             for(var i in list) {
                                 xList.push(list[i].name);
                                 var pro = list[i].project;
@@ -133,23 +133,21 @@
                                 yList.push(array[i]);
                                 var dataList = [];
                                 for(var j in list) {
-                                    var project = list[j].project , num = 0;
+                                    var curUser = list[j];
+                                    var project = list[j].project;
                                     if(project.length != 0) {
-                                        for(var k in project) {
-                                            if(project[k].project == array[i]) {
-                                                dataList.push({
-                                                    "value": project[k].money,
-                                                    "cost": project[k].time,
+                                        //找到当前用户对应的项目
+                                        var findProject = project.filter(p=>p.project == array[i]);
+                                        if (findProject.length > 0) {
+                                            dataList.push({
+                                                    "value": findProject[0].money,
+                                                    "cost": findProject[0].time,
                                                 })
-                                            } else {
-                                                num++;
-                                            }
-                                            if(k == project.length-1 && num != project.length-1) {
-                                                dataList.push({
+                                        } else {
+                                            dataList.push({
                                                     "value": 0,
                                                     "cost": 0,
                                                 })
-                                            }
                                         }
                                     } else {
                                         dataList.push({
@@ -158,6 +156,7 @@
                                         })
                                     }
                                 }
+
                                 series.push({
                                     name: array[i],
                                     type: 'bar',
@@ -203,7 +202,12 @@
                                 tooltip:{
                                     trigger:'axis',
                                     formatter: function (params,ticket,callback) {
-                                        var res = params[0].name + "<br/>";
+                                        
+                                        var totalTime = 0.0;
+                                        for(var i in params) {
+                                            totalTime += parseFloat(params[i].data.cost)
+                                        }
+                                        var res = params[0].name + " 工时 : " + totalTime.toFixed(1)+"小时<br/>";
                                         for(var i in params) {
                                             if (params[i].data.value > 0) {
                                                 res += "<div style='margin-top:3px;font-size:12px;'><font color='#ddd'>项目名称:" + params[i].seriesName 
@@ -228,7 +232,7 @@
                                 }],
                                 series: series,
                             };
-                            myChart.setOption(option);
+                            myChart.setOption(option, {notMerge: true});
                         } else {
                             this.$message({
                                 message: "暂无数据",

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

@@ -302,7 +302,7 @@
                                 },
                                 
                             ]
-                        })
+                        },{notMerge: true})
                     } else {
                         this.$message({
                             message: res.msg,

+ 346 - 24
fhKeeper/formulahousekeeper/timesheet/src/views/project/finance.vue

@@ -6,6 +6,14 @@
                 <el-form-item label="财务核算成本 | 月份选择" style="margin-top:5px;">
                 <el-date-picker size="small" v-model="date" :editable="false" format="yyyy-MM" value-format="yyyy-MM" @change="changeMonth" :clearable="false" type="month" placeholder="选择月份"></el-date-picker>
             </el-form-item>
+            <el-radio-group v-model="radio" @change="switchList" style="margin-left:160px;margin-top:5px;">
+                <el-radio-button label="全部人员" >全部人员({{allFinanceList.length}})</el-radio-button>
+                <el-radio-button label="无项目工时人员">无项目工时人员({{noReportUserList.length}})</el-radio-button>
+            </el-radio-group>
+            <el-form-item v-if="user.role == 1 || user.role == 2 || user.role == 4" style="margin-left:5px;margin-top:5px;">
+                <el-link type="primary" :underline="false" @click="showSettingDialog()" >分摊比例设置</el-link>
+            </el-form-item>
+
             <el-form-item style="float:right;" v-if="user.role == 1 || user.role == 2 || user.role == 4">
                 <el-link type="primary" :underline="false" @click="getTemplate()" >财务模板下载</el-link>
             </el-form-item>
@@ -22,6 +30,7 @@
             </el-form-item>
             </el-form>
         </el-col>
+
         <!--列表-->
         <el-table :data="list" highlight-current-row v-loading="listLoading" 
         show-summary=true
@@ -47,17 +56,23 @@
         
         <el-form :inline="true" >
             <el-form-item >
-                <el-checkbox style="margin-left:10px;" v-model="assignNoProUser" @click="assignToProject">均摊无项目人员成本</el-checkbox>
-                <el-button type="primary" :underline="false" size="small" @click="assignToProject" style="margin-left:10px;">查看项目成本分配</el-button>
+                <!-- <el-checkbox style="margin-left:10px;" v-model="assignNoProUser" @click="assignToProject">均摊无项目人员成本</el-checkbox> -->
+                <!-- <el-button type="primary" :underline="false" size="small" @click="assignNoProUser=false;assignToProject();" style="margin-left:10px;">分摊已填工时人员成本</el-button>
+                <el-button type="primary" :underline="false" size="small" @click="assignNoProUser=true;assignToProject();" style="margin-left:10px;">分摊全部人员成本</el-button> -->
+                <el-radio-group v-model="costListRadio" @change="switchCostList" style="margin-left:5px;margin-top:5px;">
+                    <el-radio-button label="1" >分摊已填工时人员成本</el-radio-button>
+                    <el-radio-button label="2">分摊全部人员成本</el-radio-button>
+                </el-radio-group>
+
             </el-form-item>
 
             <el-form-item style="float:right;">
-                <el-link type="primary" :underline="false" @click="exportData">导出项目成本数据</el-link>
+                <el-link type="primary" :underline="false" @click="exportData">导出成本数据</el-link>
             </el-form-item>
             
-            <el-form-item style="float:right;margin-right:30px;" v-if="hasNoProjectUsers">
+            <!-- <el-form-item style="float:right;margin-right:30px;" v-if="hasNoProjectUsers">
                 <el-link type="primary" :underline="false" @click="showNoProjectUsers">查看无项目数据</el-link>
-            </el-form-item>
+            </el-form-item> -->
         </el-form>
         <div id="container" style="height:300px"></div>
         <!--新增界面-->
@@ -119,7 +134,7 @@
         </el-dialog>
 
         <!--无项目人员列表-->
-        <el-dialog title="无项目人员列表" v-if="showNPDialog" :visible.sync="showNPDialog" :close-on-click-modal="false" customClass="customWidth" width="1200px">
+        <!-- <el-dialog title="无项目人员列表" v-if="showNPDialog" :visible.sync="showNPDialog" :close-on-click-modal="false" customClass="customWidth" width="1200px">
             <el-table :data="npUserList" highlight-current-row v-loading="listLoading" 
             show-summary=true
             ref="table"
@@ -133,7 +148,7 @@
             <el-table-column prop="insuranceLosejob" label="失业保险" ></el-table-column>
             <el-table-column prop="insuranceInjury" label="工伤保险" ></el-table-column>
             <el-table-column prop="houseFund" label="住房公积金" ></el-table-column>
-            <!-- <el-table-column prop="others" label="其他" ></el-table-column> -->
+             <el-table-column prop="others" label="其他" ></el-table-column> 
             <el-table-column :label="item.fieldName" v-for="(item, index) in customCols" :key="item.id" :prop="index==0?'customField1':(index==1?'customField2':(index==2?'customField3':''))">
                 <template slot-scope="scope">
                     {{index==0?scope.row.customField1:(index==1?scope.row.customField2:(index==2?scope.row.customField3:''))}}
@@ -145,7 +160,7 @@
                 <div style="float:left;color:#ff9900;">*以上人员当月尚无投入的项目,请提醒他们填写日报。</div>
                 <el-button type="primary" @click="showNPDialog = false" >关闭</el-button>
             </div>
-        </el-dialog>
+        </el-dialog> -->
 
         <el-dialog title="自定义薪资项" show-header="false" v-if="itemDialog" :visible.sync="itemDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
             <div style="margin-left:30px;">
@@ -167,6 +182,77 @@
                 <el-button type="primary" @click="saveItems()" >保存</el-button>
             </div>
         </el-dialog>
+
+        <el-dialog :title="date+'月 无项目工时人员分摊比例设置'" show-header="false" v-if="settingDialog" :visible.sync="settingDialog" 
+        :close-on-click-modal="false" customClass="customWidth" width="1200px">
+            <div>
+                <div>
+                    <el-button :disabled="multipleSelection.length==0" @click="setPercent(true, null)">批量设置比例</el-button>
+                    <el-button :disabled="projectCols.length==0 || userCostSettingList.length == 0" @click="getLastMonthSetting">使用上月比例设置</el-button>
+                    <el-button @click="showSelectProjectDialog">管理待分摊项目</el-button>
+                </div>
+                <el-table :data="userCostSettingList" highlight-current-row v-loading="costSettingLoading" 
+                     ref="settingTable"  @selection-change="handleSelectionChange" 
+                    :height="400" style="width: 100%;">
+                    <el-table-column type="selection" width="55"></el-table-column>
+                    <el-table-column prop="name" label="姓名" sortable width="90" fixed="left"></el-table-column>
+                    
+                    <el-table-column :label="item.projectName" v-for="(item) in projectCols" width="180" size="small"
+                        :key="item.id" align="center">
+                        <template slot-scope="scope">
+                            <span>{{scope.row[item.projectId]}}</span>%
+                        </template>
+                    </el-table-column>
+                    <el-table-column label="设置比例"  width="80" fixed="right">
+                        <template slot-scope="scope">
+                            <el-button size="small" @click="setPercent(false,scope.row)">设置</el-button>
+                        </template>
+                    </el-table-column>
+                </el-table>
+            </div>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="settingDialog = false" >关闭</el-button>
+                <el-button type="primary" @click="saveMonthSetting()" >保存</el-button>
+            </div>
+        </el-dialog>
+
+        <el-dialog title="待分摊项目选择" show-header="false" v-if="projectsDialog" :visible.sync="projectsDialog" 
+            :close-on-click-modal="false" customClass="customWidth" width="1000px">
+            <el-select v-model="chosenProjects" multiple filterable clearable style="width:100%">
+                <el-option v-for="item in allProjectList" :label="item.projectName" :key="item.id" :value="item.id"></el-option>
+            </el-select>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="default" @click="projectsDialog = false" >关闭</el-button>
+                <el-button type="primary" @click="saveProjectSetting()" >确定</el-button>
+            </div>
+        </el-dialog>
+        <el-dialog title="设置员工成本各项目占比" show-header="false" v-if="setPercentDialog" :visible.sync="setPercentDialog" 
+            :close-on-click-modal="false" customClass="customWidth" width="600px" >
+            <div style="margin:0px 10px 10px 10px;">
+                <span>选择员工</span>
+                <el-select v-model="chosenNoReportUserIds" multiple filterable clearable style="width:330px;" collapse-tags>
+                        <el-option v-for="item in noReportUserList" :label="item.name" :key="item.id" :value="item.userId"></el-option>
+                    </el-select>
+                    <el-button @click="averageCost" >自动分摊</el-button>
+            </div>
+            <el-divider ></el-divider>
+            <!--项目列表 -->
+            <el-form v-model="curPercentVal" label-width="365px" style="margin-top:10px;">
+                <div class="nameList">
+                    <el-form-item v-for="item in projectCols" :label="item.projectName" :key="item.projectId" >
+                        占比: <el-input v-model="curPercentVal[item.projectId]" style="width:100px;" @input="updatePercentValue"></el-input>&nbsp;%
+                    </el-form-item>
+                </div>
+                <el-form-item >
+                    总比例: {{totalPercent}}&nbsp;%
+                </el-form-item>
+            </el-form>
+            
+            <div slot="footer" class="dialog-footer">
+                <el-button type="default" @click="setPercentDialog = false" >关闭</el-button>
+                <el-button type="primary" @click="setPercentSetting()" >确定</el-button>
+            </div>
+        </el-dialog>
     </section>
 </template>
 <style scoped>
@@ -186,11 +272,26 @@
     export default {
         data() {
             return {
+                costListRadio: 0,
+                costSettingLoading: false,
+                chosenNoReportUserIds:[],
+                curPercentVal:{},
+                setPercentDialog: false,
+                chosenProjects:[],
+                projectsDialog: false,
+                projectCols:[],
+                allProjectList:[],
+                multipleSelection:[],
+                userCostSettingList: [],
+                settingDialog: false,
+                radio:"全部人员",
+                noReportUserList:[],
+                allFinanceList:[],
                 assignNoProUser: false,
                 customFieldList:{field1:null, field2: null, field3: null},
                 itemDialog: false,
                 customCols:[],
-                showNPDialog: false,
+                // showNPDialog: false,
                 npUserList:[],
                 hasNoProjectUsers: false,
                 isUploading:false,
@@ -208,9 +309,217 @@
                 
                 myChart: null,
                 params: null,
+                totalPercent:0,
             };
         },
         methods: {
+            switchCostList() {
+                //已填日报的人员成本
+                if (this.costListRadio == 1) {
+                    this.assignNoProUser=false;
+                    this.assignToProject();
+                } else if (this.costListRadio == 2) {
+                    //全部人员成本
+                    this.assignNoProUser=true;
+                    this.assignToProject();
+                }
+            },
+            getLastMonthSetting() {
+                this.costSettingLoading = true;
+                var dataArr = this.date.split('-');
+                var year = dataArr[0];
+                var month = dataArr[1];
+                if (parseInt(month) == 1) {
+                    year = parseInt(year) -1;
+                    month = 12;
+                } else {
+                    month = parseInt(month) -1;
+                    if (month < 10) {
+                        month = '0'+month;
+                    }
+                }
+                var lastMonth = year + '-' + month;
+                this.http.post('/project-percentage/getMonthSetting', {ymonth: lastMonth},
+                    res => {
+                        this.costSettingLoading = false;
+                        if (res.code == "ok") {
+                            this.projectCols = res.data.financeProjects;
+                            this.allProjectList = res.data.allProjectList;
+                            this.userCostSettingList = res.data.userCostSetting;
+                            //上次如果没有配置过,需要初始化
+                            for (var i=0;i<this.noReportUserList.length; i++) {
+                                var rUser = this.noReportUserList[i];
+                                //检查当前列表中的无项目人员是否在之前的里面存在,如果不在需要加上去
+                                if (this.userCostSettingList.filter(c=>c.id == rUser.userId).length == 0) {
+                                    var item = {name: rUser.name, id: rUser.userId};
+                                    this.projectCols.forEach(p=>{
+                                        item[p.projectId] = 0;
+                                    });
+                                    this.userCostSettingList.push(item);
+                                }
+                            }
+                            this.$nextTick(()=>{
+                                this.$refs.settingTable.doLayout();
+                            })
+                        } });
+            },
+            //获取当月的无项目工时人员的分配比例设置
+            getMonthSetting() {
+                this.costSettingLoading = true;
+                this.http.post('/project-percentage/getMonthSetting', {ymonth: this.date},
+                    res => {
+                        this.costSettingLoading = false;
+                        if (res.code == "ok") {
+                            this.projectCols = res.data.financeProjects;
+                            this.allProjectList = res.data.allProjectList;
+                            this.userCostSettingList = res.data.userCostSetting;
+                            //上次如果没有配置过,需要初始化
+                            for (var i=0;i<this.noReportUserList.length; i++) {
+                                var rUser = this.noReportUserList[i];
+                                console.log('userId====='+rUser.userId);
+                                //检查当前列表中的无项目人员是否在之前的里面存在,如果不在需要加上去
+                                if (this.userCostSettingList.filter(c=>c.id == rUser.userId).length == 0) {
+                                    var item = {name: rUser.name, id: rUser.userId};
+                                    this.projectCols.forEach(p=>{
+                                        item[p.projectId] = 0;
+                                    });
+                                    this.userCostSettingList.push(item);
+                                }
+                            }
+                        } });
+            },
+            //提交无工时人员的分配设置
+            saveMonthSetting() {
+                //检查数据是否都分配到100%了,防止由于修改了项目列而导致之前的数据不正确的情况
+                var errorList = this.userCostSettingList.filter(u=>{
+                    let totalPercent = 0.0;
+                    this.projectCols.forEach(p=>{
+                        totalPercent += parseFloat(u[p.projectId]);
+                    });
+                    totalPercent = totalPercent.toFixed(1);
+                    if (totalPercent != 100) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                });
+                if (errorList.length > 0) {
+                    var nameList = errorList.map(e=>e.name);
+                    this.$message({type:'error', message:'存在人员分配比例非100%: '+nameList});
+                    return;
+                }
+                this.http.post('/project-percentage/saveMonthSetting', {projectCols: JSON.stringify(this.projectCols),
+                            ymonth: this.date, userSettings: JSON.stringify(this.userCostSettingList)},
+                    res => {
+                        if (res.code == "ok") {
+                            this.$message({type:'success', message:'保存成功'});
+                            this.settingDialog = false;
+                        } else {
+                            this.$message({type:'error', message:'发生错误:'+res.msg});
+                        }});
+            },
+            updatePercentValue() {
+                var total = 0.0;
+                this.projectCols.forEach(p=>{
+                    total += parseFloat(this.curPercentVal[p.projectId]);
+                })
+                this.totalPercent = total.toFixed(1);
+                this.$forceUpdate();
+            },
+            averageCost() {
+                var avg = (100/this.projectCols.length).toFixed(1);
+                //最后一个用100减去前面的总和,保证最终合计为100
+                for (var i=0;i<this.projectCols.length; i++) {
+                    if (i < this.projectCols.length -1) {
+                        this.curPercentVal[this.projectCols[i].projectId] = avg;
+                    } else {
+                        this.curPercentVal[this.projectCols[i].projectId] = (100-avg*(this.projectCols.length-1)).toFixed(1);
+                    }
+                }
+                this.updatePercentValue();
+                this.$forceUpdate();
+            },
+            setPercent(isBatch, row) {
+                this.setPercentDialog = true;
+                this.chosenNoReportUserIds = [];
+                if (!isBatch) {
+                    this.chosenNoReportUserIds.push(row.id);
+                    //获取当前比例
+                    this.projectCols.forEach(p=>{
+                        this.curPercentVal[p.projectId] = row[p.projectId];
+                    });
+                } else {
+                    //批量处理
+                    this.multipleSelection.forEach(m=>{
+                        this.chosenNoReportUserIds.push(m.id);
+                    })
+                    //批量时获取第一条的比例进行加载
+                    this.projectCols.forEach(p=>{
+                        this.curPercentVal[p.projectId] = this.multipleSelection[0][p.projectId];
+                    });
+                }
+                this.updatePercentValue();
+            },
+            //确认设置的项目列
+            saveProjectSetting() {
+                this.projectsDialog = false;
+                this.projectCols = [];
+                this.chosenProjects.forEach(c=>{
+                    var item = this.allProjectList.filter(a=>a.id == c)[0];
+                    this.projectCols.push({projectId: item.id, projectName: item.projectName, projectCode: item.projectCode});
+                });
+                
+                this.$nextTick(()=>{
+                    this.$refs.settingTable.doLayout();
+                })
+            },
+            handleProjectSelectionChange(val) {
+                this.projectSelection = val;
+            },
+            showSelectProjectDialog() {
+                //设置选中状态
+                this.chosenProjects = [];
+                this.projectCols.forEach(item=>{
+                    this.chosenProjects.push(item.projectId);
+                })
+                this.projectsDialog = true;
+            },
+            setPercentSetting() {
+                //检测是否填写的情况下,是否达到100%
+                if (this.totalPercent != 100) {
+                    this.$message({
+                            message: '分配比例之和必须是100%',
+                            type: "error"
+                            });
+                    return;
+                }
+
+                this.setPercentDialog = false;
+                this.chosenNoReportUserIds.forEach(u=>{
+                    var targetU = this.userCostSettingList.filter(a=>a.id == u)[0];
+                    
+                    //遍历项目
+                    this.projectCols.forEach(p=>{
+                        targetU[p.projectId] = this.curPercentVal[p.projectId];
+                    })
+                });
+                this.userCostSettingList.splice(1,0);
+                
+            },
+            showSettingDialog() {
+                this.settingDialog = true;
+                this.getMonthSetting();
+            },
+            handleSelectionChange(val) {
+                this.multipleSelection = val;
+            },
+            switchList() {
+                if (this.radio == '全部人员') {
+                    this.list = this.allFinanceList;
+                } else {
+                    this.list = this.noReportUserList;
+                }
+            },
             downloadByA(row) {
                 const a = document.createElement('a'); // 创建a标签
                 a.setAttribute('download', row.name);// download属性
@@ -262,14 +571,23 @@
                             this.customCols = res.data;
                         }});
             },
-            showNoProjectUsers() {
-                this.showNPDialog = true;
-                this.http.post('/finance/getNoProjectUsers', {yearMonth: this.date},
-                res => {
-                    if (res.code == "ok") {
-                        this.npUserList = res.data;
-                    }});
-            },
+            // getProjects() {
+            //     this.http.post('/finance/getProjects', {companyId: this.user.companyId, yearMonth: this.date},
+            //         res => {
+            //             if (res.code == "ok") {
+            //                 this.projectCols = res.data.financeProjects;
+            //                 this.allProjectList = res.data.allProjectList;
+            //             }});
+                
+            // },
+            // showNoProjectUsers() {
+            //     this.showNPDialog = true;
+            //     this.http.post('/finance/getNoProjectUsers', {yearMonth: this.date},
+            //     res => {
+            //         if (res.code == "ok") {
+            //             this.npUserList = res.data;
+            //         }});
+            // },
             assignToProject(){
                 var _this = this;
                 this.http.post('/finance/getTimeCost', {yearMonth: this.date, assignNoProUser: this.assignNoProUser},
@@ -301,10 +619,8 @@
                         var option = {
                             title: {
                                 text: this.assignNoProUser?'成本总计 ' + totalMoneyCost + '元'
-                                    +(this.hasNoProjectUsers?",含无项目人员成本总计 " + nopCost+"元 ":"")
-                                    :'项目成本总计 ' + totalMoneyCost + '元'
-                                    +(this.hasNoProjectUsers?",无项目人员成本总计 " + nopCost+"元, 共: "+(totalMoneyCost+nopCost)+"元":"")
-                                    ,
+                                    +(this.hasNoProjectUsers?",含无项目人员成本 " + nopCost+"元 ":"")
+                                    :'成本总计 ' + totalMoneyCost + '元',
                                 left:'left',
                             },
                             // 工具箱
@@ -351,7 +667,7 @@
                                 data: yList,
                             }]
                         };
-                        option && myChart.setOption(option);
+                        option && myChart.setOption(option,{notMerge: true});
                         // myChart.getZr().on('click', params => {
                         //     const pointInPixel = [params.offsetX, params.offsetY];
                         //     if (myChart.containPixel('grid', pointInPixel)) {
@@ -449,7 +765,6 @@
                     let formData = new FormData();
                     formData.append("file", item.file);
                     formData.append("companyId", this.user.companyId);
-                    console.log('date====='+this.date);
                     formData.append("yearMonth", this.date);
                     formData.append("syncUserCost", this.importParam.syncUserCost);
                     formData.append("syncHistoryReport", this.importParam.syncHistoryReport);
@@ -497,7 +812,9 @@
                     this.listLoading = false;
                     if (res.code == "ok") {
                         var list = res.data;
-                        this.list = list;
+                        this.allFinanceList = list;
+                        this.list = this.allFinanceList;
+                        this.noReportUserList = list.filter(r=>r.hasReport == 0);
                     } else {
                         this.$message({
                         message: res.msg,
@@ -530,6 +847,7 @@
             };
             this.getList();
             this.getCustomColumn();
+            // this.getProjects();
         },
         updated() {
             this.$nextTick(() => {
@@ -540,4 +858,8 @@
 </script>
 
 <style lang="scss" scoped>
+.nameList {
+    height: 400px;
+    overflow: auto;
+}
 </style>

+ 4 - 4
fhKeeper/formulahousekeeper/timesheet/src/views/project/summary.vue

@@ -243,7 +243,7 @@
                                     data: xList2
                                 }]
                         };
-                        myChart.setOption(option);
+                        myChart.setOption(option,{notMerge: true});
                     } else {
                         this.$message({
                             message: res.msg,
@@ -328,7 +328,7 @@
                                 data: yList,
                             }]
                         };
-                        myChart.setOption(option);
+                        myChart.setOption(option,{notMerge: true});
                     } else {
                         this.$message({
                             message: res.msg,
@@ -383,7 +383,7 @@
                                     data:list
                                 }
                             ]
-                        })
+                        },{notMerge: true})
                     } else {
                         this.$message({
                             message: res.msg,
@@ -468,7 +468,7 @@
                                 data: yList,
                             }]
                         };
-                        myChart.setOption(option);
+                        myChart.setOption(option,{notMerge: true});
                     } else {
                         this.$message({
                             message: res.msg,

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/simplereport/list.vue

@@ -227,7 +227,7 @@
                                 data: yList,
                             }]
                         };
-                        myChart.setOption(option);
+                        myChart.setOption(option,{notMerge: true});
                     } else {
                         this.$message({
                             message: res.msg,

+ 28 - 21
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -77,7 +77,7 @@
                             
                             <!-- <el-link type="primary" style="margin-right:10px;" :underline="false" @click="isSubstitude=true; fillInReport(-1,1)">批量代填</el-link> -->
                             <el-link type="primary" style="margin-right:10px;" :underline="false" @click="showExportDialog">导出日报</el-link>
-                            <el-link type="primary" style="margin-right:10px;" :underline="false" @click="batchApprove" >批量审核</el-link>
+                            <!-- <el-link type="primary" style="margin-right:10px;" :underline="false" @click="batchApprove" >批量审核</el-link> -->
                         </span>
                     </div>
                     <!--普通员工,含项目经理 -->
@@ -88,7 +88,7 @@
                             <el-link type="primary" v-if="user.leader" style="margin-right:10px;" :underline="false" @click="isSubstitude=true; fillInReport(-1,0)">代填日报</el-link>
                             <el-link type="primary" style="margin-right:10px;" :underline="false" @click="isSubstitude=false;fillInReport(-1,1)">批量填报</el-link>
                             <!-- <el-link type="primary" v-if="user.leader" style="margin-right:10px;" :underline="false" @click="isSubstitude=true; fillInReport(-1,1)">批量代填</el-link> -->
-                            <el-link type="primary" v-if="user.leader" style="margin-right:10px;" :underline="false" @click="batchApprove">批量审核</el-link>
+                            <!-- <el-link type="primary" v-if="user.leader" style="margin-right:10px;" :underline="false" @click="batchApprove">批量审核</el-link> -->
                     </span>
                     </div>
                     <div :style="'height:'+(tableHeight-50)+'px;overflow:scroll;padding-top:10px;'">
@@ -104,15 +104,9 @@
                                     <span >{{item1.cost}}</span>元</span>
                                 </span>
                             </span>
-                            <div class="checkbtn">
-                                <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item1.data[0].inchargerId) && (item1.state == 0 || item1.state == -1)" type="primary" :loading="logining" size="small" @click="approve(item1.id, item1)">通过</el-button>
-                                <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item1.data[0].inchargerId) && (item1.state == 0 || item1.state == -1)" type="danger" :loading="logining" size="small" @click="showDenyDialog(item1.id,0, item1)">驳回</el-button>
-                                <!--自己可以撤回待审核状态的报告 -->
-                                <el-button v-if="user.id == item1.id && (item1.state == 0 || item1.state == -1)" type="normal" :loading="logining" size="small" @click="cancel(item1)">撤回</el-button>
-                                <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item1.data[0].inchargerId) && item1.state == 1" type="normal" :loading="logining" size="small" @click="showDenyDialog(item1.id,1, item1)">撤销</el-button>
+                            <div class="checkbtn" style="padding-right:20px;">
                                 <el-button v-if="item1.state >= 2 && user.id == item1.id" type="primary" size="small" @click="isSubstitude=false; fillInReport(index1,0)">编辑日报</el-button>
                                 <el-button v-if="(user.role == 1 || user.role == 2 || user.manageDeptId != 0) && item1.state != 1" size="small" @click="guanli(item1)" style="float: right;">删除</el-button>
-                                
                             </div>
                             <div class="one_daily_body">
                                 <el-timeline>
@@ -121,7 +115,7 @@
                                             <p>项目:<b>{{item2.project}}</b><span v-if="item2.subProjectName != null"> / {{item2.subProjectName}}</span>
                                             
                                             <span v-if="user.company.packageEngineering == 0">
-                                            <span style="margin-left:15px;color:#DAA520;"  v-if="item2.state == 0 || item2.state == -1">[ 
+                                            <span style="margin-left:15px;color:#DAA520;"  v-if="item2.state == 0">[ 
                                                 <span v-if="item2.isDeptAudit==0">
                                                     <span v-if="item2.projectAuditState==0">
                                                         待项目负责人审核
@@ -135,13 +129,14 @@
                                                     {{('待'+item2.auditDeptName+'审核')}}
                                                 </span>
                                                  ]</span>
+                                            <span style="margin-left:15px;color:#DAA520;" v-else-if="item2.state == -1">[ 导入待审核 ]</span>
                                             <span style="margin-left:15px;color:#32CD32;" v-else-if="item2.state == 1">[ 已通过 ]</span>
                                             <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 2">[ 已驳回 ] 原因:{{item2.rejectReason}}</span>
                                             <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 3">[ 待提交 ]</span>
                                             </span>
                                             <!-- <el-button v-if="(user.role == 1 || user.role == 2) && item2.state != 1 && user.manageDeptId != 0" size="mini" @click="guanli(item2, item1)" style="float: right;">删除</el-button> -->
                                             <span v-if="user.company.packageEngineering == 1">
-                                                <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == -1">[ 待审核 ]</span>
+                                                <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == -1">[ 导入待审核 ]</span>
                                                 <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == 0 && item2.departmentAuditState == -1">[ 待专业审核 ]</span>
                                                 <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == 0 && item2.departmentAuditState == 0">[ 待部门审核 ]</span>
                                                 <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == 0 && item2.departmentAuditState == 1">[ 待项目经理审核 ]</span>
@@ -149,6 +144,18 @@
                                                 <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 2">[ 已驳回 ] 原因:{{item2.rejectReason}}</span>
                                                 <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 3">[ 待提交 ]</span>
                                             </span>
+
+                                            <!--每个项目上单独审核 -->
+                                            <span style="float:right;">
+                                                <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item2.inchargerId) && item2.state == 0 && item2.isDeptAudit==0 && item2.projectAuditState==0" type="primary" :loading="logining" 
+                                                size="small" @click="approve(item1.id, item2)">通过</el-button>
+                                                <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item2.inchargerId) && item2.state == 0 && item2.isDeptAudit==0 && item2.projectAuditState==0" type="danger" :loading="logining" 
+                                                size="small" @click="showDenyDialog(item1.id,0, item2)">驳回</el-button>
+                                                <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item2.inchargerId) && item2.state == 1" type="normal" :loading="logining" size="small" 
+                                                @click="showDenyDialog(item1.id,1, item2)">撤销</el-button>
+                                                <!--自己可以撤回待审核状态的报告 -->
+                                                <el-button v-if="user.id == item1.id && (item2.state == 0 || item2.state == -1)" type="normal" :loading="logining" size="small" @click="cancel(item1)">撤回</el-button>
+                                            </span>
                                             </p>
                                             <p v-if="user.timeType.customDegreeActive==1 && item2.degree_id != null">{{user.timeType.customDegreeName}}:{{item2.degreeName}}</p>
                                             <p v-if="user.company.packageEngineering == 1">
@@ -3487,11 +3494,11 @@
                 this.logining = true;
                 let day = (this.choseDay + 1) > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
 
-                var ids = '';
-                var data = item.data;
-                data.forEach(element => {
-                    ids +=(element.id+',');
-                });
+                var ids = item.id;
+                // var data = item.data;
+                // data.forEach(element => {
+                //     ids +=(element.id+',');
+                // });
                 this.http.post( this.port.report.approve, {id: id , date: this.date +day, reportIds: ids},
                 res => {
                     this.logining = false;
@@ -3555,11 +3562,11 @@
             showDenyDialog(id,i, item) {
                 this.denyReasonDialog = true;
                 let day = (this.choseDay+1) > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
-                var ids = '';
-                var data = item.data;
-                data.forEach(element => {
-                    ids +=(element.id+',');
-                });
+                var ids = item.id;
+                // var data = item.data;
+                // data.forEach(element => {
+                //     ids +=(element.id+',');
+                // });
                 this.denyForm = {id: id ,i:i, date: this.date +day, reportIds: ids, reason:null};
             },
             // 未通过日报

+ 28 - 7
fhKeeper/formulahousekeeper/timesheet/src/views/workflow/report.vue

@@ -219,8 +219,8 @@
             },
 
             deleteNode() {
-              this.dialogVisible = false;
-              this.dataArray.splice(this.index, 1);
+                this.dialogVisible = false;
+                this.dataArray.splice(this.index, 1);
             },
 
             addNode() {
@@ -239,11 +239,32 @@
               }
             },
             editNodeDialog(index, item) {
-                this.isAdd = false;
-                this.index = index;
-                this.curUserId = item.userId;
-                this.dialogVisible = true;
-                this.curDeptId = item.auditDeptId;
+                //检查是否可编辑
+                this.http.post('/audit-workflow-time-setting/checkNodeInUse',{auditDeptId: item.auditDeptId, deptId: this.depData.id},
+                    res => {
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            this.isAdd = false;
+                            this.index = index;
+                            this.curUserId = item.userId;
+                            this.dialogVisible = true;
+                            this.curDeptId = item.auditDeptId;
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+                
             },
             showNodeDialog(index) {
               this.isAdd = true;

+ 10 - 10
fhKeeper/formulahousekeeper/timesheet_h5/vue.config.js

@@ -5,16 +5,16 @@ const themePath = path.resolve(__dirname,'src/assets/style/theme.less');
 
 // var ip = '127.0.0.1'
 // var ip = '192.168.2.105'
-var ip = '47.100.37.243'
-// var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
-// for (var i in ifaces) {
-//     for (var j in ifaces[i]) {
-//         var val = ifaces[i][j]
-//         if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
-//             ip = val.address
-//         }
-//     }
-// }
+// var ip = '47.100.37.243'
+var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
+for (var i in ifaces) {
+    for (var j in ifaces[i]) {
+        var val = ifaces[i][j]
+        if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
+            ip = val.address
+        }
+    }
+}
 
 module.exports = {
     // 关闭eslint检查