seyason 3 gadi atpakaļ
vecāks
revīzija
7932234f62
38 mainītis faili ar 912 papildinājumiem un 319 dzēšanām
  1. 0 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/config/RefererInterceptor.java
  2. 11 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java
  3. 43 19
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  4. 25 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/StagesController.java
  5. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java
  6. 21 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskGroupController.java
  7. 6 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Project.java
  8. 14 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Report.java
  9. 8 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TaskGroup.java
  10. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ReportVO.java
  11. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectMapper.java
  12. 1 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  13. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/TaskGroupMapper.java
  14. 4 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java
  15. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/TaskGroupService.java
  16. 0 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceServiceImpl.java
  17. 112 7
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  18. 22 15
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  19. 14 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TaskGroupServiceImpl.java
  20. 27 10
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml
  21. 23 12
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  22. 14 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SubProjectMapper.xml
  23. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TaskGroupMapper.xml
  24. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TaskMapper.xml
  25. 10 10
      fhKeeper/formulahousekeeper/timesheet/config/index.js
  26. 63 69
      fhKeeper/formulahousekeeper/timesheet/src/views/project/cost.vue
  27. 7 5
      fhKeeper/formulahousekeeper/timesheet/src/views/project/detail.vue
  28. 7 3
      fhKeeper/formulahousekeeper/timesheet/src/views/project/detailDep.vue
  29. 89 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue
  30. 47 2
      fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue
  31. 136 87
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  32. 1 0
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/audit/audit.vue
  33. 136 28
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue
  34. 7 2
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/review/department_list.vue
  35. 7 2
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/review/index.vue
  36. 7 2
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/review/profession_list.vue
  37. 7 3
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue
  38. 10 10
      fhKeeper/formulahousekeeper/timesheet_h5/vue.config.js

+ 0 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/config/RefererInterceptor.java

@@ -35,14 +35,12 @@ public class RefererInterceptor extends HandlerInterceptorAdapter {
             String[] split = excludeUrls.split(",");
             boolean isPass = false;
             for (String pattern: split) {
-//                System.out.println(""+pattern+", "+reqUrl);
                 if (matcher.match(pattern, reqUrl)) {
                     isPass = true;
                     break;
                 }
             }
             if (isPass) {
-                System.out.println("开放请求,不检查Referer");
                 return true;
             }
         }
@@ -70,9 +68,7 @@ public class RefererInterceptor extends HandlerInterceptorAdapter {
             // 首先判断请求域名和referer域名是否相同
             if (!isSame) {
                 // 如果不等,判断是否在白名单中
-                LOGGER.info("properties.getRefererDomain()=="+properties.getRefererDomain());
                 if (properties.getRefererDomain() != null) {
-                    LOGGER.info("request from Host="+url.getHost()+", REF="+url.getRef());
                     for (String s : properties.getRefererDomain()) {
                         if (s.equals(url.getHost())) {
                             return true;

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

@@ -73,11 +73,12 @@ public class ProjectController {
                                    String projectBaseCostData,
                                    String chosenLeaders,
                                    String associateDegrees,
-                                   String associateDegreeNames
+                                   String associateDegreeNames,
+                                   Integer taskGpIncharge
                                    ) {
         return projectService.editProject(id, name, code, userId, inchargerId, isPublic, planStartDate, planEndDate, level, contractAmount,
                 projectBaseCostData,
-                 budget,customerId,chosenLeaders, associateDegrees, associateDegreeNames, request);
+                 budget,customerId,chosenLeaders, associateDegrees, associateDegreeNames, taskGpIncharge, request);
     }
 
     @RequestMapping("/adjustBase")
@@ -113,8 +114,8 @@ public class ProjectController {
      * id 要删除的项目的id
      */
     @RequestMapping("/deleteProject")
-    public HttpRespMsg deleteProject(@RequestParam Integer id) {
-        return projectService.deleteProject(id);
+    public HttpRespMsg deleteProject(@RequestParam Integer id, @RequestParam(required = false, defaultValue = "0") Integer force) {
+        return projectService.deleteProject(id, force);
     }
 
     /**
@@ -355,5 +356,11 @@ public class ProjectController {
     public HttpRespMsg getDegreeCost(String startDate, String endDate, Integer projectId) {
         return projectService.getDegreeCost(startDate, endDate, projectId, request);
     }
+
+    @RequestMapping("exportData")
+    public HttpRespMsg exportData() {
+        return projectService.exportData(request);
+    }
+
 }
 

+ 43 - 19
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -146,7 +146,8 @@ public class ReportController {
                                   String[] pics,
                                   Integer[] multiWorktime,
                                   Integer[] degreeId,
-                                  @RequestParam(required = false, defaultValue = "0") Integer draft
+                                  @RequestParam(required = false, defaultValue = "0") Integer draft,
+                                  Integer[] groupId//任务分组id
                                     ) {
         List<Report> reportList = new ArrayList<>();
         String token = request.getHeader("Token");
@@ -157,6 +158,13 @@ public class ReportController {
             msg.setError("项目不能为空");
             return msg;
         }
+        if (subProjectId == null) {
+            System.out.println("!!===!!有空的子项目");
+            subProjectId = new Integer[projectId.length];
+            for(int i=0;i<subProjectId.length; i++) {
+                subProjectId[i] = 0;
+            }
+        }
         //初始化,防止老版本无此字段奔溃报错
         if (multiWorktime == null) {
             multiWorktime = new Integer[projectId.length];
@@ -167,13 +175,13 @@ public class ReportController {
         if (degreeId == null) {
             degreeId = new Integer[projectId.length];
             for(int i=0;i<degreeId.length; i++) {
-                degreeId[i] = null;
+                degreeId[i] = -1;
             }
-        } else {
-            for(int i=0;i<degreeId.length; i++) {
-                if (degreeId[i] == -1) {
-                    degreeId[i] = null;
-                }
+        }
+        if (groupId == null) {
+            groupId = new Integer[projectId.length];
+            for(int i=0;i<groupId.length; i++) {
+                groupId[i] = 0;
             }
         }
 
@@ -186,10 +194,22 @@ public class ReportController {
             Optional<Project> findP = projectList.stream().filter(p->p.getId().equals(pid)).findFirst();
             if (findP.isPresent()) {
                 Project curP = findP.get();
-                if (curP.getPlanEndDate().isBefore(LocalDate.parse(createDate[i], localDtf))) {
-                    HttpRespMsg msg = new HttpRespMsg();
-                    msg.setError("提交失败,项目["+curP.getProjectName()+"]截止于"+localDtf.format(curP.getPlanEndDate())+",请修改。");
-                    return msg;
+                if (!createDate[i].contains("@")) {
+                    if (curP.getPlanEndDate().isBefore(LocalDate.parse(createDate[i], localDtf))) {
+                        HttpRespMsg msg = new HttpRespMsg();
+                        msg.setError("提交失败,项目["+curP.getProjectName()+"]截止于"+localDtf.format(curP.getPlanEndDate())+",请修改。");
+                        return msg;
+                    }
+                } else {
+                    //批量填报
+                    String[] dateArr = createDate[i].split("@");
+                    for (String curDate : dateArr) {
+                        if (curP.getPlanEndDate().isBefore(LocalDate.parse(curDate, localDtf))) {
+                            HttpRespMsg msg = new HttpRespMsg();
+                            msg.setError("提交失败,项目["+curP.getProjectName()+"]截止于"+localDtf.format(curP.getPlanEndDate())+",请修改。");
+                            return msg;
+                        }
+                    }
                 }
             }
         }
@@ -345,7 +365,8 @@ public class ReportController {
                             Report report = new Report()
                                     .setId(id[i] == -1 ? null : id[i])
                                     .setProjectId(projectId[i])
-                                    .setSubProjectId(subProjectId[i] == 0?null:subProjectId[i])
+                                    .setSubProjectId(subProjectId[i])
+                                    .setGroupId(groupId[i])
                                     .setReportTimeType(reportTimeType[i])
                                     .setMultiWorktime(multiWorktime[i])
                                     .setContent(content[i])
@@ -353,7 +374,7 @@ public class ReportController {
                                     .setState(draft==0?0:3)
                                     .setCompanyId(user.getCompanyId())
                                     .setPicAdd(pics!=null?pics[i]:null)
-                                    .setStage(stage != null && stage.length > 0 && !StringUtil.isEmpty(stage[i])?stage[i]:null)
+                                    .setStage(stage[i])
                                     .setCreateDate(localStartDate)
                                     .setCreatorId(token);
                             report.setProjectAuditState(0);
@@ -395,12 +416,13 @@ public class ReportController {
                                 Report report = new Report()
                                         .setId(id[i] == -1 ? null : id[i])
                                         .setProjectId(projectId[i])
-                                        .setSubProjectId(subProjectId[i] == 0?null:subProjectId[i])
+                                        .setSubProjectId(subProjectId[i])
+                                        .setGroupId(groupId[i])
                                         .setReportTimeType(reportTimeType[i])
                                         .setMultiWorktime(multiWorktime[i])
                                         .setContent(content[i])
                                         .setDegreeId(degreeId.length > 0?degreeId[i]:null)
-                                        .setStage(stage!=null && stage.length > 0  && !StringUtil.isEmpty(stage[i])?stage[i]:null)
+                                        .setStage(stage[i])
                                         .setState(1)//代填,直接是审核通过状态
                                         .setCompanyId(user.getCompanyId())
                                         .setPicAdd(pics!=null?pics[i]:null)
@@ -445,12 +467,13 @@ public class ReportController {
                         Report report = new Report()
                                 .setId(id[i] == -1 ? null : id[i])
                                 .setProjectId(projectId[i])
-                                .setSubProjectId(subProjectId[i] == 0?null:subProjectId[i])
+                                .setSubProjectId(subProjectId[i])
+                                .setGroupId(groupId[i])
                                 .setReportTimeType(reportTimeType[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)
+                                .setStage(stage[i])
                                 .setState(draft==0?0:3)
                                 .setCompanyId(user.getCompanyId())
                                 .setPicAdd(pics!=null?pics[i]:null)
@@ -499,12 +522,13 @@ public class ReportController {
                             Report report = new Report()
                                     .setId(id[i] == -1 ? null : id[i])
                                     .setProjectId(projectId[i])
-                                    .setSubProjectId(subProjectId[i] == 0?null:subProjectId[i])
+                                    .setSubProjectId(subProjectId[i])
+                                    .setGroupId(groupId[i])
                                     .setReportTimeType(reportTimeType[i])
                                     .setMultiWorktime(multiWorktime[i])
                                     .setContent(content[i])
                                     .setDegreeId(degreeId.length > 0?degreeId[i]:null)
-                                    .setStage(stage!=null && stage.length > 0  && !StringUtil.isEmpty(stage[i])?stage[i]:null)
+                                    .setStage(stage[i])
 //                                    .setState(auditWorkflowList.size() == 0?1:0)//代填的如果没有自定义审核流程就直接审核通过了
                                     .setCompanyId(user.getCompanyId())
                                     .setPicAdd(pics!=null?pics[i]:null)

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

@@ -54,6 +54,23 @@ public class StagesController {
     @RequestMapping("/save")
     public HttpRespMsg save(Stages item) {
         HttpRespMsg msg = new HttpRespMsg();
+        //检查名称是否已经存在
+        boolean findSameName = false;
+        if (item.getId() == null) {
+            QueryWrapper<Stages> queryWrapper = new QueryWrapper<Stages>();
+            queryWrapper.eq("group_id", item.getGroupId()).eq("stagesName", item.getStagesName());
+            int cnt = stagesService.count(queryWrapper);
+            findSameName = cnt>0?true: false;
+        } else {
+            QueryWrapper<Stages> queryWrapper = new QueryWrapper<Stages>();
+            queryWrapper.eq("group_id", item.getGroupId()).eq("stagesName", item.getStagesName()).ne("id", item.getId());
+            int cnt = stagesService.count(queryWrapper);
+            findSameName = cnt>0?true: false;
+        }
+        if (findSameName) {
+            msg.setError("当前分组中已存在该任务列表,无法重复添加");
+            return msg;
+        }
         //给seq排序
         QueryWrapper<Stages> queryWrapper = new QueryWrapper<Stages>();
         queryWrapper.eq("group_id", item.getGroupId());
@@ -258,5 +275,13 @@ public class StagesController {
     public HttpRespMsg changeStageOrder(Integer projectId) {
         return stagesService.getProjectStages(projectId);
     }
+
+    //获取分组下的阶段列表
+    @RequestMapping("/getProjectStagesByGroup")
+    public HttpRespMsg getProjectStagesByGroup(Integer groupId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = stagesService.list(new QueryWrapper<Stages>().eq("group_id", groupId));
+        return msg;
+    }
 }
 

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

@@ -444,7 +444,8 @@ public class TaskController {
     }
 
     @RequestMapping("/getRecentTask")
-    public HttpRespMsg getRecentTask(Integer projectId, @RequestParam(required = false, defaultValue = "0") Integer isSubstitude) {
+    public HttpRespMsg getRecentTask(Integer projectId, Integer groupId, Integer stage,
+                                     @RequestParam(required = false, defaultValue = "0") Integer isSubstitude) {
         HttpRespMsg msg = new HttpRespMsg();
         String userId = request.getHeader("Token");
         if (isSubstitude == 0) {

+ 21 - 5
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskGroupController.java

@@ -72,17 +72,23 @@ public class TaskGroupController {
         if (cnt > 0) {
             msg.setError("该分组下存在任务,不可删除");
         } else {
-            taskGroupService.removeById(item.getId());
-            QueryWrapper<TaskGroup> queryWrapper = new QueryWrapper<TaskGroup>();
-            queryWrapper.eq("project_id", item.getProjectId());
-            msg.data = taskGroupService.list(queryWrapper);
+            //至少保留一个分组
+            int count = taskGroupService.count(new QueryWrapper<TaskGroup>().eq("project_id", item.getProjectId()));
+            if (count == 1) {
+                msg.setError("至少保留一个任务分组");
+            } else {
+                taskGroupService.removeById(item.getId());
+                QueryWrapper<TaskGroup> queryWrapper = new QueryWrapper<TaskGroup>();
+                queryWrapper.eq("project_id", item.getProjectId());
+                msg.data = taskGroupService.list(queryWrapper);
+            }
         }
 
         return msg;
     }
 
     /**
-     * 删除任务分组
+     * 获取任务分组
      * @param item
      * @return
      */
@@ -148,5 +154,15 @@ public class TaskGroupController {
         return msg;
     }
 
+
+    @RequestMapping("/saveGroupIncharger")
+    public HttpRespMsg saveGroupIncharger(TaskGroup taskGroup) {
+        taskGroupService.saveGroupIncharger(taskGroup);
+        HttpRespMsg msg = new HttpRespMsg();
+        return msg;
+    }
+
+
+
 }
 

+ 6 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Project.java

@@ -21,7 +21,7 @@ import org.springframework.format.annotation.DateTimeFormat;
  * </p>
  *
  * @author Seyason
- * @since 2021-12-18
+ * @since 2022-03-03
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -227,6 +227,11 @@ public class Project extends Model<Project> {
      */
     @TableField("associate_degree_names")
     private String associateDegreeNames;
+    /**
+     * 下放日报审核权限到分组负责人
+     */
+    @TableField("task_gp_incharge")
+    private Integer taskGpIncharge;
 
 
     @Override

+ 14 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Report.java

@@ -22,7 +22,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2022-02-21
+ * @since 2022-03-03
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -140,7 +140,7 @@ public class Report extends Model<Report> {
     @TableField(exist = false)
     private List<ReportProfessionProgress> professionProgressList;
     @TableField(exist = false)
-    private List<String> stages;
+    private List<Stages> stages;
 
     /**
      * 部门审核状态: -1 专业未审核,0-部门未审核,1-已通过,2-未通过
@@ -250,6 +250,18 @@ public class Report extends Model<Report> {
     private Integer projectAuditState;
 
 
+    /**
+     * 任务分组id
+     */
+    @TableField("group_id")
+    private Integer groupId;
+
+    @TableField(exist = false)
+    private String groupName;
+
+    @TableField(exist = false)
+    private List<TaskGroup> taskGroups;
+
     @Override
     protected Serializable pkVal() {
         return this.id;

+ 8 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TaskGroup.java

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2021-04-19
+ * @since 2022-03-03
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -36,6 +36,13 @@ public class TaskGroup extends Model<TaskGroup> {
     @TableField("name")
     private String name;
 
+    /**
+     * 分组负责人id
+     */
+    @TableField("incharger_id")
+
+    private String inchargerId;
+
     @TableField(exist = false)
     private boolean isNew;
 

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ReportVO.java

@@ -0,0 +1,21 @@
+package com.management.platform.entity.vo;
+
+import com.management.platform.entity.Report;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.time.LocalDateTime;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ReportVO extends Report {
+    private String name;//用户姓名
+    private String project;//项目名称
+    private String subProjectName;//子项目名称
+    private String taskName;//任务名称
+    private String degreeName;//自定义维度名称
+    private String groupName;//分组名称
+}

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectMapper.java

@@ -9,6 +9,7 @@ import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Update;
 import org.springframework.test.context.jdbc.Sql;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -58,4 +59,6 @@ public interface ProjectMapper extends BaseMapper<Project> {
 
     List<Map<String, Object>> getDegreeCost(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projectId") Integer projectId, @Param("companyId") Integer companyId);
 
+    //获取导出的项目数据
+    List<HashMap<String, Object>> getExportData(Integer companyId, String userId);
 }

+ 1 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java

@@ -25,10 +25,7 @@ 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<HashMap<String, Object>> getProjectMembReportByDate(@Param("startDate") String startDate,
                                                      @Param("companyId") Integer companyId,
                                                      @Param("leaderId") String leaderId,

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/TaskGroupMapper.java

@@ -2,6 +2,7 @@ package com.management.platform.mapper;
 
 import com.management.platform.entity.TaskGroup;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Update;
 
 /**
  * <p>
@@ -13,4 +14,6 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  */
 public interface TaskGroupMapper extends BaseMapper<TaskGroup> {
 
+    @Update("update task_group set incharger_id = null where id = #{id}")
+    void removeInchargerId(Integer id);
 }

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

@@ -33,9 +33,10 @@ public interface ProjectService extends IService<Project> {
                             String chosenLeaders,
                             String associateDegrees,
                             String associateDegreeNames,
+                            Integer taskGpIncharge,
                             HttpServletRequest request);
 
-    HttpRespMsg deleteProject(Integer id);
+    HttpRespMsg deleteProject(Integer id, Integer force);
 
     HttpRespMsg getTimeCost(String startDate, String endDate, String userId, HttpServletRequest request);
 
@@ -94,4 +95,6 @@ public interface ProjectService extends IService<Project> {
     HttpRespMsg exportOvertimeList(Integer projectId, String startDate, String endDate, HttpServletRequest request);
 
     HttpRespMsg getDegreeCost(String startDate, String endDate, Integer projectId, HttpServletRequest request);
+
+    HttpRespMsg exportData(HttpServletRequest request);
 }

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

@@ -13,4 +13,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface TaskGroupService extends IService<TaskGroup> {
 
+    void saveGroupIncharger(TaskGroup taskGroup);
 }

+ 0 - 6
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceServiceImpl.java

@@ -191,7 +191,6 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
 
                 if (name.equals("姓名") && rowIndex == 0) {
                     //跳过第一行标题
-                    System.out.println("injuryCell===="+injuryCell.getStringCellValue());
                     if (!"工伤保险".equals(injuryCell.getStringCellValue())) {
                         //缺少工伤保险,需要新的财务报表模板
                         msg.setError("缺少工伤保险栏,请重新下载财务模板填写上传");
@@ -326,7 +325,6 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                             if (map.get("creatorId").equals(finance.getUserId())) {
                                 double time = (Double)map.get("workingTime");
                                 localUser.setCost(total.divide(new BigDecimal(time), 6, BigDecimal.ROUND_HALF_UP));
-//                                System.out.println("cost=="+localUser.getCost());
                                 break;
                             }
                         }
@@ -407,7 +405,6 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                 if (outputStream != null && inputStream != null) {
                     outputStream.close();
                     inputStream.close();
-                    System.out.println("流已关闭");
                 }
             } catch (IOException e) {
                 e.printStackTrace();
@@ -693,7 +690,6 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                         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());
@@ -1149,14 +1145,12 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                 //按比例分配
                 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());

+ 112 - 7
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -14,6 +14,7 @@ import com.management.platform.service.ProjectService;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.ListUtil;
+import io.micrometer.core.instrument.util.DoubleFormat;
 import org.apache.poi.ss.usermodel.CellType;
 import org.apache.poi.xssf.usermodel.XSSFCell;
 import org.apache.poi.xssf.usermodel.XSSFRow;
@@ -28,10 +29,12 @@ import org.springframework.util.StringUtils;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.annotation.Resources;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
 import java.math.BigDecimal;
+import java.text.DecimalFormat;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
@@ -86,6 +89,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     StagesMapper stagesMapper;
     @Resource
     FinanceMapper financeMapper;
+    @Resource
+    TaskGroupMapper taskGroupMapper;
+    @Resource
+    ProjectProfessionMapper projectProfessionMapper;
+
     @Resource
     private HttpServletResponse response;
 
@@ -155,6 +163,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
             List<ProjectVO> list = new ArrayList<>();
             for (Project project : projectList) {
+                System.out.println(project.getTaskGpIncharge());
                 ProjectVO projectVO = new ProjectVO();
                 BeanUtils.copyProperties(project, projectVO);
                 projectVO.setParticipator(participationMapper.getParticipator(projectVO.getId()));
@@ -166,6 +175,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 }
 
                 list.add(projectVO);
+                System.out.println(projectVO.getTaskGpIncharge());
             }
             Long total = projectIPage.getTotal();
             Map<String, Object> map = new HashMap<>();
@@ -193,6 +203,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                    String chosenLeaders,
                                    String associateDegrees,
                                    String associateDegreeNames,
+                                   Integer taskGpIncharge,
                                    HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         User user = userMapper.selectById(request.getHeader("Token"));
@@ -244,7 +255,9 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                             .setBudget(budget)
                             .setAssociateDegrees(associateDegrees)
                             .setAssociateDegreeNames(associateDegreeNames)
-                            .setCustomerId(customerId);
+                            .setCustomerId(customerId)
+                            .setTaskGpIncharge(taskGpIncharge)
+                            ;
                     if (!StringUtils.isEmpty(planStartDate)) {
                         project.setPlanStartDate(LocalDate.parse(planStartDate));
                     }
@@ -301,7 +314,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                         .setBudget(budget)
                         .setAssociateDegrees(associateDegrees)
                         .setAssociateDegreeNames(associateDegreeNames)
-                        .setCustomerId(customerId);
+                        .setCustomerId(customerId)
+                        .setTaskGpIncharge(taskGpIncharge);
                 if (!StringUtils.isEmpty(planStartDate)) {
                     p.setPlanStartDate(LocalDate.parse(planStartDate));
                 }
@@ -431,16 +445,33 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
 
     //删除项目
     @Override
-    public HttpRespMsg deleteProject(Integer id) {
+    public HttpRespMsg deleteProject(Integer id, Integer force) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
-        if (reportMapper.selectCount(new QueryWrapper<Report>().eq("project_id", id)) > 0) {
-            httpRespMsg.setError("项目存在相关报告 无法删除");
-        } else if (projectMapper.deleteById(id) == 0) {
-            httpRespMsg.setError("操作失败");
+        if (force == 1) {
+            //强制删除
+            deleteProData(id);
+        } else {
+            if (reportMapper.selectCount(new QueryWrapper<Report>().eq("project_id", id)) > 0) {
+                httpRespMsg.setError("检测到该项目存在相关日报,确定要删除全部数据吗");
+                httpRespMsg.code = "reconfirm";
+            } else  {
+                deleteProData(id);
+            }
         }
         return httpRespMsg;
     }
 
+    private void deleteProData(Integer id) {
+        reportMapper.delete(new QueryWrapper<Report>().eq("project_id", id));
+        subProjectMapper.delete(new QueryWrapper<SubProject>().eq("project_id", id));
+        participationMapper.delete(new QueryWrapper<Participation>().eq("project_id", id));
+        taskMapper.delete(new QueryWrapper<Task>().eq("project_id", id));
+        taskGroupMapper.delete(new QueryWrapper<TaskGroup>().eq("project_id", id));
+        stagesMapper.delete(new QueryWrapper<Stages>().eq("project_id", id));
+        projectProfessionMapper.delete(new QueryWrapper<ProjectProfession>().eq("project_id", id));
+        projectMapper.deleteById(id);
+    }
+
     private static int monthsNum(String startDate, String endDate) {
         DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
         LocalDate localDateTime = LocalDate.parse(startDate, df);
@@ -1656,4 +1687,78 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         msg.data = projectMapper.getDegreeCost(startDate, endDate, projectId, user.getCompanyId());
         return msg;
     }
+
+    @Override
+    public HttpRespMsg exportData(HttpServletRequest request) {
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        String userId = null;
+        if(user.getRole() != 1 && user.getRole() != 2) {
+            //非系统管理员只能导出自己相关的(创建或参与)
+            userId = user.getId();
+        }
+        List<HashMap<String, Object>> list = projectMapper.getExportData(user.getCompanyId(), userId);
+        Company company = companyMapper.selectById(user.getCompanyId());
+        List<String> headList = new ArrayList<String>();
+        headList.add("项目编号");
+        headList.add("项目名称");
+        headList.add("负责人");
+        headList.add("参与人");
+        headList.add("开始日期");
+        headList.add("结束日期");
+        headList.add("创建人");
+        headList.add("创建日期");
+        //自定义维度
+        TimeType timeType = timeTypeMapper.selectById(user.getCompanyId());
+        if (timeType.getCustomDegreeActive() == 1) {
+            headList.add(timeType.getCustomDegreeName());
+        }
+        if (company.getPackageProject() == 1) {
+            //项目管理专业版以上的,导出的数据更全面
+            headList.add("客户");
+            headList.add("项目级别");
+            headList.add("合同金额");
+        }
+        List<List<String>> allList = new ArrayList<List<String>>();
+        allList.add(headList);
+        String[] levelArray = new String[]{"正常","紧急","重要","重要且紧急"};
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        DecimalFormat df = new DecimalFormat("##0.0#");
+        for (Map<String, Object> map : list) {
+            List<String> rowData = new ArrayList<>();
+            rowData.add((String)map.get("project_code"));
+            rowData.add((String)map.get("project_name"));
+            rowData.add((String)map.get("incharger_name"));
+            rowData.add((String)map.get("participators"));
+            Date start = (Date)map.get("plan_start_date");
+            rowData.add(start==null?"":sdf.format(start));
+            Date end = (Date)map.get("plan_end_date");
+            rowData.add(end==null?"":sdf.format(end));
+            rowData.add((String)map.get("creator_name"));
+            Date createDate = (Date)map.get("create_date");
+            rowData.add(createDate==null?"":sdf.format(createDate));
+
+            if (timeType.getCustomDegreeActive() == 1) {
+                rowData.add((String)map.get("associate_degree_names"));
+            }
+            if (company.getPackageProject() == 1) {
+                Integer level = (Integer)map.get("level");
+                if (level == null) {
+                    level = 1;
+                }
+                rowData.add((String)map.get("customer_name"));
+                rowData.add(levelArray[level-1]);
+                rowData.add(df.format((Double)map.get("contract_amount")));
+            }
+            allList.add(rowData);
+        }
+
+        //生成excel文件导出
+        String fileName = "项目导出_"+company.getCompanyName()+System.currentTimeMillis();
+        String resp = ExcelUtil.exportGeneralExcelByTitleAndList(fileName , allList, path);
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg.data = resp;
+
+        return httpRespMsg;
+    }
 }

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

@@ -75,7 +75,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     public String appId;
     @Value("${wx.app_secret}")
     public String appSecret;
-
+    @Resource
+    private TaskGroupMapper taskGroupMapper;
     @Resource
     private ReportService reportService;
     @Resource
@@ -192,7 +193,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     } else {
                         queryDeptList = allDepts.stream().filter(
                                 dp -> user.getId().equals(dp.getManagerId())).collect(Collectors.toList());
-                        System.out.println("查询到的部门id列表=="+queryDeptList.size());
                     }
 
                     if (queryDeptList.size() > 0) {
@@ -412,8 +412,9 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             List<Profession> professions = professionMapper.selectList(new QueryWrapper<Profession>().eq("company_id", companyId));
 
             List<ReportExtraDegree> degreeList = reportExtraDegreeMapper.selectList(new QueryWrapper<ReportExtraDegree>().eq("company_id", companyId));
-
-            //获取当前项目的子项目列表,任务列表,项目相关维度列表
+            List<TaskGroup> taskGroups = integerList.size() > 0?taskGroupMapper.selectList(new QueryWrapper<TaskGroup>().in("project_id", integerList)):new ArrayList<>();
+            List<Stages> stagesList = integerList.size() > 0?stagesMapper.selectList(new QueryWrapper<Stages>().in("project_id", integerList)) : new ArrayList<>();
+            //获取当前项目的子项目列表,任务分组,任务列表,项目相关维度列表
             reports.forEach(r->{
                 r.setSubProjectList(subProjectList.stream().filter(s->s.getProjectId().equals(r.getProjectId())).collect(Collectors.toList()));
                 r.setTaskList(taskList.stream().filter(t->t.getProjectId().equals(r.getProjectId()) && t.getUserId().equals(r.getCreatorId())).collect(Collectors.toList()));
@@ -424,8 +425,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 });
                 r.setProfessionProgressList(progressList);
                 //获取任务阶段列表
-                if (company.getPackageProject() == 1) {
-                    r.setStages(stagesMapper.getProjectStages(r.getProjectId()));
+                if (company.getPackageProject() == 1 && r.getGroupId() != null && r.getGroupId() != 0) {
+                    r.setStages(stagesList.stream().filter(s->s.getGroupId() !=null && s.getGroupId().equals(r.getGroupId())).collect(Collectors.toList()));
                 }
                 //处理图片
                 if (!StringUtils.isEmpty(r.getPicStr()) && !r.getPicStr().equals("@")) {
@@ -469,6 +470,17 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     }
                     r.setDegreeList(degreeMapList);
                 }
+
+                //分组
+                if (company.getPackageProject() == 1) {
+                    r.setTaskGroups(taskGroups.stream().filter(tg->tg.getProjectId().equals(r.getProjectId())).collect(Collectors.toList()));
+                    if (r.getGroupId() != null && r.getGroupId() != 0) {
+                        Optional<TaskGroup> optinal = taskGroups.stream().filter(tg->tg.getId().equals(r.getGroupId())).findFirst();
+                        if (optinal.isPresent()) {
+                            r.setGroupName(optinal.get().getName());
+                        }
+                    }
+                }
             });
             resultMap.put("report", reports);
             //顺便再获取一下可分配时间
@@ -494,6 +506,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
             httpRespMsg.data = resultMap;
         } catch (NullPointerException e) {
+            e.printStackTrace();
             httpRespMsg.setError("验证失败");
             return httpRespMsg;
         } catch (DateTimeParseException e) {
@@ -870,7 +883,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 List<AuditWorkflowTimeSetting> settings = auditWorkflowTimeSettingMapper.selectList(
                         new QueryWrapper<AuditWorkflowTimeSetting>().eq("dept_id", auditTargetUser.getDepartmentId())
                                 .orderByAsc("seq"));
-                System.out.println("======setting count==" + settings.size());
                 if (settings.size() == 0) {
                     //直接进行项目经理审核
                     reportMapper.update(new Report().setState(1).setProjectAuditState(1),
@@ -914,7 +926,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                     new QueryWrapper<Report>().in("id", ids));
                         } else {
                             //当前的先审核通过
-                            System.out.println("===========更新项目审核状态======"+ids.size());
                             reportMapper.update(new Report().setProjectAuditState(1),
                                     new QueryWrapper<Report>().in("id", ids));
                             //项目审核的情况下,需要判断是否该员工当天所有项目是否都是项目经理审核通过了
@@ -1361,7 +1372,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 for (Integer rid : ids) {
                     String creatorId = allReports.stream().filter(a->a.getId().equals(rid)).findFirst().get().getCreatorId();
                     User auditTargetUser = allUsers.stream().filter(a->a.getId().equals(creatorId)).findFirst().get();
-                    System.out.println("======setting count==" + settings.size());
                     List<AuditWorkflowTimeSetting> deptSettings = settings.stream().filter(s->s.getDeptId().equals(auditTargetUser.getDepartmentId())).collect(Collectors.toList());
                     Report curReport = new Report().setId(rid);
                     if (deptSettings.size() == 0) {
@@ -1577,7 +1587,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             //按日期过滤
             if (!StringUtils.isEmpty(date)) {
                 nameList = nameList.stream().filter(map->{
-                    System.out.println("已有数据日期=="+sdf.format((java.sql.Date)map.get("date"))+", 参数date="+date);
                     return (sdf.format((java.sql.Date)map.get("date"))).equals(date);
                 }).collect(Collectors.toList());
             }
@@ -1759,7 +1768,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         String startDate = month + "-01";
         LocalDate ld = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
         int year = ld.getYear();
-        System.out.println("year = "+year);
         boolean isLerpYear = false;
         if (year%4==0&&year%100!=0) {
             isLerpYear = true;
@@ -1780,7 +1788,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         }
 
         String endDate = month + "-"+maxDaysOfMonth;
-        System.out.println("endDate=="+endDate);
         HttpRespMsg msg = new HttpRespMsg();
         List<Map<String, Object>> list = null;
         //分角色权限:管理员看全部的,部门负责人看自己部门的,个人只能看自己的。
@@ -1794,7 +1801,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     subDepts.addAll(getSubDepts(dp, allDepts));
                     subDepts.add(dp);
                 }
-                System.out.println("部门=="+subDepts.size());
                 List<Integer> collect = subDepts.stream().map(Department::getDepartmentId).collect(Collectors.toList());
                 list = reportMapper.getUserDailyWorkTime(companyId, startDate, endDate, collect, null);
             } else {
@@ -1930,7 +1936,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             List<SubProject> allSubProjectList = subProjectMapper.selectList(new QueryWrapper<SubProject>().eq("company_id", companyId));
             List<Report> reportList = new ArrayList<>();
             int projectNameStartIndex = (withCheckIn==null?2:6);
-
+            int dataCount = 0;
             for (int rowIndex = 0; rowIndex <= rowNum; rowIndex++) {
                 Row row = sheet.getRow(rowIndex);
                 if (row == null) {
@@ -1978,6 +1984,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         return msg;
                     }
                 } else {
+                    dataCount++;
                     //数据行
                     for (int i=1;i<projectNameStartIndex+projectList.size(); i++) {
                         row.getCell(i).setCellType(CellType.STRING);
@@ -2050,7 +2057,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             }
             //存储
             reportService.saveBatch(reportList);
-            msg.data = rowNum;
+            msg.data = dataCount;
         } catch (IOException e) {
             e.printStackTrace();
             msg.setError("文件处理出错");

+ 14 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TaskGroupServiceImpl.java

@@ -5,6 +5,9 @@ import com.management.platform.mapper.TaskGroupMapper;
 import com.management.platform.service.TaskGroupService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
 
 /**
  * <p>
@@ -16,5 +19,16 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class TaskGroupServiceImpl extends ServiceImpl<TaskGroupMapper, TaskGroup> implements TaskGroupService {
+    @Resource
+    private TaskGroupMapper taskGroupMapper;
 
+    @Override
+    public void saveGroupIncharger(TaskGroup taskGroup) {
+        if (StringUtils.isEmpty(taskGroup.getInchargerId())) {
+            //清除负责人
+            taskGroupMapper.removeInchargerId(taskGroup.getId());
+        } else {
+            taskGroupMapper.updateById(taskGroup);
+        }
+    }
 }

+ 27 - 10
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml

@@ -34,8 +34,15 @@
         <result column="is_public" property="isPublic" />
         <result column="associate_degrees" property="associateDegrees" />
         <result column="associate_degree_names" property="associateDegreeNames" />
+        <result column="task_gp_incharge" property="taskGpIncharge" />
     </resultMap>
 
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, project_name, company_id, project_code, incharger_id, plan_start_date, plan_end_date, progress, level, status, finish_date, creator_id, creator_name, create_date, contract_amount, budget, base_man, base_outsourcing, base_risk1, base_risk2, base_fee, fee_normal, fee_travel, fee_outsourcing, fee_man, customer_id, customer_name, is_public, associate_degrees, associate_degree_names, task_gp_incharge
+    </sql>
+
+
     <resultMap id="BaseResultMap2" type="com.management.platform.entity.vo.ProjectWithStage">
         <result column="id" property="id" />
         <result column="project_name" property="projectName" />
@@ -44,11 +51,6 @@
                     ofType="com.management.platform.entity.vo.StageCost"
                     select="selectStageSum" column="projectId=id"></collection>
     </resultMap>
-
-    <!-- 通用查询结果列 -->
-    <sql id="Base_Column_List">
-        id, project_name, company_id, project_code, incharger_id, plan_start_date, plan_end_date, progress, level, status, finish_date, creator_id, creator_name, create_date, contract_amount, budget, base_man, base_outsourcing, base_risk1, base_risk2, base_fee, fee_normal, fee_travel, fee_outsourcing, fee_man, customer_id, customer_name, is_public, associate_degrees, associate_degree_names
-    </sql>
     <resultMap id="CustomerResultMap" type="com.management.platform.entity.vo.CustomerProject" >
         <result column="customer_id" property="customerId" />
         <result column="customer_name" property="customerName" />
@@ -279,15 +281,30 @@
         FROM report AS a
         left join report_extra_degree b on b.id = a.degree_id
         WHERE
-         a.state = 1
-         and a.company_id = #{companyId}
-         <if test="projectId != null">
-             and a.project_id = #{projectId}
-         </if>
+        a.state = 1
+        and a.company_id = #{companyId}
+        <if test="projectId != null">
+            and a.project_id = #{projectId}
+        </if>
         <if test="startDate != null and endDate != null">
             AND a.create_date between #{startDate} and #{endDate}
         </if>
         GROUP BY a.degree_id
         ORDER BY a.degree_id ASC
     </select>
+    <!--项目导出数据-->
+    <select id="getExportData" resultType="java.util.HashMap" >
+        SELECT project.id, project_name, project_code, plan_start_date, d.name AS incharger_name,GROUP_CONCAT(u.name) AS participators,
+        plan_end_date, progress, LEVEL, STATUS, finish_date, creator_id, creator_name, create_date, contract_amount,
+        customer_name, associate_degree_names
+        FROM project LEFT JOIN sub_project ON sub_project.id = project.`id`
+        LEFT JOIN participation c ON c.project_id = project.`id`
+        LEFT JOIN user u ON u.id = c.user_id
+        LEFT JOIN user d ON d.id = project.`incharger_id`
+        WHERE project.`company_id` = #{companyId}
+        <if test="userId != null" >
+            project.creator_id = #{userId} or c.user_id = #{userId}
+        </if>
+        GROUP BY project.id
+    </select>
 </mapper>

+ 23 - 12
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

@@ -36,27 +36,30 @@
         <result column="audit_dept_managerid" property="auditDeptManagerid" />
         <result column="is_final_audit" property="isFinalAudit" />
         <result column="project_audit_state" property="projectAuditState" />
+        <result column="group_id" property="groupId" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, creator_id, project_id, create_date, working_time, content, state, create_time, time_type, cost, start_time, end_time, report_time_type, sub_project_id, task_id, is_overtime, progress, department_audit_state, stage, pic_str, multi_worktime, reject_reason, reject_username, reject_userid, degree_id, company_id, fill_userid, audit_deptid, is_dept_audit, audit_dept_managerid, is_final_audit, project_audit_state
+        id, creator_id, project_id, create_date, working_time, content, state, create_time, time_type, cost, start_time, end_time, report_time_type, sub_project_id, task_id, is_overtime, progress, department_audit_state, stage, pic_str, multi_worktime, reject_reason, reject_username, reject_userid, degree_id, company_id, fill_userid, audit_deptid, is_dept_audit, audit_dept_managerid, is_final_audit, project_audit_state, group_id
     </sql>
 
 
+
     <!--根据日期获取全部报告信息-->
     <select id="getAllReportByDate" 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
+        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,task_group.name as groupName,a.group_id as groupId
         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
+        left join task_group on task_group.id = a.group_id
         WHERE a.state = 1
         <if test="startDate != null and startDate != ''">
             AND a.create_date between #{startDate} and #{endDate}
@@ -78,13 +81,14 @@
         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
+        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,task_group.name as groupName,a.group_id as groupId
         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
+        left join task_group on task_group.id = a.group_id
         WHERE a.state = 1
         <if test="startDate != null and startDate != ''">
             AND a.create_date between #{startDate} and #{endDate}
@@ -103,13 +107,14 @@
         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
+        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,task_group.name as groupName,a.group_id as groupId
         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
+        left join task_group on task_group.id = a.group_id
         WHERE a.state = 1
         <if test="startDate != null and startDate != ''">
             AND a.create_date between #{startDate} and #{endDate}
@@ -128,13 +133,14 @@
         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
+        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,task_group.name as groupName,a.group_id as groupId
         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
+        left join task_group on task_group.id = a.group_id
         WHERE a.state = 1
         <if test="startDate != null and startDate != ''">
             AND a.create_date between #{startDate} and #{endDate}
@@ -160,13 +166,14 @@
         a.creator_id as creatorId, 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.stage, 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,
-        department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState
+        department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState,task_group.name as groupName,a.group_id as groupId
         FROM report AS a
         JOIN project AS b ON a.project_id=b.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
         left join department on department.department_id = a.audit_deptid
+        left join task_group on task_group.id = a.group_id
         WHERE 1=1
         <if test="date != null and date != ''">
             AND a.create_date=#{date}
@@ -183,13 +190,14 @@
         a.creator_id as creatorId, 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.stage, 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,
-        department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState
+        department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState,task_group.name as groupName,a.group_id as groupId
         FROM report AS a
         JOIN project AS b ON a.project_id=b.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
         left join department on department.department_id = a.audit_deptid
+        left join task_group on task_group.id = a.group_id
         WHERE 1=1
         <if test="date != null and date != ''">
             AND a.create_date=#{date}
@@ -209,7 +217,7 @@
         a.creator_id as creatorId, 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.stage, 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,
-        department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState
+        department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState,task_group.name as groupName,a.group_id as groupId
         FROM report AS a
         left join user on user.id = a.creator_id
         JOIN project AS b ON a.project_id=b.id
@@ -217,6 +225,7 @@
         left join task on task.id = a.task_id
         left join report_extra_degree on report_extra_degree.id = a.degree_id
         left join department on department.department_id = a.audit_deptid
+        left join task_group on task_group.id = a.group_id
         WHERE a.company_id = #{companyId}
         and a.state = 0
         <if test="date != null and date != ''">
@@ -236,7 +245,7 @@
         </if>
         <if test="inchargerId != null">
             AND ((a.is_dept_audit = 0 and b.incharger_id = #{inchargerId} and a.project_audit_state = 0)
-                or (a.is_dept_audit = 1 and a.audit_dept_managerid = #{inchargerId}))
+            or (a.is_dept_audit = 1 and a.audit_dept_managerid = #{inchargerId}))
         </if>
         <if test="isEngeering == 1">
             AND a.department_audit_state = 1
@@ -251,12 +260,14 @@
         a.end_time as endTime, b.incharger_id as inchargerId,
         a.creator_id as creatorId, d.name as subProjectName,a.task_id as taskId, task.name as taskName,
         a.is_overtime as isOvertime,a.progress as progress, a.stage, 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
+        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,
+        task_group.name as groupName,a.group_id as groupId
         FROM report AS a
         JOIN project AS b ON a.project_id=b.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
+        left join task_group on task_group.id = a.group_id
         WHERE 1=1
         <if test="date != null and date != ''">
             AND a.create_date=#{date}
@@ -276,13 +287,14 @@
         a.is_overtime as isOvertime,a.progress as progress,
         a.department_audit_state as departmentAuditState, a.stage, 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,
-        department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState
+        department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState,task_group.name as groupName,a.group_id as groupId
         FROM report AS a
         JOIN project AS b ON a.project_id=b.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
         left join department on department.department_id = a.audit_deptid
+        left join task_group on task_group.id = a.group_id
         WHERE 1=1
         <if test="date != null and date != ''">
             AND a.create_date=#{date}
@@ -475,5 +487,4 @@
         left join project on project.id = report.project_id
             where report.company_id = #{companyId} and report.create_date between #{startDate} and #{endDate}
     </select>
-
 </mapper>

+ 14 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SubProjectMapper.xml

@@ -14,5 +14,18 @@
     <sql id="Base_Column_List">
         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/TaskGroupMapper.xml

@@ -7,11 +7,12 @@
         <id column="id" property="id" />
         <result column="project_id" property="projectId" />
         <result column="name" property="name" />
+        <result column="incharger_id" property="inchargerId" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, project_id, name
+        id, project_id, name, incharger_id
     </sql>
 
 </mapper>

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

@@ -174,6 +174,6 @@
         <if test="userId != null">
             and executor_id = #{userId}
         </if>
-        and task_status = 0 order by task.id desc limit 30
+        and task_status = 0 order by task.id desc limit 50
     </select>
 </mapper>

+ 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.159'
 
-// 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: {

+ 63 - 69
fhKeeper/formulahousekeeper/timesheet/src/views/project/cost.vue

@@ -1,6 +1,14 @@
 <template>
     <section>
-        <el-col :span="24" style="padding-bottom: 0px;text-align:center;margin-top:10px;position: fixed;top: 60px;left: 160px;z-index: 999;">
+        <el-row style="padding-bottom: 0px;text-align:center;margin-top:20px;z-index: 999;">
+        <el-col :span="6" >
+            <div ><span style="color:#999;">图表Y轴: </span>
+            <el-radio-group v-model="yAxisValue" @change="onYAxisChange">
+            <el-radio-button label="0">显示成本</el-radio-button>
+            <el-radio-button label="1">显示工时</el-radio-button>
+            </el-radio-group></div>
+        </el-col>
+        <el-col :span="12" style="">
             <el-date-picker v-show="user.timeType.fixMonthcost==0"
             v-model="dateRange" :editable="false" 
             format="yyyy-MM-dd" value-format="yyyy-MM-dd" 
@@ -27,17 +35,16 @@
                 <el-radio-button :label="namess" v-if="jichu.customDegreeActive == 1"></el-radio-button>
             </el-radio-group>
         </el-col>
-        <!-- <div :style="'width:'+widthHtval+'rem;position: relative;'"> -->
+        <el-col :span="6">
+            <el-button @click="showExportDialog">报表导出</el-button>
+        </el-col>
+        </el-row>
         <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> -->
-            
+        <div style="position:fixed;top:170px;left:600px;" v-show="radio=='部门' && parentDeptId != null">
             <el-button @click="backToParentDept">返回上级</el-button>
         </div>
-        <div style="position:fixed;top:120px;right:150px;"><el-button @click="showExportDialog">报表导出</el-button></div>
 
         <!--导出报表条件选择 -->
         <el-dialog title="工时报表导出" v-if="exportDialog" :visible.sync="exportDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
@@ -97,6 +104,7 @@
     export default {
         data() {
             return {
+                yAxisValue: localStorage.yAxisValue?localStorage.yAxisValue:0,
                 parentDeptStack:[],
                 parentDeptId:null,
                 hasReportUserList:[],
@@ -118,6 +126,11 @@
             };
         },
         methods: {
+            //Y轴点击改变显示的数据
+            onYAxisChange() {
+                localStorage.yAxisValue = this.yAxisValue;
+                this.jieliu();
+            },
             jutishez() {
                 this.http.post('/time-type/getCompanyTimeSetting', {
                     companyId: this.user.companyId,
@@ -271,6 +284,7 @@
                         this.hasReportUserList = res.data.userList;
                         var xList = [] , yList = [] , list = res.data.list, array = [] , series = [];
                         var totalMoneyCost = res.data.totalCostMoney;
+                        var totalHours = 0.0;
                         if (list.length > 0) {
                             var num = list.length==0?0:list[0].project.length;
                             for(var i in list) {
@@ -292,9 +306,11 @@
                                         for(var k in project) {
                                             if(project[k].project == array[i]) {
                                                 dataList.push({
-                                                    "value": project[k].money,
+                                                    "value": this.yAxisValue==0?project[k].money:project[k].time,
                                                     "cost": project[k].time,
+                                                     "money":project[k].money
                                                 })
+                                                totalHours += parseFloat(project[k].time);
                                             } else {
                                                 num++;
                                             }
@@ -302,6 +318,7 @@
                                                 dataList.push({
                                                     "value": 0,
                                                     "cost": 0,
+                                                    "money":0,
                                                 })
                                             }
                                         }
@@ -309,6 +326,7 @@
                                         dataList.push({
                                             "value": 0,
                                             "cost": 0,
+                                            "money":0,
                                         })
                                     }
                                 }
@@ -324,11 +342,12 @@
                             
                             
                             var myChart = echarts.init(document.getElementById("container"));
+                            totalHours = totalHours.toFixed(1);
                             _this.myChart = myChart;
                             var option = {
                                 //总成本
                                 title: {
-                                    text: '工时成本总计' + totalMoneyCost.toFixed(2) + '元',
+                                    text: '工时成本总计' + totalMoneyCost.toFixed(2) + '元, 时长'+totalHours+'小时',
                                     left:'left',
                                 },
                                 
@@ -373,10 +392,10 @@
                                         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 
-                                                    + "</font><br/>工作成本 : " + params[i].data.value
+                                                    + "</font><br/>工作成本 : " + params[i].data.money
                                                     + "元 <br/>工作时长"+" : " + params[i].data.cost + "小时</br></div>";
                                                 totalTime += Number(params[i].data.cost);
-                                                totalCost += Number(params[i].data.value);
+                                                totalCost += Number(params[i].data.money);
                                             }
                                         }
                                         res = res +'<br/>'+ params[0].name+ '<br/>总计: ' + totalTime.toFixed(1)+'小时 '+totalCost.toFixed(2) + "元<br/>";
@@ -392,7 +411,7 @@
                                 yAxis: [{
                                     type : 'value',
                                     axisLabel: {
-                                        formatter:'{value} (元)'
+                                        formatter:this.yAxisValue==0?'{value} (元)':'{value} (小时)'
                                     }
                                 }],
                                 series: series,
@@ -476,42 +495,50 @@
                         var xList = []
                         var yList = []
                         var list
-                        var totalMoneyCost
-                        if(this.radio == '项目' || this.radio == '人员' || this.radio=='部门') {
+                        var totalMoneyCost;
+                        var totalHours = 0.0;
+                        if(this.radio == '项目' || this.radio=='部门') {
                             list = res.data.costList
-                            totalMoneyCost = ((this.radio=='项目' || this.radio=='人员')?res.data.totalMoneyCost:res.data.totalCostMoney);
+                            totalMoneyCost = ((this.radio=='项目')?res.data.totalMoneyCost:res.data.totalCostMoney);
                             for(var i in list) {
-                                if(this.radio=='项目' || this.radio == '人员') {
+                                if(this.radio=='项目') {
                                     xList.push(this.radio=='项目'?list[i].project:list[i].name);
                                     yList.push({
-                                        "value": list[i].costMoney.toFixed(2) || list[i].costMoney,
+                                        "value": this.yAxisValue==0?list[i].costMoney.toFixed(2) || list[i].costMoney:list[i].cost.toFixed(1),
                                         "id": list[i].id || i,
-                                        "cost": list[i].cost
+                                        "cost": list[i].cost,
+                                        "money":list[i].costMoney.toFixed(2)
                                     });
+                                    totalHours += parseFloat(list[i].cost);
                                 } else {
                                     xList.push(list[i].departmentName);
                                     yList.push({
-                                        "value": list[i].costMoney.toFixed(2) || list[i].costMoney,
+                                        "value": this.yAxisValue==0? list[i].costMoney.toFixed(2) || list[i].costMoney: list[i].costTime.toFixed(1),
                                         "id": list[i].departmentId,
                                         "cost": list[i].costTime,
-                                        "hasSubDept": list[i].hasSubDept
+                                        "hasSubDept": list[i].hasSubDept,
+                                        "money":list[i].costMoney.toFixed(2)
                                     });
+                                    totalHours += parseFloat(list[i].costTime);
                                 }
                             }
                         } else {
                             list = res.data
-                            var totalMoneyCost = 1
+                            var totalMoneyCost = 0;
                             for(var i in list) {
                                 console.log(list[i].name, list[i].costMoney, list[i].cost)
                                 xList.push(list[i].name);
                                 yList.push({
-                                    "value": list[i].costMoney,
+                                    "value": this.yAxisValue==0?list[i].costMoney:list[i].cost,
                                     "id": list[i].id || i,
-                                    "cost": list[i].cost
+                                    "cost": list[i].cost,
+                                    "money":list[i].costMoney.toFixed(2)
                                 });
+                                totalHours += parseFloat(list[i].cost);
+                                totalMoneyCost += parseFloat(list[i].costMoney);
                             }
                         }
-                        
+                        totalHours = totalHours.toFixed(1);
                         
                         var myChart = echarts.init(document.getElementById("container"));
                         myChart.resize({
@@ -526,36 +553,20 @@
                         if(this.radio == '项目' || this.radio == '人员' || this.radio=='部门') {
                             var option = {
                                 title: {
-                                    text: '工时成本总计' + this.zhishin + '元',
+                                    text: '工时成本总计' + this.zhishin + '元, 时长'+totalHours+'小时',
                                     left:'left',
                                 },
                                 // 工具箱
                                 toolbox: {
                                     show: true,
                                     feature:{
-                                    
-                                        saveAsImage:{
-                                            show:true
-                                        },
-                                        restore:{
-                                            show:true
-                                        },
-                                        // dataView:{
-                                        //     show:true
-                                        // },
-                                        // dataZoom:{
-                                        //     show:true
-                                        // },
-                                        magicType:{
-                                            type:['line','bar']
-                                        },
-                                        
+                                        saveAsImage:{show:true},restore:{show:true}, magicType:{ type:['line','bar']},
                                     }
                                 },
                                 tooltip:{
                                     trigger:'axis',
                                     formatter: function (params,ticket,callback) {
-                                        var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.value 
+                                        var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.money 
                                         + "元 <br/>工作时长"+" : " + params[0].data.cost + "小时";
                                         _this.params = params;
                                         return res;
@@ -570,11 +581,11 @@
                                 yAxis: [{
                                     type : 'value',
                                     axisLabel: {
-                                        formatter:'{value} (元)'
+                                        formatter:this.yAxisValue==0?'{value} (元)':'{value}小时'
                                     }
                                 }],
                                 series: [{
-                                    name: '工作成本(元)',
+                                    name: this.yAxisValue==0?'工作成本(元)':'工作时长(小时)',
                                     type: 'bar',
                                     barMaxWidth: 30,
                                     data: yList,
@@ -583,36 +594,20 @@
                         } else {
                             var option = {
                                 title: {
-                                    text: '',
+                                    text: '工时成本总计' + this.zhishin + '元, 时长'+totalHours+'小时',
                                     left:'left',
                                 },
                                 // 工具箱
                                 toolbox: {
                                     show: true,
                                     feature:{
-                                    
-                                        saveAsImage:{
-                                            show:true
-                                        },
-                                        restore:{
-                                            show:true
-                                        },
-                                        // dataView:{
-                                        //     show:true
-                                        // },
-                                        // dataZoom:{
-                                        //     show:true
-                                        // },
-                                        magicType:{
-                                            type:['line','bar']
-                                        },
-                                        
+                                        saveAsImage:{show:true},restore:{show:true}, magicType:{ type:['line','bar']},
                                     }
                                 },
                                 tooltip:{
                                     trigger:'axis',
                                     formatter: function (params,ticket,callback) {
-                                        var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.value 
+                                        var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.money 
                                         + "元 <br/>工作时长"+" : " + params[0].data.cost + "小时";
                                         _this.params = params;
                                         return res;
@@ -627,11 +622,11 @@
                                 yAxis: [{
                                     type : 'value',
                                     axisLabel: {
-                                        formatter:'{value} (元)'
+                                        formatter:this.yAxisValue==0?'{value} (元)':'{value}小时'
                                     }
                                 }],
                                 series: [{
-                                    name: '工作成本(元)',
+                                    name: this.yAxisValue==0?'工作成本(元)':'工作时长(小时)',
                                     type: 'bar',
                                     barMaxWidth: 30,
                                     data: yList,
@@ -661,7 +656,6 @@
                                         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();
@@ -694,10 +688,10 @@
         created() {
         },
         mounted() {
-            this.containerHeight = window.innerHeight - 140
+            this.containerHeight = window.innerHeight - 200
             const that = this;
             window.onresize = function temp() {
-                this.containerHeight = window.innerHeight - 100
+                this.containerHeight = window.innerHeight - 200
             };
             if (this.user.timeType.fixMonthcost == 0) {
                 if (this.$route.query.startDate != null) {

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

@@ -33,6 +33,7 @@
     export default {
         data() {
             return {
+                yAxisValue: localStorage.yAxisValue,
                 startDate:null,
                 endDate: null,
                 detailId: this.$route.params.id,
@@ -82,8 +83,9 @@
                         for(var i in list) {
                             xList.push(list[i].name);
                             yList.push({
-                                "value": list[i].costMoney,
-                                "cost": list[i].cost
+                                "value": this.yAxisValue==0?list[i].costMoney:list[i].cost,
+                                "cost": list[i].cost,
+                                "money": list[i].costMoney,
                             });
                         }
 
@@ -114,7 +116,7 @@
                             tooltip:{
                                 trigger:'axis',
                                 formatter: function (params,ticket,callback) {
-                                    var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.value 
+                                    var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.money 
                                     + "元 <br/>工作时长"+" : " + params[0].data.cost + "小时";
                                     return res;
                                 }
@@ -128,11 +130,11 @@
                             yAxis: [{
                                 type : 'value',
                                 axisLabel: {
-                                    formatter:'{value} (元)'
+                                    formatter:this.yAxisValue==0?'{value} (元)':'{value}(小时)'
                                 }
                             }],
                             series: [{
-                                name: '工作成本(元)',
+                                name: this.yAxisValue==0?'工作成本(元)':'工作时长(小时)',
                                 type: 'bar',
                                 barMaxWidth: 30,
                                 data: yList,

+ 7 - 3
fhKeeper/formulahousekeeper/timesheet/src/views/project/detailDep.vue

@@ -30,6 +30,7 @@
     export default {
         data() {
             return {
+                yAxisValue: localStorage.yAxisValue,
                 startDate:null,
                 endDate: null,
                 detailId: this.$route.params.id,
@@ -140,19 +141,22 @@
                                         var findProject = project.filter(p=>p.project == array[i]);
                                         if (findProject.length > 0) {
                                             dataList.push({
-                                                    "value": findProject[0].money,
+                                                    "value": this.yAxisValue==0?findProject[0].money:findProject[0].time,
                                                     "cost": findProject[0].time,
+                                                    "money": findProject[0].money
                                                 })
                                         } else {
                                             dataList.push({
                                                     "value": 0,
                                                     "cost": 0,
+                                                    "money": 0,
                                                 })
                                         }
                                     } else {
                                         dataList.push({
                                             "value": 0,
                                             "cost": 0,
+                                            "money": 0
                                         })
                                     }
                                 }
@@ -211,7 +215,7 @@
                                         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 
-                                                    + "</font><br/>工作成本 : " + params[i].data.value
+                                                    + "</font><br/>工作成本 : " + params[i].data.money
                                                     + "元 <br/>工作时长"+" : " + params[i].data.cost + "小时</br></div>";
                                             }
                                         }
@@ -227,7 +231,7 @@
                                 yAxis: [{
                                     type : 'value',
                                     axisLabel: {
-                                        formatter:'{value} (元)'
+                                        formatter:this.yAxisValue==0?'{value} (元)':'{value}(小时)'
                                     }
                                 }],
                                 series: series,

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

@@ -31,6 +31,10 @@
                 <el-form-item style="float:right;"  v-if="user.company.packageProject == 1 && (user.role == 1||user.role == 2||user.role == 5)">
                     <el-link type="primary" :underline="false" @click="showBaseCostItemDialog">基线成本项</el-link>
                 </el-form-item>
+                
+                <el-form-item style="float:right;" v-if="user.role == 1||user.role == 2||user.role == 5">
+                    <el-link type="primary" style="margin-left:5px;" :underline="false" @click="exportProjectData" download="项目导出.xlsx">导出项目</el-link>
+                </el-form-item>
                 <el-form-item style="float:right;" v-if="user.role == 1||user.role == 2||user.role == 5">
                     <el-link type="primary" style="margin-left:5px;" :underline="false" href="./upload/项目导入模板.xlsx" download="项目导入模板.xlsx">模板下载</el-link>
                 </el-form-item>
@@ -221,6 +225,14 @@
                      :clearable="false" type="date" 
                      placeholder="选择日期"></el-date-picker>
                 </el-form-item>
+
+                <!--非建筑工程专业版设置 -->
+                <!-- <el-form-item label="日报审核权限" v-if="user.company.packageProject==1 && user.company.packageEngineering == 0">
+                    <el-radio-group v-model="addForm.taskGpIncharge" >
+                        <el-radio :label="0">由项目负责人审核</el-radio>
+                        <el-radio :label="1">由各任务分组负责人审核</el-radio>
+                    </el-radio-group>
+                </el-form-item> -->
                 
                 <!-- 项目基线 -->
                 <div style="margin: 10px 0 30px 0;min-height:200px;" v-if="user.company.packageProject == 1">
@@ -450,6 +462,14 @@
                 <el-button type="primary" @click="addPpMemb" >确定</el-button>
             </div>
         </el-dialog>
+
+        <!-- <el-dialog title="提示"  v-if="deleteReconfirmDialog" :visible.sync="deleteReconfirmDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
+            <p>{{deleteAlertMsg}}</p>
+            <div slot="footer" class="dialog-footer">
+                <el-button  @click="deleteReconfirmDialog = false" >取消</el-button>
+                <el-button type="primary" @click="forceDeletePro" >确认并删除</el-button>
+            </div>
+        </el-dialog> -->
     </section>
 </template>
 <style scoped>
@@ -484,6 +504,7 @@ a {
     export default {
         data() {
             return {
+                deleteAlertMsg: null,
                 chosenLeaders:[],
                 chooseLeaderVisible:false,
                 projectProfessionItem:null,
@@ -547,6 +568,7 @@ a {
                     name: '',
                     userId: [],
                     level:1,
+                    taskGpIncharge: 0
                 },
                 rules: {
                     name: [{ required: true, message: "请输入名称", trigger: "blur" }],
@@ -578,6 +600,27 @@ a {
             }
         },
         methods: {
+            exportProjectData() {
+                //导出项目
+                this.http.post('/project/exportData',{},
+                res => {
+                    if (res.code == "ok") {
+                        var filePath = res.data;
+                        const a = document.createElement('a'); // 创建a标签
+                        a.setAttribute('download', '项目导出.xls');// download属性
+                        a.setAttribute('href', filePath);// href链接
+                        a.click(); //自执行点击事件
+                        a.remove();
+                    } 
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                    }
+                );
+            },
             userssHu() {
                 this.http.post('/time-type/getCompanyTimeSetting',{ 
                     companyId: this.user.companyId
@@ -1370,6 +1413,7 @@ a {
                         customerId:null,
                         notifyUserNames:'',
                         chosenLeaders:[],
+                        taskGpIncharge: 0,
                     }
                     this.projectBaseCostData = [];
                     this.auseList = [];
@@ -1411,6 +1455,7 @@ a {
                         baseRisk2: item.baseRisk2,
                         baseOutsourcing: item.baseOutsourcing,
                         customerId:item.customerId==0?null:item.customerId,
+                        taskGpIncharge: item.taskGpIncharge
                     }
                     console.log(item.associateDegrees)
                     if(item.associateDegrees != null && item.associateDegrees != 'null' && item.associateDegrees != '') {
@@ -1599,6 +1644,8 @@ a {
                         listName.toString()
                         formData.append("associateDegrees", listId)
                         formData.append("associateDegreeNames", listName)
+                        formData.append("taskGpIncharge", this.addForm.taskGpIncharge)
+                        
                         this.http.uploadFile(this.port.project.add,formData,
                         res => {
                             this.addLoading = false;
@@ -1632,7 +1679,7 @@ a {
 
             // 删除
             deletePro(i, item) {
-                this.$confirm("确定要项目" + item.projectName + "吗?","删除项目", {
+                this.$confirm("确定要删除项目[" + item.projectName + "]吗?","删除项目", {
                     confirmButtonText: "确定",
                     cancelButtonText: "取消",
                     type: "warning"
@@ -1642,6 +1689,47 @@ a {
                     this.http.post(this.port.project.delete,{ 
                         id: item.id 
                     },
+                    res => {
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: "删除成功",
+                                type: "success"
+                            });
+                            this.getList();
+                        } else if (res.code == 'reconfirm') {
+                            this.deleteAlertMsg = res.msg;
+                            this.forceDeletePro(item.id);
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+                })
+                .catch(() => {});
+            },
+            //强制删除项目
+            forceDeletePro(deleteProId) {
+                this.$confirm(this.deleteAlertMsg,"删除项目", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning"
+                })
+                .then(() => {
+                    this.listLoading = true;
+                    this.http.post(this.port.project.delete,{ 
+                        id: deleteProId ,force:1
+                    },
                     res => {
                         this.listLoading = false;
                         if (res.code == "ok") {

+ 47 - 2
fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue

@@ -44,8 +44,12 @@
                                         <el-dropdown-item divided @click.native="addToTemplate(item)">
                                             <i class="el-icon-plus"></i>
                                             设为模板</el-dropdown-item>
+                                        <el-dropdown-item divided @click.native="editIncharger(item)">
+                                            <i class="el-icon-user"></i>
+                                            设负责人</el-dropdown-item>
                                         <el-dropdown-item divided @click.native="deleteGroup(item)">
-                                            <i class="el-icon-delete"></i>删除分组</el-dropdown-item>
+                                            <i class="el-icon-delete"></i>
+                                            删除分组</el-dropdown-item>
                                     </el-dropdown-menu>
                                 </el-dropdown>
                                 </div>
@@ -569,6 +573,18 @@
                 </el-tabs>
             </div>
         </el-dialog>
+        <el-dialog title="设置任务分组负责人" v-if="setInchargerDialog" :visible.sync="setInchargerDialog" :close-on-click-modal="false" customClass="customWidth" width="300px">
+            <el-form ref="formIncharger" :model="groupForm" :rules="rules" style="margin-top:10px;">
+                    <el-form-item prop="taskGpIncharge">
+                        <el-select v-model="groupForm.inchargerId" placeholder="请选择任务分组负责人" style="width:100%;" clearable filterable>
+                            <el-option v-for="item in joinMembList" :key="item.id" :value="item.id" :label="item.name"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="saveGroupIncharger" style="width:100%;" >保存</el-button>
+            </div>
+        </el-dialog>
         <el-dialog title="修改任务分组" v-if="modGroupDialog" :visible.sync="modGroupDialog" :close-on-click-modal="false" customClass="customWidth" width="300px">
             <el-form ref="form2" :model="groupForm" :rules="rules" style="margin-top:10px;">
                     <el-form-item prop="name">
@@ -676,6 +692,8 @@
         
         data() {
             return {
+                joinMembList:[],
+                setInchargerDialog: false,
                 recentProgressInfo:{},
                 addToTmpDialog:false,
                 templateForm:{},
@@ -813,6 +831,28 @@
             
         },
         methods: {
+            //保存分组负责人
+            saveGroupIncharger() {
+                this.http.post('/task-group/saveGroupIncharger', {id: this.groupForm.id, inchargerId: this.groupForm.inchargerId},
+                        res => {
+                            this.setInchargerDialog = false;
+                            if (res.code == "ok") {
+                                this.$message({
+                                    message: '设置成功',
+                                    type: "success"
+                                });
+                                //更新原始分组数据
+                                this.groupList.filter(g=>g.id == this.groupForm.id)[0].inchargerId = this.groupForm.inchargerId;
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        }
+                    );
+                
+            },
             //删除模板
             deleteTemplate(t) {
                 var that = this;
@@ -1590,6 +1630,10 @@
                     this.groupList = this.allGroupData;
                 }
             },
+            editIncharger(item) {
+                this.groupForm = JSON.parse(JSON.stringify(item));
+                this.setInchargerDialog = true;
+            },
             renameGroup(item) {
                 this.groupForm = JSON.parse(JSON.stringify(item));
                 this.modGroupDialog = true;
@@ -1679,7 +1723,7 @@
                         this.addGroupDialog = false;
                         this.modGroupDialog = false;
                         if (this.selectedGroup.id !== this.groupForm.id) {
-                            this.selectedGroup = this.groupForm;
+                            this.selectedGroup = this.groupList.filter(g=>g.new)[0];
                         }
                         this.defaultGroupId = this.groupList[this.groupList.length - 1].id
                         // this.getTaskGroup();
@@ -1999,6 +2043,7 @@
                 res => {
                     if (res.code == "ok") {
                         this.currentProject = res.data;
+                        this.joinMembList = this.currentProject.participationList;
                     } else {
                     }
                 },

+ 136 - 87
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -155,7 +155,10 @@
                                                 <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="item2.groupId != 0">任务分组:{{item2.groupName}} <span v-if="item2.stage != null && item2.stage != '-'" style="margin-left:10px;">投入阶段:{{item2.stage}}</span></p>
+                                            <p v-if="user.timeType.customDegreeActive==1 && item2.degree_id != null && item2.degree_id != -1">{{user.timeType.customDegreeName}}:{{item2.degreeName}}</p>
+
                                             <p v-if="user.company.packageEngineering == 1">
                                                 专业进度:
                                                 <span style="margin-right:10px;" v-for="progressItem in item2.professionProgress" :key="progressItem.id">{{progressItem.professionName}}({{progressItem.progress}}%) 
@@ -178,8 +181,6 @@
                                                 <span v-if="item2.reportTimeType == 2" style="margin-right:10px;">{{item2.startTime+'-'+item2.endTime}}</span>
                                             {{item2.time.toFixed(1)}}h  
                                             <el-tag type="danger" size="mini" style="margin-left: 65px" v-if="item2.isOvertime === 1">加班</el-tag>
-                                            <!-- 阶段 -->
-                                            <span v-if="item2.stage != null" style="margin-left:10px;"> 投入阶段:{{item2.stage}}</span>
                                             </p>
                                             <p>事项:<span v-html="item2.content"></span></p>
                                             </div>
@@ -294,41 +295,50 @@
                     
                     <el-form-item label="投入项目" :prop="'domains.' + index + '.projectId'"
                         :rules="{ required: true, message: '请选择投入项目', trigger: ['change','blur'] }">
-                        <el-select v-model="domain.projectId" placeholder="请选择" style="width:200px;" clearable="true"  filterable="true"
+                        <el-select v-model="domain.projectId" placeholder="请选择项目" style="width:200px;" clearable="true"  filterable="true"
                         @change="selectProject(domain, index)"
                         :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
                             <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id"></el-option>
                         </el-select>
+                        <span  v-if="domain.subProjectList != null && domain.subProjectList.length> 0"
+                            style="margin-left:45px;">子项目</span>
                         <!--子项目 -->
-                        <el-select v-model="domain.subProjectId" placeholder="请选择" style="width:200px;" clearable="true" v-if="domain.subProjectList != null && domain.subProjectList.length> 0"
-                        :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
+                        <el-select v-model="domain.subProjectId" placeholder="请选择子项目" style="width:200px;margin-left:10px;" clearable="true"
+                            v-if="domain.subProjectList != null && domain.subProjectList.length> 0"
+                        :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)" @change="updateSubProject">
                             <el-option v-for="item in domain.subProjectList" :key="item.id" :label="item.name" :value="item.id"></el-option>
                         </el-select>
-                        <!-- 项目的阶段 -->
-                        <span v-if="user.company.packageProject == 1 && domain.stages != null && domain.stages.length> 0" 
-                            style="margin-left:30px;">投入阶段</span>
-                        <el-select v-model="domain.stage" placeholder="请选择" style="width:200px;margin-left:10px;" 
-                        clearable="true" v-if="user.company.packageProject == 1 && domain.stages != null && domain.stages.length> 0"
-                        @change="changeStages(domain, index)"
-                        :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
-                            <el-option v-for="item in domain.stages" :key="item" :label="item" :value="item"></el-option>
-                        </el-select>
 
                         <el-link v-if="index >= 1" type="primary" :underline="false" @click="delDomain(index)" style="float:right;margin-right:10px;"
                             :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
                             <i class="fa fa-trash" style="color: red;;font-size:18px;"></i>
                         </el-link>
                         <el-link type="primary" v-if="workForm.domains[index].state == 0 || workForm.domains[index].state == 2"
-                             :underline="false" style="margin-left:5px;" @click="copyProject(index)">复制</el-link>
+                            :underline="false" style="margin-left:10px;" @click="copyProject(index)">复制</el-link>
+                    </el-form-item>
+                    <el-form-item label="任务分组" v-if="user.company.packageProject == 1">
+                        <!-- 任务分组 -->
+                        <el-select v-model="domain.groupId" placeholder="请选择任务分组" style="width:200px;" clearable="true" 
+                        :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)" @change="getGroupStages(domain, index)">
+                            <el-option v-for="item in domain.taskGroups" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                        </el-select>
+                        <!-- 项目的阶段 -->
+                        <span v-if="domain.stages != null && domain.stages.length> 0" 
+                            style="margin-left:30px;">投入阶段</span>
+                        <el-select v-model="domain.stage" placeholder="请选择" style="width:200px;margin-left:10px;" 
+                        clearable="true" v-if="domain.stages != null && domain.stages.length> 0"
+                        @change="changeStages(domain, index)"
+                        :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
+                            <el-option v-for="item in domain.stages" :key="item.id" :label="item.stagesName" :value="item.stagesName"></el-option>
+                        </el-select>
                     </el-form-item>
                     <!-- 相关维度 -->
                     <el-form-item :label="yonghuUser.customDegreeName" v-if="domain.projectId && yonghuUser.customDegreeActive == 1">
-                            <el-select v-model="domain.degreeId" clearable placeholder="请选择">
-                                <el-option v-for="item in domain.wuduList" :key="item.value" :label="item.name" :value="item.id">
-                                </el-option>
-                            </el-select>
-                        </el-form-item>
-                    <!-- </el-form-item> -->
+                        <el-select v-model="domain.degreeId" clearable placeholder="请选择">
+                            <el-option v-for="item in domain.wuduList" :key="item.value" :label="item.name" :value="item.id">
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
 
                     <el-form-item v-if="reportTimeType.type == 3" label="用时占比" :prop="'domains.' + index + '.'+timeFields[reportTimeType.type]"
                         :rules="{ required: true, message: '请设置用时占比', trigger: 'blur' }">
@@ -363,32 +373,44 @@
                     <div v-if="reportTimeType.multiWorktime==1">
                         <el-form-item label="投入项目" :prop="'domains.' + index + '.projectId'"
                             :rules="{ required: true, message: '请选择投入项目', trigger: ['change','blur'] }">
-                            <el-select v-model="domain.projectId" placeholder="请选择" style="width:200px;" clearable="true"  filterable="true"
+                            <el-select v-model="domain.projectId" placeholder="请选择项目" style="width:200px;" clearable="true"  filterable="true"
                             @change="selectProject(domain, index)"
                             :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
                                 <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id"></el-option>
                             </el-select>
+                            <span  v-if="domain.subProjectList != null && domain.subProjectList.length> 0"
+                                style="margin-left:45px;">子项目</span>
                             <!--子项目 -->
-                            <el-select v-model="domain.subProjectId" placeholder="请选择" style="width:200px;" clearable="true" v-if="domain.subProjectList != null && domain.subProjectList.length> 0"
-                            :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
+                            <el-select v-model="domain.subProjectId" placeholder="请选择子项目" style="width:200px;margin-left:10px;" clearable="true"
+                             v-if="domain.subProjectList != null && domain.subProjectList.length> 0"
+                            :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)" @change="updateSubProject">
                                 <el-option v-for="item in domain.subProjectList" :key="item.id" :label="item.name" :value="item.id"></el-option>
                             </el-select>
-                            <!-- 项目的阶段 -->
-                            <span v-if="user.company.packageProject == 1 && domain.stages != null && domain.stages.length> 0" 
-                                style="margin-left:30px;">投入阶段</span>
-                            <el-select v-model="domain.stage" placeholder="请选择" style="width:200px;margin-left:10px;" clearable="true" v-if="user.company.packageProject == 1 && domain.stages != null && domain.stages.length> 0"
-                                @change="changeStages(domain, index)"
-                            :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
-                                <el-option v-for="item in domain.stages" :key="item" :label="item" :value="item"></el-option>
-                            </el-select>
 
                             <el-link v-if="index >= 1" type="primary" :underline="false" @click="delDomain(index)" style="float:right;margin-right:10px;"
                                 :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
                                 <i class="fa fa-trash" style="color: red;;font-size:18px;"></i>
                             </el-link>
                             <el-link type="primary" v-if="workForm.domains[index].state == 0 || workForm.domains[index].state == 2"
-                                :underline="false" style="margin-left:5px;" @click="copyProject(index)">复制</el-link>
+                                :underline="false" style="margin-left:10px;" @click="copyProject(index)">复制</el-link>
                         </el-form-item>
+                        <el-form-item label="任务分组" v-if="user.company.packageProject == 1">
+                            <!-- 任务分组 -->
+                            <el-select v-model="domain.groupId" placeholder="请选择任务分组" style="width:200px;" clearable="true" 
+                            :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)" @change="getGroupStages(domain, index)">
+                                <el-option v-for="item in domain.taskGroups" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                            </el-select>
+                            <!-- 项目的阶段 -->
+                            <span v-if="domain.stages != null && domain.stages.length> 0" 
+                                style="margin-left:30px;">投入阶段</span>
+                            <el-select v-model="domain.stage" placeholder="请选择" style="width:200px;margin-left:10px;" 
+                            clearable="true" v-if="domain.stages != null && domain.stages.length> 0"
+                            @change="changeStages(domain, index)"
+                            :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
+                                <el-option v-for="item in domain.stages" :key="item.id" :label="item.stagesName" :value="item.stagesName"></el-option>
+                            </el-select>
+                        </el-form-item>
+                        
                         <!--工程专业版本模式下, 各个专业的进度填报 -->
                         <el-form-item label="专业进度" :prop="'domains.' + index + '.professionProgress'" v-if="user.company.packageEngineering==1">
                             <span v-for="item in domain.professionProgress" :key="item.professionId" style="margin-right:10px;">
@@ -474,8 +496,8 @@
             <span slot="footer" class="dialog-footer">
                 <el-button @click="deleteReport" v-if="workForm.domains[0].id != null">删除</el-button>
                 <el-button @click="dialogVisible = false">取消</el-button>
-                <el-button @click="submitDepartment(1)" :disabled="workForm.domains.length==0?true:(canEdit?false:true)">暂存</el-button>
-                <el-button type="primary" @click="submitDepartment(0)"
+                <el-button v-if="!isSubstitude" @click="submitReport(1)" :disabled="workForm.domains.length==0?true:(canEdit?false:true)">暂存</el-button>
+                <el-button type="primary" @click="submitReport(0)"
                 :disabled="workForm.domains.length==0?true:(canEdit?false:true)" >提交</el-button>
             </span>
         </el-dialog>
@@ -718,7 +740,7 @@
             <p>2. 填写excel模板,请确保模板中的项目和人员已添加到系统中。</p>
             <p style="display: flex;justify-content: center;">
                 <el-upload ref="upload"  action="#" :limit="1" :http-request="batchImportData" :show-file-list="false">
-                <el-button type="primary" :underline="false" >开始导入</el-button>
+                <el-button type="primary" :underline="false" :loading="importingData">开始导入</el-button>
             </el-upload>
             </p>
         </el-dialog>
@@ -819,6 +841,17 @@
                 </el-table-column>
                 </el-table>
         </el-dialog>
+        <!--基于企业微信考勤数据的工时导入 -->
+        <el-dialog title="工时导入结果" v-if="showImportResult" :visible.sync="showImportResult" customClass="customWidth" width="500px">
+            <div>
+                <span>{{importResultMsg}}</span>
+                
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="showImportResult=false">确定</el-button>
+            </span>
+        </el-dialog>
+        
     </section>
 </template>
 
@@ -828,6 +861,9 @@
     export default {
         data() {
             return {
+                importResultMsg:null,
+                showImportResult:false,
+                importingData: false,
                 isDraft: 0,
                 timeStamp: 0,
                 projectColumns:[],
@@ -983,6 +1019,26 @@
             }
         },
         methods: {
+            //获取项目下的任务分组
+            getTaskGroups(domain, index) {
+                this.workForm.domains[index].groupId=null;
+                this.http.post('/task-group/list',{ 
+                    projectId: domain.projectId
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.workForm.domains[index].taskGroups = res.data;
+                        this.$forceUpdate();
+                    } 
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                    }
+                );
+            },
             //下载带企业微信考勤数据的工时统计模板
             downloadCheckInExcel() {
                 this.http.post('/user-corpwx-time/exportCheckInExcel',{ 
@@ -1138,26 +1194,22 @@
                         type: "error"
                     });
                 } else {
-                    this.listLoading = true;
+                    this.importingData = true;
                     let formData = new FormData();
                     formData.append("file", item.file);
                     formData.append("companyId", this.user.companyId);
                     this.http.uploadFile('/report/importData', formData,
                     res => {
                         this.$refs.upload.clearFiles();
-                        this.listLoading = false;
+                        this.importingData = false;
+                        this.showImportResult = true;
                         if (res.code == "ok") {
-                            this.$message({
-                                message: "成功导入"+res.data+"名人员的工时数据",
-                                type: "success"
-                            });
+                            //换成弹出框,以免有人等了半天回来啥也没看到
+                            this.importResultMsg = "成功导入"+res.data+"条工时数据";
                             this.getReportList();
                             this.importDialog = false;
                         } else {
-                            this.$message({
-                                message: res.msg,
-                                type: "error"
-                            });
+                            this.importResultMsg = "导入失败:"+res.msg;
                         }
                     },
                     error => {
@@ -1588,6 +1640,9 @@
                 this.isNew = this.selected
                 
             },
+            updateSubProject() {
+                this.$forceUpdate();
+            },
             //项目选中了, 加载子项目
             selectProject(domain, index) {
                 console.log(domain, index, '加载')
@@ -1595,8 +1650,11 @@
                     projectId: domain.projectId
                 },
                 res => {
+                    //清空之前选中的子项目
+                    // this.workForm.domains[index].subProjectId = 0;
                     if (res.code == "ok") {
                         this.workForm.domains[index].subProjectList = res.data;
+                        this.workForm.domains[index].subProjectId = null;
                         this.$forceUpdate();
                     } 
                 },
@@ -1632,13 +1690,13 @@
                 if (this.user.company.packageEngineering == 1) {
                     this.getProjectProfessions(domain, index);
                 }
-                //获取项目相关的任务阶段
-                if (this.user.company.packageProject == 1) {
-                    this.getProjectStages(domain, index);
-                }
+                
                 // 获取项目相关的维度
-                this.dimension(domain, index)
+                this.dimension(domain, index);
+                //获取项目下的任务分组
+                this.getTaskGroups(domain, index);
             },
+            
             // 获取维度数据
             dimension(domain, index) {
                 if(domain.projectId == '') {
@@ -1669,12 +1727,14 @@
                 } else {
                     this.workForm.domains[index].taskList = this.workForm.domains[index].allTaskList.filter(t=>t.stagesName == domain.stage);
                 }
+                this.$forceUpdate();
             },
 
-            getProjectStages(domain, index) {
-                this.http.post("/stages/getProjectStages", {projectId: domain.projectId},
+            getGroupStages(domain, index) {
+                this.http.post("/stages/getProjectStagesByGroup", {groupId: domain.groupId},
                     res => {
                         if (res.code == "ok") {
+                            this.workForm.domains[index].stage = '';
                             this.workForm.domains[index].stages = res.data;
                             this.$forceUpdate();
                         }
@@ -2392,16 +2452,6 @@
                             for(var i in list.report) {
                                 var flg = null
                                 list.report[i].isOvertime == 1 ? flg = true : flg = false
-                                // var srr = []
-                                // if(list.report[i].degreeId != null) {
-                                //     var a = list.report[i].degreeId + ''
-                                //     var ace = a.split('')
-                                //     for(var b in ace) {
-                                //         var nnm = +ace[b] + 0
-                                //         srr.push(nnm)
-                                //     }
-                                // }
-                                
                                 arr.push({
                                     id: list.report[i].id,
                                     projectId: list.report[i].projectId,
@@ -2411,7 +2461,8 @@
                                     timeType: list.report[i].timeType,
                                     subProjectList: list.report[i].subProjectList,
                                     taskList: list.report[i].taskList,
-                                    subProjectId: list.report[i].subProjectId,
+                                    subProjectId: list.report[i].subProjectId == 0?null:list.report[i].subProjectId,
+                                    groupId: list.report[i].groupId == 0?null:list.report[i].groupId,
                                     taskId: list.report[i].taskId,
                                     // startTime: `Fri May 16 2021 ${list.report[i].startTime}:12 GMT+0800 (中国标准时间)`,
                                     startTime: list.report[i].startTime,
@@ -2421,12 +2472,13 @@
                                     progress:list.report[i].progress,
                                     professionProgress: list.report[i].professionProgressList,
                                     stages:list.report[i].stages,
-                                    stage:list.report[i].stage,
+                                    stage:list.report[i].stage == '-'?null:list.report[i].stage,
                                     pics: list.report[i].pics,
                                     multiWorktime: list.report[i].multiWorktime,
                                     worktimeList: list.report[i].worktimeList,
-                                    degreeId: list.report[i].degreeId,
+                                    degreeId: list.report[i].degreeId==-1?null:list.report[i].degreeId,
                                     wuduList: list.report[i].degreeList,
+                                    taskGroups:list.report[i].taskGroups
                                 })
                                 if (list.report[i].state >= 2) {
                                     this.canEdit = true;
@@ -3186,7 +3238,7 @@
             },
 
             // 保存日报
-            submitDepartment(isDraft) {
+            submitReport(isDraft) {
                 this.isDraft = isDraft;
                 this.$refs.workForm.validate(valid => {
                     if (valid) {
@@ -3317,20 +3369,25 @@
                                 // var sss = this.workForm.domains[i].degreeId.toString()
                                 formData.append("degreeId", this.workForm.domains[i].degreeId);
                             } else {
-                                formData.append("degreeId", "-1");
+                                formData.append("degreeId", -1);
                             }
-                            if (this.workForm.domains[i].id != null) {
+                            if (this.workForm.domains[i].id) {
                                 formData.append("id", this.workForm.domains[i].id);
                             } else {
                                 formData.append("id", -1);
                             }
                             formData.append("projectId", this.workForm.domains[i].projectId);
-                            if (this.workForm.domains[i].subProjectId != null) {
+                            if (this.workForm.domains[i].subProjectId) {
                                 formData.append("subProjectId", this.workForm.domains[i].subProjectId);
                             } else {
                                 formData.append("subProjectId", 0);
                             }
-                            if (this.workForm.domains[i].taskId != null) {
+                            if (this.workForm.domains[i].groupId) {
+                                formData.append("groupId", this.workForm.domains[i].groupId);
+                            } else {
+                                formData.append("groupId", 0);
+                            }
+                            if (this.workForm.domains[i].taskId) {
                                 formData.append("taskId", this.workForm.domains[i].taskId);
                             } else {
                                 formData.append("taskId", 0);
@@ -3386,7 +3443,7 @@
                                 m = m.replace(/,/g,"@");//replaceAll(',','@');企业微信不兼容replaceAll
                                 formData.append("content", m);
                             } else {
-                                if (this.workForm.domains[i].content == null || this.workForm.domains[i].content == '') {
+                                if (this.workForm.domains[i].content) {
                                     formData.append("content", '-');
                                 } else {
                                     formData.append("content", this.workForm.domains[i].content);
@@ -3400,14 +3457,11 @@
                                 formData.append("createDate", this.workForm.createDate[0]+'@'+this.workForm.createDate[1]);
                             }
                             
-                            if(this.workForm.domains[i].isOvertime == undefined ) {
-                                this.workForm.domains[i].isOvertime = '0'
-                                formData.append("isOvertime", this.workForm.domains[i].isOvertime);
-                            } else if (this.workForm.domains[i].isOvertime == false){
-                                this.workForm.domains[i].isOvertime = '0'
+                            if(this.workForm.domains[i].isOvertime) {
+                                this.workForm.domains[i].isOvertime = '1'
                                 formData.append("isOvertime", this.workForm.domains[i].isOvertime);
                             } else {
-                                this.workForm.domains[i].isOvertime = '1'
+                                this.workForm.domains[i].isOvertime = '0'
                                 formData.append("isOvertime", this.workForm.domains[i].isOvertime);
                             }
                             
@@ -3422,24 +3476,19 @@
                                 }
                             }
                             //项目专业进度
-                            if (this.workForm.domains[i].professionProgress != null) {
+                            if (this.workForm.domains[i].professionProgress) {
                                 var m = JSON.stringify(this.workForm.domains[i].professionProgress);
-                                
                                 m = m.replace(/,/g,"@");//replaceAll(',','@');企业微信不兼容replaceAll
-                                
                                 formData.append("professionProgress", m);
                             } else {
                                 formData.append("professionProgress", "[]");
                             }
-                            if (this.workForm.domains[i].stage != null) {
+                            if (this.workForm.domains[i].stage) {
                                 formData.append("stage", this.workForm.domains[i].stage);
                             } else {
-                                formData.append("stage", "");
+                                formData.append("stage", "-");
                             }
                         }
-                        // formData.forEach((value, key) => {
-                        //     })
-                        // return
                         this.http.uploadFile( this.port.report.editPort, formData,
                         res => {
                             this.listLoading = false;

+ 1 - 0
fhKeeper/formulahousekeeper/timesheet_h5/src/views/audit/audit.vue

@@ -10,6 +10,7 @@
             <div class="lis_con" v-for="items in item.data" :key="items.id">
                 <div>工作日期: {{item.dateStr}}</div>
                 <div>项目: {{items.project}}</div>
+                <div v-if="items.subProjectName">子项目: {{items.subProjectName}}</div>
                 <div>工作时长: {{items.time}}h</div>
             </div>
             <div class="lis_boot">

+ 136 - 28
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -37,14 +37,33 @@
                         :value="item.subProjectName" label="子项目" placeholder="请选择子项目" 
                     @click="clickPickSubProject(index, item)" />
 
-                    <van-popup v-model="showPickerSubProject" position="bottom">
+                    <van-popup v-model="item.showPickerSubProject" position="bottom">
                         <van-picker show-toolbar :columns="item.subProjectList" value-key="name" @confirm="choseSubProject" 
-                            @cancel="showPickerSubProject = false" />
+                            @cancel="item.showPickerSubProject = false;$forceUpdate();" />
                     </van-popup>
+                    <!--任务分组 -->
+                    <van-field  readonly  name="groupId" v-if="user.company.packageProject==1&&item.taskGroups != null && item.taskGroups.length > 0" clickable 
+                        :value="item.groupName" label="任务分组" placeholder="请选择任务分组" 
+                    @click="clickPickTaskGroup(index, item)" />
+
+                    <van-popup v-model="item.showPickerTaskGroup" position="bottom">
+                        <van-picker show-toolbar :columns="item.taskGroups" value-key="name" @confirm="choseTaskGroup" 
+                            @cancel="item.showPickerTaskGroup = false;$forceUpdate();" />
+                    </van-popup>
+                    <!--任务阶段 -->
+                    <van-field  readonly  name="stage" v-if="user.company.packageProject==1&&item.stages != null && item.stages.length > 0" clickable 
+                        :value="item.stage" label="投入阶段" placeholder="请选择投入阶段" 
+                    @click="clickPickStage(index, item)" />
+
+                    <van-popup v-model="item.showPickerStage" position="bottom">
+                        <van-picker show-toolbar :columns="item.stages" value-key="stagesName" @confirm="choseStage" 
+                            @cancel="item.showPickerStage = false;$forceUpdate();" />
+                    </van-popup>
+
                     <!-- 相关维度 -->
                     <van-field :value="item.weiduName" v-if="item.projectId && user.timeType.customDegreeActive == 1"  readonly  name="id" clickable :label="user.timeType.customDegreeName" placeholder="请选择" @click="clickPickers(index)"/>
-                    <van-popup v-model="showPickerProjects" position="bottom">
-                        <van-picker show-toolbar :columns="item.wuduList" value-key="name" @confirm="choseProjects" @cancel="showPickerProjects = false" />
+                    <van-popup v-model="item.showPickDegree" position="bottom">
+                        <van-picker show-toolbar :columns="item.wuduList" value-key="name" @confirm="choseProjects" @cancel="item.showPickDegree = false;$forceUpdate()" />
                     </van-popup>
 
                     <van-cell title="专业进度" v-if="user.company.packageEngineering == 1">
@@ -60,8 +79,8 @@
                     </van-field>
                     <van-field v-if="user.company.packageProject == 1"  readonly name="taskId" :value="item.taskName" label="关联任务" placeholder="请选择关联任务" @click="clickPickerTask(index)"
                     />
-                    <van-popup v-model="showPickerTask" position="bottom">
-                        <van-picker show-toolbar :columns="item.taskList" value-key="taskName" @confirm="choseTask" @cancel="showPickerTask = false" />
+                    <van-popup v-model="item.showPickerTask" position="bottom">
+                        <van-picker show-toolbar :columns="item.taskList" value-key="taskName" @confirm="choseTask" @cancel="item.showPickerTask = false;$forceUpdate()" />
                     </van-popup>
                     <!-- <van-field readonly clickable class="form_input" :value="item.workingTime" name="workingTime" label="工作时长" placeholder="请输入工作时长(单位:小时)"
                     :rules="[{ required: true, message: '请输入工作时长(单位:小时)' }]" @touchstart.native.stop="showNumberKey = true"/>
@@ -255,6 +274,9 @@
     export default {
         data() {
             return {
+
+                showPickerStage: false,
+                showPickerTaskGroup: false,
                 showPickerSubProject: false,
                 isDraft:0,
                 showWorkStartTime:false,
@@ -283,7 +305,7 @@
                 showPickerTime: false,
                 showPicker: false,
                 showPickerProject: false,
-                showPickerProjects: false,
+                showPickDegree: false,
                 clickIndex: 0,
                 clickTimeIndex: 0,
                 showNumberKey: false,
@@ -366,6 +388,9 @@
                 //清空任务
                 domainItem.taskId = null;
                 domainItem.taskName = null;
+                //清空分组和阶段
+                domainItem.stage = null;
+                domainItem.groupId = null;
 
                 this.showPickerUserddp = false;
                 //获取子项目
@@ -375,9 +400,23 @@
                 if (this.user.company.packageEngineering == 1){
                     this.getProjectProfessions(this.form.domains[this.proIdx],index);
                 }
+                //获取任务分组
+                this.getTaskGroups(this.form.domains[this.proIdx], this.proIdx);
+
                 // 获取1相关维度
-                var proId = this.form.domains[this.clickIndex].projectId
-                this.getTaskList(proId)
+                this.getTaskList(domainItem.projectId)
+
+            },
+            //获取项目下的任务分组
+            getTaskGroups(domainItem, index) {
+                domainItem.groupId=null;
+                this.$axios.post("/task-group/list", {projectId: domainItem.projectId})
+                    .then(res => {
+                        if(res.code == "ok") {
+                            domainItem.taskGroups = res.data;
+                        } 
+                        this.$forceUpdate();
+                    }).catch(err=> {toast.clear();});
             },
             getSubprojectList(domainItem) {
                 domainItem.subProjectList = [];
@@ -740,7 +779,7 @@
                                 }
                                 
                                 var subProjectName = null;
-                                if (list[i].subProjectId != null) {
+                                if (list[i].subProjectId != 0) {
                                     subProjectName = list[i].subProjectList.filter(s=>s.id==list[i].subProjectId)[0].name;
                                 }
                                 
@@ -771,7 +810,12 @@
                                     degreeId: list[i].degreeId,
                                     subProjectId: list[i].subProjectId,
                                     subProjectName: subProjectName,
-                                    subProjectList: list[i].subProjectList
+                                    subProjectList: list[i].subProjectList,
+                                    groupId: list[i].groupId == 0?null:list[i].groupId,
+                                    groupName: list[i].groupName,
+                                    taskGroups:list[i].taskGroups,
+                                    stages:list[i].stages,
+                                    stage:list[i].stage == '-'?null:list[i].stage,
                                 })
                                 if (list[i].state >= 2) {
                                     this.canEdit = true;
@@ -824,7 +868,20 @@
             clickPickSubProject(i, item) {
                 if (!this.canEdit) return;
                 this.clickIndex = i;
-                this.showPickerSubProject = true;
+                item.showPickerSubProject = true;
+                this.$forceUpdate();
+            },
+            clickPickTaskGroup(i, item) {
+                if (!this.canEdit) return;
+                this.clickIndex = i;
+                item.showPickerTaskGroup = true;
+                this.$forceUpdate();
+            },
+            clickPickStage(i, item) {
+                if (!this.canEdit) return;
+                this.clickIndex = i;
+                item.showPickerStage = true;
+                this.$forceUpdate();
             },
 
             // 选择项目
@@ -847,7 +904,7 @@
             clickPickers(i) {
                 if (!this.canEdit) return;
                 this.clickIndex = i;
-                this.showPickerProjects = true;
+                this.form.domains[this.clickIndex].showPickDegree = true;
                 var proId = this.form.domains[this.clickIndex].projectId
                 this.dimension(proId)
             },
@@ -857,26 +914,45 @@
                 this.clickIndex = i;
                 // var proId = this.form.domains[this.clickIndex].projectId
                 // this.getTaskList(proId)
-                this.showPickerTask = true;
+                this.form.domains[this.clickIndex].showPickerTask = true;
+                this.$forceUpdate();
             },
             choseTask(value, index) {
                 this.form.domains[this.clickIndex].taskId = value.taskId;
                 this.form.domains[this.clickIndex].taskName = value.taskName;
-                this.showPickerTask = false;
+                this.form.domains[this.clickIndex].showPickerTask = false;
+                this.$forceUpdate();
             },
 
             choseProjects(value, index) {
                 // console.log(value)
                 this.form.domains[this.clickIndex].weiduName = value.name;
                 this.form.domains[this.clickIndex].degreeId = value.id;
-                this.showPickerProjects = false;
+                this.form.domains[this.clickIndex].showPickDegree = false;
+                this.$forceUpdate();
             },
 
             choseSubProject(value, index) {
                 this.form.domains[this.clickIndex].subProjectId = value.id;
                 this.form.domains[this.clickIndex].subProjectName = value.name;
-                this.showPickerSubProject = false;
+                this.form.domains[this.clickIndex].showPickerSubProject = false;
+                this.$forceUpdate();
+
+                // this.getTaskList(value.id);
+                // this.dimension(value.id) // 获取维度
+                
+                // //加载项目相关的工程进度
+                // if (this.user.company.packageEngineering == 1) {
+                //     this.getProjectProfessions(this.form.domains[this.clickIndex], index);
+                // }
+            },
 
+            choseTaskGroup(value, index) {
+                this.form.domains[this.clickIndex].groupId = value.id;
+                this.form.domains[this.clickIndex].groupName = value.name;
+                this.form.domains[this.clickIndex].showPickerTaskGroup = false;
+                
+                this.getGroupStages(this.form.domains[this.clickIndex], index);
                 // this.getTaskList(value.id);
                 // this.dimension(value.id) // 获取维度
                 
@@ -885,6 +961,26 @@
                 //     this.getProjectProfessions(this.form.domains[this.clickIndex], index);
                 // }
             },
+            choseStage(value, index) {
+                this.form.domains[this.clickIndex].stage = value.stagesName;
+                this.form.domains[this.clickIndex].showPickerStage = false;
+                this.$forceUpdate();
+
+            },
+
+            getGroupStages(domain, index) {
+                this.$axios.post("/stages/getProjectStagesByGroup", {groupId: domain.groupId})
+                        .then(res => {
+                            if(res.code == "ok") {
+                                domain.stage = '';
+                                domain.stages = res.data;
+                                this.$forceUpdate();
+                            } else {
+                                this.$toast.fail('获取失败');
+                            }
+                        }).catch(err=> {toast.clear();});
+            },
+
 
             getProjectProfessions(domain, index) {
                 console.log(domain, '数据')
@@ -912,6 +1008,7 @@
                 }).catch(err=> {toast.clear();});
             },
 
+
             getTaskList(projectId) {
                 //如果是专业版,需要列出任务列表
                 if (this.user.company.packageProject == 1) {
@@ -1078,19 +1175,31 @@
                         } else {
                             formData.append("degreeId", -1);
                         }
+                    } else {
+                        formData.append("degreeId", -1);
                     }
                     
-                    if (this.form.domains[i].id != null) {
+                    if (this.form.domains[i].id) {
                         formData.append("id", this.form.domains[i].id);
                     } else {
                         formData.append("id", -1);
                     }
                     formData.append("projectId", parseFloat(this.form.domains[i].projectId));
-                    if (this.form.domains[i].subProjectId != null) {
+                    if (this.form.domains[i].subProjectId) {
                         formData.append("subProjectId", this.form.domains[i].subProjectId);
                     } else {
                         formData.append("subProjectId", 0);
                     }
+                    if (this.form.domains[i].groupId) {
+                        formData.append("groupId", this.form.domains[i].groupId);
+                    } else {
+                        formData.append("groupId", 0);
+                    }
+                    if (this.form.domains[i].stage) {
+                        formData.append("stage", this.form.domains[i].stage);
+                    } else {
+                        formData.append("stage", '-');
+                    }
                     formData.append("reportTimeType", this.reportTimeType.type);
                     formData.append("multiWorktime", this.reportTimeType.multiWorktime);
                     if (this.reportTimeType.type == 0) {
@@ -1106,17 +1215,16 @@
                         formData.append("workingTime",this.form.domains[i].workingTime);
                     }
                     
-                    
-                    if (this.form.domains[i].taskId == null) {
-                        formData.append("taskId", 0);
-                    } else {
+                    if (this.form.domains[i].taskId) {
                         formData.append("taskId", this.form.domains[i].taskId);
+                    } else {
+                        formData.append("taskId", 0);
                     }
                     formData.append("createDate", this.form.createDate);
                     formData.append("isOvertime", this.form.domains[i].isOvertime?1:0);
 
                     //项目专业进度
-                    if (this.form.domains[i].professionProgress != null) {
+                    if (this.form.domains[i].professionProgress) {
                         let m = JSON.stringify(this.form.domains[i].professionProgress);
                         m = m.replace(/,/g,"@");//replaceAll(',','@');企业微信不兼容replaceAll
                         formData.append("professionProgress", m);
@@ -1124,7 +1232,7 @@
                         formData.append("professionProgress", "[]");
                     }
                     //图片的处理,serverPic是当前所有的照片
-                    if (this.form.domains[i].serverPics!= null && this.form.domains[i].serverPics.length > 0) {
+                    if (this.form.domains[i].serverPics) {
                         let m = JSON.stringify(this.form.domains[i].serverPics);
                         m = m.replace(/,/g,"@");//replaceAll(',','@');企业微信不兼容replaceAll
                         formData.append("pics", m);
@@ -1164,10 +1272,10 @@
                         m = m.replace(/,/g,"@");//replaceAll(',','@');企业微信不兼容replaceAll
                         formData.append("content", m);
                     } else {
-                        if (this.form.domains[i].content == null || this.form.domains[i].content == '') {
-                            formData.append("content", '-');
-                        } else {
+                        if (this.form.domains[i].content) {
                             formData.append("content", this.form.domains[i].content);
+                        } else {
+                            formData.append("content", '-');
                         }
                     }
                 }

+ 7 - 2
fhKeeper/formulahousekeeper/timesheet_h5/src/views/review/department_list.vue

@@ -19,6 +19,11 @@
                             style="color:#DAA520;">{{item1.departmentAuditState==-1?'待专业审核':'待部门审核'}}</span>
                         </div>
                         <div class="project_title" v-if="item1.subProjectName != null" >子项目:{{item1.subProjectName}}</div>
+                        <div class="project_title" v-if="user.company.packageProject==1&&item1.groupName != null" >任务分组:{{item1.groupName}}</div>
+                        <div class="project_title" v-if="user.company.packageProject==1&&item1.stage != '-'" >投入阶段:{{item1.stage}}</div>
+                        <!--自定义维度 -->
+                        <div class="project_title" v-if="user.timeType.customDegreeActive == 1" >{{user.timeType.customDegreeName}}:{{item1.degreeName}}</div>
+                        
                         <div class="project_title" v-if="user.company.packageEngineering == 1">
                             专业进度:
                             <span style="margin-right:10px;" v-for="progressItem in item1.professionProgressList" :key="progressItem.id">{{progressItem.professionName}}({{progressItem.progress}}%) 
@@ -30,7 +35,7 @@
                         <div v-if="item1.multiWorktime == 0">
                             <div class="project_time">时长:
                                 <span v-if="item1.reportTimeType == 0" style="margin-right:10px;">{{fullDayTxt[item1.timeType]}}</span>
-                                <span v-if="item1.reportTimeType == 2" style="margin-right:10px;">{{item1.startTime+'-'+item1.endTime}}</span>{{item1.time}}h
+                                <span v-if="item1.reportTimeType == 2" style="margin-right:10px;">{{item1.startTime+'-'+item1.endTime}}</span>{{item1.time.toFixed(1)}}h
                                 <div class="button" v-if="item1.isOvertime == 1">加班</div>
                             </div>
                             <div class="project_content">事项:<span v-html="item1.content"></span></div>
@@ -40,7 +45,7 @@
                             <div style="position:relative;border:#ccc 0.5px solid;padding:3px;margin:5px 0px;" v-for="(timeItem, index) in item1.worktimeList" :key="index" >
                                 <div class="project_time">时长:
                                     <!-- <span v-if="timeItem.reportTimeType == 0" style="margin-right:10px;">{{fullDayTxt[item1.timeType]}}</span> -->
-                                    <span style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>{{timeItem.time}}h
+                                    <span style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>{{timeItem.time.toFixed(1)}}h
                                 </div>
                                 <div class="project_content">事项:<span v-html="timeItem.content"></span></div>
                             </div>

+ 7 - 2
fhKeeper/formulahousekeeper/timesheet_h5/src/views/review/index.vue

@@ -37,6 +37,11 @@
 
                         </div>
                         <div class="project_title" v-if="item1.subProjectName != null" >子项目:{{item1.subProjectName}}</div>
+                        <div class="project_title" v-if="user.company.packageProject==1&&item1.groupName != null" >任务分组:{{item1.groupName}}</div>
+                        <div class="project_title" v-if="user.company.packageProject==1&&item1.stage != '-'" >投入阶段:{{item1.stage}}</div>
+                        <!--自定义维度 -->
+                        <div class="project_title" v-if="user.timeType.customDegreeActive == 1" >{{user.timeType.customDegreeName}}:{{item1.degreeName}}</div>
+                        
                         <div class="project_title" v-if="user.company.packageEngineering == 1">
                             专业进度:
                             <span style="margin-right:10px;" v-for="progressItem in item1.professionProgressList" :key="progressItem.id">{{progressItem.professionName}}({{progressItem.progress}}%) 
@@ -48,7 +53,7 @@
                         <div v-if="item1.multiWorktime == 0">
                             <div class="project_time">时长:
                                 <span v-if="item1.reportTimeType == 0" style="margin-right:10px;">{{fullDayTxt[item1.timeType]}}</span>
-                                <span v-if="item1.reportTimeType == 2" style="margin-right:10px;">{{item1.startTime+'-'+item1.endTime}}</span>{{item1.time}}h
+                                <span v-if="item1.reportTimeType == 2" style="margin-right:10px;">{{item1.startTime+'-'+item1.endTime}}</span>{{item1.time.toFixed(1)}}h
                                 <div class="button" v-if="item1.isOvertime == 1">加班</div>
                             </div>
                             <div class="project_content">事项:<span v-html="item1.content"></span></div>
@@ -58,7 +63,7 @@
                             <div style="position:relative;border:#ccc 0.5px solid;padding:3px;margin:5px 0px;" v-for="(timeItem, index) in item1.worktimeList" :key="index" >
                                 <div class="project_time">时长:
                                     <!-- <span v-if="timeItem.reportTimeType == 0" style="margin-right:10px;">{{fullDayTxt[item1.timeType]}}</span> -->
-                                    <span style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>{{timeItem.time}}h
+                                    <span style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>{{timeItem.time.toFixed(1)}}h
                                 </div>
                                 <div class="project_content">事项:<span v-html="timeItem.content"></span></div>
                             </div>

+ 7 - 2
fhKeeper/formulahousekeeper/timesheet_h5/src/views/review/profession_list.vue

@@ -17,6 +17,11 @@
                     <div v-for="(item1,index1) in item.data" :key="index1" class="one_report_data">
                         <div class="project_title">项目:{{item1.project}}</div>
                         <div class="project_title" v-if="item1.subProjectName != null" >子项目:{{item1.subProjectName}}</div>
+                        <div class="project_title" v-if="user.company.packageProject==1&&item1.groupName != null" >任务分组:{{item1.groupName}}</div>
+                        <div class="project_title" v-if="user.company.packageProject==1&&item1.stage != '-'" >投入阶段:{{item1.stage}}</div>
+                        <!--自定义维度 -->
+                        <div class="project_title" v-if="user.timeType.customDegreeActive == 1" >{{user.timeType.customDegreeName}}:{{item1.degreeName}}</div>
+                        
                         <div class="project_title" v-if="user.company.packageEngineering == 1">
                             专业进度:
                             <span style="margin-right:10px;" v-for="progressItem in item1.professionProgressList" :key="progressItem.id">{{progressItem.professionName}}({{progressItem.progress}}%) 
@@ -28,7 +33,7 @@
                         <div v-if="item1.multiWorktime == 0">
                             <div class="project_time">时长:
                                 <span v-if="item1.reportTimeType == 0" style="margin-right:10px;">{{fullDayTxt[item1.timeType]}}</span>
-                                <span v-if="item1.reportTimeType == 2" style="margin-right:10px;">{{item1.startTime+'-'+item1.endTime}}</span>{{item1.time}}h
+                                <span v-if="item1.reportTimeType == 2" style="margin-right:10px;">{{item1.startTime+'-'+item1.endTime}}</span>{{item1.time.toFixed(1)}}h
                                 <div class="button" v-if="item1.isOvertime == 1">加班</div>
                             </div>
                             <div class="project_content">事项:<span v-html="item1.content"></span></div>
@@ -38,7 +43,7 @@
                             <div style="position:relative;border:#ccc 0.5px solid;padding:3px;margin:5px 0px;" v-for="(timeItem, index) in item1.worktimeList" :key="index" >
                                 <div class="project_time">时长:
                                     <!-- <span v-if="timeItem.reportTimeType == 0" style="margin-right:10px;">{{fullDayTxt[item1.timeType]}}</span> -->
-                                    <span style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>{{timeItem.time}}h
+                                    <span style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>{{timeItem.time.toFixed(1)}}h
                                 </div>
                                 <div class="project_content">事项:<span v-html="timeItem.content"></span></div>
                             </div>

+ 7 - 3
fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue

@@ -21,7 +21,7 @@
                         <!-- <span>系统智能统计:{{item.calculateTime}}h</span> -->
                     </div>
                     <div v-for="(item1,index1) in item.data" class="one_report_data" :key="index1">
-                        <div class="project_title">项目:{{item1.project}} <span :style="'color:'+statusColor[item1.state]">[
+                        <div class="project_title" style="font-weight:bold;">项目:{{item1.project}} <span :style="'color:'+statusColor[item1.state]">[
                             <span v-if="item1.state==0">
                             <span v-if="item1.isDeptAudit==0">
                                 <span v-if="item1.projectAuditState==0">
@@ -43,13 +43,17 @@
                             ] </span></div>
                         <div style="color:red;" v-if="item1.state ==2&&item1.rejectReason!=null">原因:{{item1.rejectReason}}</div>
                         <div class="project_title" v-if="item1.subProjectName != null" >子项目:{{item1.subProjectName}}</div>
+                        <div class="project_title" v-if="user.company.packageProject==1&&item1.groupName != null" >任务分组:{{item1.groupName}}</div>
+                        <div class="project_title" v-if="user.company.packageProject==1&&item1.stage != '-'" >投入阶段:{{item1.stage}}</div>
+                        <!--自定义维度 -->
+                        <div class="project_title" v-if="user.timeType.customDegreeActive == 1" >{{user.timeType.customDegreeName}}:{{item1.degreeName}}</div>
                         <div class="project_title" v-if="user.company.packageEngineering == 1">
                             专业进度:
                             <span style="margin-right:10px;" v-for="progressItem in item1.professionProgress" :key="progressItem.id">{{progressItem.professionName}}({{progressItem.progress}}%) 
                             </span>
                         </div>
                         
-                        <div class="project_title" v-if="item1.taskId != null" >任务:{{item1.taskName}}</div>
+                        <div class="project_title" v-if="item1.taskId" >任务:{{item1.taskName}}</div>
                         <!--根据类型选择使用的模板 -->
                         <div v-if="item1.multiWorktime == 0">
                             <div class="project_time">时长:
@@ -86,7 +90,7 @@
 
                     <!-- 编辑 -->
                     <div slot="footer" class="foot">
-                        <van-button size="small" type="default" @click="editor(item)" v-if="item.id == user.id && (item.state == 2 || item.state == 3)">编辑日报</van-button>
+                        <van-button size="small" type="primary" @click="editor(item)" v-if="item.id == user.id && (item.state == 2 || item.state == 3)">编辑日报</van-button>
                     </div>
                 </van-panel>
             </van-skeleton>

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

@@ -4,17 +4,17 @@ const path = require('path');
 const themePath = path.resolve(__dirname,'src/assets/style/theme.less');
 
 // var ip = '127.0.0.1'
-var ip = '192.168.2.159'
+// var ip = '192.168.2.159'
 // 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 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检查