Browse Source

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

QuYueTing 11 months ago
parent
commit
16bbe80afa
51 changed files with 2333 additions and 151 deletions
  1. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/index.vue
  2. 2 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/relatedBusiness.vue
  3. 19 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java
  4. 24 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  5. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportLogController.java
  6. 20 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java
  7. 87 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserGroupController.java
  8. 36 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserWorkbenchController.java
  9. 6 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/User.java
  10. 54 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/UserGroup.java
  11. 44 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/UserWorkbench.java
  12. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/UserVO.java
  13. 12 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectMapper.java
  14. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/UserGroupMapper.java
  15. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/UserWorkbenchMapper.java
  16. 7 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java
  17. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserGroupService.java
  18. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserService.java
  19. 19 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserWorkbenchService.java
  20. 235 17
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  21. 1 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  22. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserGroupServiceImpl.java
  23. 10 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  24. 73 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserWorkbenchServiceImpl.java
  25. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/MessageUtils.java
  26. 4 2
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  27. 230 5
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml
  28. 18 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserGroupMapper.xml
  29. 4 2
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserMapper.xml
  30. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserWorkbenchMapper.xml
  31. BIN
      fhKeeper/formulahousekeeper/management-platform/费用报销导入模板.xlsx
  32. 17 10
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/WxCorpInfoController.java
  33. 13 11
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java
  34. 17 6
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  35. 17 11
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/task/TimingTask.java
  36. 5 4
      fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/ReportMapper.xml
  37. 92 0
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/plan/orderInsert.vue
  38. 2 2
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/statistic/index.vue
  39. 5 0
      fhKeeper/formulahousekeeper/timesheet/src/components/echartsEchar.vue
  40. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/http.js
  41. 2 1
      fhKeeper/formulahousekeeper/timesheet/src/i18n/en.json
  42. 2 1
      fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json
  43. 5 0
      fhKeeper/formulahousekeeper/timesheet/src/permissions.js
  44. 4 0
      fhKeeper/formulahousekeeper/timesheet/src/routes.js
  45. 283 7
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/echartsData.js
  46. 189 49
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue
  47. 370 0
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/packetConsumption/tables.vue
  48. 7 3
      fhKeeper/formulahousekeeper/timesheet/src/views/project/info.vue
  49. 73 1
      fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue
  50. 231 0
      fhKeeper/formulahousekeeper/timesheet/src/views/userGrouping/userGrouping.vue
  51. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list.vue

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/index.vue

@@ -41,7 +41,7 @@
         </el-form-item>
         </el-form-item>
         <el-form-item label="联系人:" v-if="TASK_TYPE.find(v => v.value == (form.taskType || '1'))?.show">
         <el-form-item label="联系人:" v-if="TASK_TYPE.find(v => v.value == (form.taskType || '1'))?.show">
           <el-select v-model="form.contactsId" placeholder="请选择" clearable filterable
           <el-select v-model="form.contactsId" placeholder="请选择" clearable filterable
-            :disabled="(disabledList && disabledList.includes('contactsId'))">
+            :disabled="(disabledList && disabledList.includes('contactsId')) || !form[TASK_TYPE_FIELD[form.taskType].field]">
             <el-option v-for="item in contactValueData" :key="item.id" :value="item.id" :label="item.name" />
             <el-option v-for="item in contactValueData" :key="item.id" :value="item.id" :label="item.name" />
           </el-select>
           </el-select>
         </el-form-item>
         </el-form-item>

+ 2 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/relatedBusiness.vue

@@ -146,7 +146,8 @@ watchEffect(() => {
     relatedTaskstable.value = (data.businessOpportunityList || []).map((item: any) => {
     relatedTaskstable.value = (data.businessOpportunityList || []).map((item: any) => {
         return {
         return {
             ...item,
             ...item,
-            expectedTransactionDate: item.expectedTransactionDate ? formatDate(new Date(item.expectedTransactionDate)) : ''
+            expectedTransactionDate: item.expectedTransactionDate ? formatDate(new Date(item.expectedTransactionDate)) : '',
+            editTime: item.editTime ? formatDate(new Date(item.editTime)) : ''
         }
         }
     })
     })
 });
 });

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

@@ -1477,12 +1477,30 @@ public class ProjectController {
         return projectService.groupExpendProcessList(startDate,endDate,projectId,pageIndex,pageSize);
         return projectService.groupExpendProcessList(startDate,endDate,projectId,pageIndex,pageSize);
     }
     }
 
 
-    //依斯倍定制 分组耗用进度
+    //依斯倍定制 分组耗用
     @RequestMapping("/groupExpendProcessListForChart")
     @RequestMapping("/groupExpendProcessListForChart")
     public HttpRespMsg groupExpendProcessListForChart(String startDate,String endDate,String projectIds,String groupNames){
     public HttpRespMsg groupExpendProcessListForChart(String startDate,String endDate,String projectIds,String groupNames){
         return projectService.groupExpendProcessListForChart(startDate,endDate,projectIds,groupNames);
         return projectService.groupExpendProcessListForChart(startDate,endDate,projectIds,groupNames);
     }
     }
 
 
+    //依斯倍定制 分组耗用人员分组耗用
+    @RequestMapping("/groupExpendProcessListForUser")
+    public HttpRespMsg groupExpendProcessListForUser(String startDate,String endDate,String projectIds,String groupNames,String deptIdStr,Integer pageIndex,Integer pageSize){
+        return projectService.groupExpendProcessListForUser(startDate,endDate,projectIds,groupNames,deptIdStr,pageIndex,pageSize);
+    }
+
+    //依斯倍定制 分组耗用人员分组耗用
+    @RequestMapping("/exportGroupExpendProcessListForUser")
+    public HttpRespMsg exportGroupExpendProcessListForUser(String startDate,String endDate,String projectIds,String groupNames,String titleStr,String deptIdStr){
+        return projectService.exportGroupExpendProcessListForUser(startDate,endDate,projectIds,groupNames,titleStr,deptIdStr);
+    }
+
+    //依斯倍定制 分组耗用表项目占比
+    @RequestMapping("/groupExpendProcessListForProject")
+    public HttpRespMsg groupExpendProcessListForProject(String startDate,String endDate,String projectIds,String groupNames,String deptIdStr,Integer pageIndex,Integer pageSize){
+        return projectService.groupExpendProcessListForProject(startDate,endDate,projectIds,groupNames,deptIdStr,pageIndex,pageSize);
+    }
+
     //依斯倍定制 导出分组耗用进度表
     //依斯倍定制 导出分组耗用进度表
     @RequestMapping("/exportGroupExpendProcessList")
     @RequestMapping("/exportGroupExpendProcessList")
     public HttpRespMsg exportGroupExpendProcessList(String startDate,String endDate,Integer projectId){
     public HttpRespMsg exportGroupExpendProcessList(String startDate,String endDate,Integer projectId){

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

@@ -111,6 +111,8 @@ public class ReportController {
     private UserFvTimeMapper userFvTimeMapper;
     private UserFvTimeMapper userFvTimeMapper;
     @Resource
     @Resource
     private UserCustomMapper userCustomMapper;
     private UserCustomMapper userCustomMapper;
+    @Resource
+    private UserGroupMapper userGroupMapper;
 
 
     //获取任务相关的日报列表
     //获取任务相关的日报列表
     @RequestMapping("/getTaskReportList")
     @RequestMapping("/getTaskReportList")
@@ -1304,6 +1306,28 @@ public class ReportController {
             }
             }
         }
         }
 
 
+        //校验非项目工时占比
+        User reportOwner = userMapper.selectById(reportList.get(0).getCreatorId());
+        if (reportOwner.getUserGroupId() != null) {
+            //获取非项目列表
+            List<Project> nonProjectList = projectMapper.selectList(new QueryWrapper<Project>().select("id").eq("is_public", 1).eq("company_id", reportOwner.getCompanyId()));
+            List<Integer> collect = nonProjectList.stream().map(Project::getId).collect(Collectors.toList());
+            List<Report> oldRelatedReportList = reportMapper.selectList(new QueryWrapper<Report>().select("id,project_id,working_time").eq("creator_id", reportOwner.getId()).and(wrapper->wrapper.eq("state",0).or().eq("state",1).or().eq("state",3)));
+            //剔除掉当前日报中的
+            oldRelatedReportList = oldRelatedReportList.stream().filter(old->!reportList.stream().map(Report::getId).collect(Collectors.toList()).contains(old.getId())).collect(Collectors.toList());
+            oldRelatedReportList.addAll(reportList);
+            double totalWorkingTime = oldRelatedReportList.stream().mapToDouble(Report::getWorkingTime).sum();
+            double nonProjectWorkingTime = oldRelatedReportList.stream().filter(old->collect.contains(old.getProjectId())).mapToDouble(Report::getWorkingTime).sum();
+            double percent = 100*nonProjectWorkingTime/totalWorkingTime;
+            
+            int maxPercent = userGroupMapper.selectById(reportOwner.getUserGroupId()).getNoProjectPercent();
+            if(percent > maxPercent){
+                HttpRespMsg httpRespMsg = new HttpRespMsg();
+                httpRespMsg.setError("非项目工时占比不得超过"+maxPercent+"%");
+                return httpRespMsg;
+            }
+        }
+
         //如果锁定工作时长上限的话,需要校验每日的合计工作时长
         //如果锁定工作时长上限的话,需要校验每日的合计工作时长
         for (Report report : reportList) {
         for (Report report : reportList) {
             String creatorId = report.getCreatorId();
             String creatorId = report.getCreatorId();
@@ -1430,7 +1454,6 @@ public class ReportController {
             for (Report report : reportList) {
             for (Report report : reportList) {
                 report.setDepartmentAuditState(0);
                 report.setDepartmentAuditState(0);
                 //优先按照当前日报填写人的直属审核人审核
                 //优先按照当前日报填写人的直属审核人审核
-                User reportOwner = creatorList.stream().filter(c->c.getId().equals(report.getCreatorId())).findFirst().get();
                 if (!StringUtils.isEmpty(reportOwner.getSuperiorId())) {
                 if (!StringUtils.isEmpty(reportOwner.getSuperiorId())) {
                     User auditor = tempAuditorUserList.stream().filter(t -> t.getId().equals(reportOwner.getSuperiorId())).findFirst().get();
                     User auditor = tempAuditorUserList.stream().filter(t -> t.getId().equals(reportOwner.getSuperiorId())).findFirst().get();
                     report.setProjectAuditorId(auditor.getId());
                     report.setProjectAuditorId(auditor.getId());

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

@@ -179,7 +179,8 @@ public class ReportLogController {
             item.add(String.valueOf(df1.format(reportLog.getOperateDate())));
             item.add(String.valueOf(df1.format(reportLog.getOperateDate())));
             dataList.add(item);
             dataList.add(item);
         }
         }
-        String resp = ExcelUtil.exportGeneralExcelByTitleAndList("日报审核记录", dataList, path);
+        String fileName = "日报审核记录_"+System.currentTimeMillis();
+        String resp = ExcelUtil.exportGeneralExcelByTitleAndList(fileName, dataList, path);
         msg.setData(resp);
         msg.setData(resp);
         return msg;
         return msg;
     }
     }

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

@@ -113,6 +113,8 @@ public class UserController {
     private UserMapper userMapper;
     private UserMapper userMapper;
     @Resource
     @Resource
     private UserCertMapper userCertMapper;
     private UserCertMapper userCertMapper;
+    @Resource
+    private UserGroupMapper userGroupMapper;
 
 
     public static HashMap<String, Integer> corpddJobCenter = new HashMap();
     public static HashMap<String, Integer> corpddJobCenter = new HashMap();
     //用于控制线程锁
     //用于控制线程锁
@@ -235,9 +237,9 @@ public class UserController {
                                   @RequestParam Integer roleId, Double monthCost, Double cost,
                                   @RequestParam Integer roleId, Double monthCost, Double cost,
                                   Integer departmentId, Integer salaryType, String costApplyDate,
                                   Integer departmentId, Integer salaryType, String costApplyDate,
                                     String position, String certJson,String inductionDate,String superiorId,
                                     String position, String certJson,String inductionDate,String superiorId,
-                                    String plate1,String plate2,String plate3,String plate4,String plate5, String jobNumber, String inactiveDate,String reportDeptIds) {
+                                    String plate1,String plate2,String plate3,String plate4,String plate5, String jobNumber, String inactiveDate,String reportDeptIds,Integer groupId) {
         return userService.insertUser(id, name, phone, onlyAuditOnce, roleId, monthCost, cost, departmentId, salaryType, costApplyDate,
         return userService.insertUser(id, name, phone, onlyAuditOnce, roleId, monthCost, cost, departmentId, salaryType, costApplyDate,
-                    position, certJson, request,inductionDate,superiorId,plate1, plate2, plate3,plate4,plate5, jobNumber, inactiveDate,reportDeptIds);
+                    position, certJson, request,inductionDate,superiorId,plate1, plate2, plate3,plate4,plate5, jobNumber, inactiveDate,reportDeptIds,groupId);
     }
     }
 
 
     /**
     /**
@@ -996,5 +998,21 @@ public class UserController {
         return msg;
         return msg;
     }
     }
 
 
+    @RequestMapping("/batchSetUserGroup")
+    public HttpRespMsg batchSetUserGroup(String userIds,Integer groupId){
+        HttpRespMsg msg=new HttpRespMsg();
+        if(!StringUtils.isEmpty(userIds)){
+            List<String> list = Arrays.asList(userIds.split(","));
+            List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().in(User::getId, list));
+            userList.forEach(u->{
+                u.setUserGroupId(groupId);
+            });
+            if(!userService.updateBatchById(userList)){
+                msg.setError("验证失败");
+            }
+        }
+        return msg;
+    }
+
 }
 }
 
 

+ 87 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserGroupController.java

@@ -0,0 +1,87 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.management.platform.entity.User;
+import com.management.platform.entity.UserGroup;
+import com.management.platform.mapper.UserGroupMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.UserGroupService;
+import com.management.platform.service.UserService;
+import com.management.platform.util.HttpRespMsg;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-07-29
+ */
+@RestController
+@RequestMapping("/user-group")
+@RequiredArgsConstructor
+public class UserGroupController {
+
+    private final UserGroupService userGroupService;
+    private final UserMapper userMapper;
+    private final HttpServletRequest request;
+    private final UserService userService;
+
+
+    @RequestMapping("/addOrUpdate")
+    public HttpRespMsg addOrUpdate(UserGroup userGroup){
+        HttpRespMsg msg=new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        userGroup.setCompanyId(companyId);
+        Integer count;
+        if(userGroup.getId()==null){
+            count=userGroupService.count(new LambdaQueryWrapper<UserGroup>().eq(UserGroup::getCompanyId,companyId).eq(UserGroup::getGroupName,userGroup.getGroupName()));
+        }else {
+            count=userGroupService.count(new LambdaQueryWrapper<UserGroup>().ne(UserGroup::getId,userGroup.getId()).eq(UserGroup::getCompanyId,companyId).eq(UserGroup::getGroupName,userGroup.getGroupName()));
+        }
+        if(count>0){
+            msg.setError("分组:"+userGroup.getGroupName()+"已存在");
+            return msg;
+        }
+        userGroupService.saveOrUpdate(userGroup);
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id){
+        HttpRespMsg msg=new HttpRespMsg();
+        Integer count = userMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getUserGroupId, id));
+        if(count>0){
+            msg.setError("存在处于当前分组的人员,无法删除");
+            return msg;
+        }
+        if(!userGroupService.removeById(id)){
+            msg.setError("验证失败");
+        }
+        return msg;
+    }
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(){
+        HttpRespMsg msg=new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        LambdaQueryWrapper<UserGroup> wrapper = new LambdaQueryWrapper<UserGroup>().eq(UserGroup::getCompanyId, companyId).orderByDesc(UserGroup::getId);
+        List<UserGroup> list = userGroupService.list(wrapper);
+        msg.setData(list);
+        return msg;
+    }
+
+}
+

+ 36 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserWorkbenchController.java

@@ -0,0 +1,36 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.UserWorkbench;
+import com.management.platform.service.UserWorkbenchService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-08-06
+ */
+@RestController
+@RequestMapping("/user-workbench")
+public class UserWorkbenchController {
+    @Resource
+    private UserWorkbenchService userWorkbenchService;
+
+    @RequestMapping("/saveWorkbench")
+    public HttpRespMsg saveWorkbench(String userId, String workbench) {
+        UserWorkbench userWorkbench = new UserWorkbench();
+        userWorkbench.setUserId(userId);
+        userWorkbench.setTableList(workbench);
+        userWorkbenchService.saveOrUpdate(userWorkbench);
+        return new HttpRespMsg();
+    }
+}
+

+ 6 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/User.java

@@ -296,6 +296,12 @@ public class User extends Model<User> {
     @TableField("only_audit_once")
     @TableField("only_audit_once")
     private Integer onlyAuditOnce;
     private Integer onlyAuditOnce;
 
 
+    /**
+     * 人员所属分组
+     */
+    @TableField("user_group_id")
+    private Integer userGroupId;
+
     @TableField(exist = false)
     @TableField(exist = false)
     private List<Department> userReportDeptList;
     private List<Department> userReportDeptList;
 
 

+ 54 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/UserGroup.java

@@ -0,0 +1,54 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-07-29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class UserGroup extends Model<UserGroup> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 公司id
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 分组名称
+     */
+    @TableField("group_name")
+    private String groupName;
+
+    /**
+     * 非项目工时占比
+     */
+    @TableField("no_project_percent")
+    private Integer noProjectPercent;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 44 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/UserWorkbench.java

@@ -0,0 +1,44 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-08-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class UserWorkbench extends Model<UserWorkbench> {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 用户id
+     */
+    @TableId("user_id")
+    private String userId;
+
+    /**
+     * 表集合,json array格式
+     */
+    @TableField("table_list")
+    private String tableList;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.userId;
+    }
+
+}

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/UserVO.java

@@ -1,5 +1,6 @@
 package com.management.platform.entity.vo;
 package com.management.platform.entity.vo;
 
 
+import com.alibaba.fastjson.JSONArray;
 import com.management.platform.entity.*;
 import com.management.platform.entity.*;
 import lombok.Data;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.EqualsAndHashCode;
@@ -26,4 +27,6 @@ public class UserVO extends User {
 
 
     private boolean hasAuditDept;
     private boolean hasAuditDept;
 
 
+    private JSONArray userWorkbench;
+
 }
 }

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

@@ -9,6 +9,7 @@ import com.management.platform.entity.vo.StageCost;
 import com.management.platform.entity.vo.UserCateTimeVo;
 import com.management.platform.entity.vo.UserCateTimeVo;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Update;
 import org.apache.ibatis.annotations.Update;
+import org.omg.CORBA.INTERNAL;
 
 
 import java.time.LocalDate;
 import java.time.LocalDate;
 import java.util.HashMap;
 import java.util.HashMap;
@@ -186,4 +187,15 @@ public interface ProjectMapper extends BaseMapper<Project> {
     void removeReviwer(Integer id);
     void removeReviwer(Integer id);
 
 
     List<Map<String, Object>> groupExpendProcessListForChart(String userId, Integer companyId, String startDate, String endDate,@Param("list") List<Integer> deptIds,@Param("listSecond") List<Integer> regularDeptIds,@Param("listThird") List<Integer> projectIdList,@Param("listFour") List<String> groupNameList);
     List<Map<String, Object>> groupExpendProcessListForChart(String userId, Integer companyId, String startDate, String endDate,@Param("list") List<Integer> deptIds,@Param("listSecond") List<Integer> regularDeptIds,@Param("listThird") List<Integer> projectIdList,@Param("listFour") List<String> groupNameList);
+
+    List<Map<String, Object>> groupExpendProcessListForUser(String userId, Integer companyId, String startDate, String endDate, @Param("list") List<Integer> deptIds, @Param("listSecond") List<Integer> regularDeptIds, @Param("listThird")List<Integer> projectIdList, @Param("listFour") List<String> groupNameList, @Param("listFive") List<Integer> deptIdList,Integer start,Integer size);
+
+    Integer groupExpendProcessListForUserCount(String userId, Integer companyId, String startDate, String endDate, @Param("list") List<Integer> deptIds, @Param("listSecond") List<Integer> regularDeptIds, @Param("listThird")List<Integer> projectIdList, @Param("listFour") List<String> groupNameList, @Param("listFive") List<Integer> deptIdList);
+
+    List<Map<String, Object>> groupExpendProcessListForProject(String userId,  Integer companyId, String startDate, String endDate, @Param("list") List<Integer> deptIds, @Param("listSecond") List<Integer> regularDeptIds, @Param("listThird")List<Integer> projectIdList, @Param("listFour") List<String> groupNameList, @Param("listFive") List<Integer> deptIdList,Integer start,Integer size);
+
+    Integer groupExpendProcessListForProjectCount(String userId, Integer companyId, String startDate, String endDate, @Param("list") List<Integer> deptIds, @Param("listSecond") List<Integer> regularDeptIds, @Param("listThird")List<Integer> projectIdList, @Param("listFour") List<String> groupNameList, @Param("listFive") List<Integer> deptIdList);
+
+    @Update("update project set category=null,category_name=null where id=#{id}")
+    void updateProjectCategoryToNull(@Param("id") Integer id);
 }
 }

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.UserGroup;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-07-29
+ */
+public interface UserGroupMapper extends BaseMapper<UserGroup> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.UserWorkbench;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-08-06
+ */
+public interface UserWorkbenchMapper extends BaseMapper<UserWorkbench> {
+
+}

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

@@ -300,4 +300,11 @@ public interface ProjectService extends IService<Project> {
     HttpRespMsg batchSetProjectTaskExecutor(String projectIds, String userIds);
     HttpRespMsg batchSetProjectTaskExecutor(String projectIds, String userIds);
 
 
     HttpRespMsg groupExpendProcessListForChart(String startDate, String endDate, String projectIds, String groupNames);
     HttpRespMsg groupExpendProcessListForChart(String startDate, String endDate, String projectIds, String groupNames);
+
+    HttpRespMsg groupExpendProcessListForUser(String startDate, String endDate, String projectIds, String groupNames, String deptIdStr,Integer pageIndex,Integer pageSize);
+
+    HttpRespMsg groupExpendProcessListForProject(String startDate, String endDate, String projectIds, String groupNames, String deptIdStr,Integer pageIndex,Integer pageSize);
+
+    HttpRespMsg exportGroupExpendProcessListForUser(String startDate, String endDate, String projectIds, String groupNames,String titleStr, String deptIdStr);
+
 }
 }

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.UserGroup;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-07-29
+ */
+public interface UserGroupService extends IService<UserGroup> {
+
+}

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

@@ -38,7 +38,7 @@ public interface UserService extends IService<User> {
     HttpRespMsg insertUser(String id, String name, String phone,Integer onlyAuditOnce, Integer roleId, Double monthCost, Double cost, Integer departmentId,
     HttpRespMsg insertUser(String id, String name, String phone,Integer onlyAuditOnce, Integer roleId, Double monthCost, Double cost, Integer departmentId,
                            Integer salaryType, String costApplyDate, String position, String certJson,
                            Integer salaryType, String costApplyDate, String position, String certJson,
                            HttpServletRequest request,String inductionDate, String superiorId,String plate1,
                            HttpServletRequest request,String inductionDate, String superiorId,String plate1,
-                           String plate2,String plate3,String plate4,String plate5, String jobNumber, String inactiveDate,String reportDeptIds);
+                           String plate2,String plate3,String plate4,String plate5, String jobNumber, String inactiveDate,String reportDeptIds,Integer groupId);
 
 
     HttpRespMsg importUser(MultipartFile multipartFile, HttpServletRequest request);
     HttpRespMsg importUser(MultipartFile multipartFile, HttpServletRequest request);
 
 

+ 19 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserWorkbenchService.java

@@ -0,0 +1,19 @@
+package com.management.platform.service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.management.platform.entity.UserWorkbench;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-08-06
+ */
+public interface UserWorkbenchService extends IService<UserWorkbench> {
+
+    public JSONArray getMyWorkbench(String userId);
+
+}

+ 235 - 17
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -318,7 +318,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     .mapToDouble(r->r.getWorkingTime()).sum();
                     .mapToDouble(r->r.getWorkingTime()).sum();
             String rWorkTime=reallWorkTime==null ? "0":df.format(reallWorkTime);
             String rWorkTime=reallWorkTime==null ? "0":df.format(reallWorkTime);
             project.setReallyWorkTime(rWorkTime);
             project.setReallyWorkTime(rWorkTime);
-            String pEstimatedWork=Integer.valueOf(String.valueOf(project.getManDay()))==null ? 0*allday+"": project.getManDay()*allday+"";
+            String pEstimatedWork=project.getManDay()==null? "0": (project.getManDay()*allday+"");
             project.setEstimatedWorkTime(pEstimatedWork);
             project.setEstimatedWorkTime(pEstimatedWork);
             List<TaskGroup> taskGroupCollect = taskGroups.stream().filter(t -> t.getProjectId().equals(project.getId())).collect(Collectors.toList());
             List<TaskGroup> taskGroupCollect = taskGroups.stream().filter(t -> t.getProjectId().equals(project.getId())).collect(Collectors.toList());
 
 
@@ -649,17 +649,20 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             }
             }
             long end = System.currentTimeMillis();
             long end = System.currentTimeMillis();
             List<String> stringList = providerCategoryList.stream().map(ProviderCategory::getProviderCategoryName).distinct().collect(Collectors.toList());
             List<String> stringList = providerCategoryList.stream().map(ProviderCategory::getProviderCategoryName).distinct().collect(Collectors.toList());
-            //处理项目日报审核人
-            if(projectIds.size()>0){
-                List<ProjectAuditor> projectAuditorList = projectAuditorMapper.selectList(new LambdaQueryWrapper<ProjectAuditor>().in(ProjectAuditor::getProjectId, projectIds));
-                list.forEach(l->{
-                    Optional<ProjectAuditor> first = projectAuditorList.stream().filter(p -> p.getProjectId().equals(l.getId())).findFirst();
-                    if(first.isPresent()){
-                        l.setProjectAuditorName(first.get().getAuditorName());
-                        l.setProjectAuditorId(first.get().getAuditorId());
-                    }
-                });
+            //针对成都明夷电子科技有限公司,显示项目日报审核人
+            if (company.getCompanyName().equals("成都明夷电子科技有限公司")) {
+                if(projectIds.size()>0){
+                    List<ProjectAuditor> projectAuditorList = projectAuditorMapper.selectList(new LambdaQueryWrapper<ProjectAuditor>().in(ProjectAuditor::getProjectId, projectIds));
+                    list.forEach(l->{
+                        Optional<ProjectAuditor> first = projectAuditorList.stream().filter(p -> p.getProjectId().equals(l.getId())).findFirst();
+                        if(first.isPresent()){
+                            l.setProjectAuditorName(first.get().getAuditorName());
+                            l.setProjectAuditorId(first.get().getAuditorId());
+                        }
+                    });
+                }
             }
             }
+
             //stringList.add("未分类");
             //stringList.add("未分类");
             stringList.add(MessageUtils.message("excel.unclassified"));
             stringList.add(MessageUtils.message("excel.unclassified"));
             Long total = projectIPage.getTotal();
             Long total = projectIPage.getTotal();
@@ -1020,6 +1023,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                         p.setCategory(category);
                         p.setCategory(category);
                         p.setCategoryName(projectCategory.getName());
                         p.setCategoryName(projectCategory.getName());
                     }
                     }
+                }else {
+                    projectMapper.updateProjectCategoryToNull(p.getId());
                 }
                 }
                 ProjectSeparate oldSeparate = projectSeparateMapper.selectById(id);
                 ProjectSeparate oldSeparate = projectSeparateMapper.selectById(id);
                 if(companyId==936){
                 if(companyId==936){
@@ -2219,9 +2224,9 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             //String fileName = "项目成本工时统计_"+System.currentTimeMillis();
             //String fileName = "项目成本工时统计_"+System.currentTimeMillis();
             String fileName = null;
             String fileName = null;
             if (withMainProject == 1) {
             if (withMainProject == 1) {
-                fileName = "主项目成本工时统计"+System.currentTimeMillis();
+                fileName = "主项目成本工时统计" +(startDate==null?"":(startDate+MessageUtils.message("leave.to")+endDate))+System.currentTimeMillis();
             } else {
             } else {
-                fileName = MessageUtils.message("fileName.projectCost")+System.currentTimeMillis();
+                fileName = (startDate==null?"":(startDate+MessageUtils.message("leave.to")+endDate)) + MessageUtils.message("fileName.projectCost")+System.currentTimeMillis();
             }
             }
 
 
             return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileName , allList, path);
             return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileName , allList, path);
@@ -8227,7 +8232,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             }
             }
             //生成excel文件导出
             //生成excel文件导出
             //String fileName = "项目分类工时成本统计_"+System.currentTimeMillis();
             //String fileName = "项目分类工时成本统计_"+System.currentTimeMillis();
-            String fileName = MessageUtils.message("fileName.proClassLaborCost")+System.currentTimeMillis();
+            String fileName = (startDate==null?"":(startDate+MessageUtils.message("leave.to")+endDate)) + MessageUtils.message("fileName.proClassLaborCost")+System.currentTimeMillis();
             try {
             try {
                 return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileName , allList, path);
                 return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileName , allList, path);
             } catch (Exception e) {
             } catch (Exception e) {
@@ -11789,7 +11794,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             allList.add(sumRow);
             allList.add(sumRow);
             //生成excel文件导出
             //生成excel文件导出
             //String fileName = "维度成本工时统计_"+System.currentTimeMillis();
             //String fileName = "维度成本工时统计_"+System.currentTimeMillis();
-            String fileName = timeType.getCustomDegreeName() + MessageUtils.message("fileName.degreeCost")+System.currentTimeMillis();
+            String fileName = (startDate==null?"":(startDate+MessageUtils.message("leave.to")+endDate)) + timeType.getCustomDegreeName() + MessageUtils.message("fileName.degreeCost")+System.currentTimeMillis();
             return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileName , allList, path);
             return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileName , allList, path);
         } catch (NullPointerException e) {
         } catch (NullPointerException e) {
             e.printStackTrace();
             e.printStackTrace();
@@ -13552,8 +13557,6 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                             item.put("corpwxDeptId",corpwxDeptid);
                             item.put("corpwxDeptId",corpwxDeptid);
                             item.put("department_name",departmentName);
                             item.put("department_name",departmentName);
                             if(taskGroup.isPresent()){
                             if(taskGroup.isPresent()){
-//                                List<Map<String, Object>> mapList = resultList.stream().filter(r -> Integer.valueOf(String.valueOf(r.get("projectId"))).equals(project.getId())
-//                                        && Integer.valueOf(String.valueOf(r.get("groupId"))).equals(taskGroup.get().getId()) && (Integer.valueOf(String.valueOf(r.get("deptId"))).equals(7458) || subDeptIds.contains(Integer.valueOf(String.valueOf(r.get("deptId")))))).collect(Collectors.toList());
                                 List<Map<String, Object>> mapList = resultList.stream().filter(r -> Integer.valueOf(String.valueOf(r.get("projectId"))).equals(project.getId())
                                 List<Map<String, Object>> mapList = resultList.stream().filter(r -> Integer.valueOf(String.valueOf(r.get("projectId"))).equals(project.getId())
                                         && Integer.valueOf(String.valueOf(r.get("groupId"))).equals(taskGroup.get().getId())).collect(Collectors.toList());
                                         && Integer.valueOf(String.valueOf(r.get("groupId"))).equals(taskGroup.get().getId())).collect(Collectors.toList());
                                 if(mapList!=null&&mapList.size()>0){
                                 if(mapList!=null&&mapList.size()>0){
@@ -14407,4 +14410,219 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         msg.setData(resultList);
         msg.setData(resultList);
         return msg;
         return msg;
     }
     }
+
+    @Override
+    public HttpRespMsg groupExpendProcessListForUser(String startDate, String endDate, String projectIds, String groupNames, String deptIdStr,Integer pageIndex,Integer pageSize) {
+        HttpRespMsg msg=new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        List<Department> departments = departmentMapper.selectList(new LambdaQueryWrapper<Department>().eq(Department::getCompanyId, user.getCompanyId()));
+        NumberFormat percentFormat = NumberFormat.getPercentInstance();
+        percentFormat.setMaximumFractionDigits(2);
+        Integer start=null;
+        Integer size=null;
+        if(pageIndex!=null&&pageSize!=null){
+            size=pageSize;
+            start=(pageIndex-1)*size;
+        }
+        Integer companyId = user.getCompanyId();
+        List<String> groupNameList=new ArrayList<>();
+        List<Integer> projectIdList=new ArrayList<>();
+        List<Integer> deptIdList=new ArrayList<>();
+        if(!StringUtils.isEmpty(groupNames)){
+            groupNameList = Arrays.asList(groupNames.split(","));
+        }
+        if(!StringUtils.isEmpty(projectIds)){
+            projectIdList=Arrays.asList(projectIds.split(",")).stream().map(i->Integer.valueOf(i)).collect(Collectors.toList());
+        }
+        if(!StringUtils.isEmpty(deptIdStr)){
+            deptIdList=Arrays.asList(deptIdStr.split(",")).stream().map(i->Integer.valueOf(i)).collect(Collectors.toList());
+        }
+        boolean viewAll = sysFunctionService.hasPriviledge(user.getRoleId(), "全部分组耗用进度表");
+        boolean incharger = sysFunctionService.hasPriviledge(user.getRoleId(), "负责部门分组耗用进度表");
+        List<Department> allDeptList = departmentMapper.selectList(new LambdaQueryWrapper<Department>().eq(Department::getCompanyId, companyId));
+        List<Map<String,Object>> resultList;
+        Integer total;
+        //是否具有查看全部数据的权限
+        //针对依斯呗 指定部门
+        List<Integer> regularDeptIds=new ArrayList<>();
+        if(user.getCompanyId()==3092){
+            List<String> nameString=new ArrayList<>();
+            nameString.add("4");
+            nameString.add("46");
+            nameString.add("45");
+            List<Department> departmentList = departmentMapper.selectList(new LambdaQueryWrapper<Department>().eq(Department::getCompanyId, user.getCompanyId()).in(Department::getDepartmentName, nameString));
+            List<Integer> theCollect = departmentList.stream().map(dm -> dm.getDepartmentId()).distinct().collect(Collectors.toList());
+            theCollect.add(-1);
+            for (Integer integer : theCollect) {
+                List<Integer> branchDepartment = getBranchDepartment(integer, allDeptList);
+                regularDeptIds.addAll(branchDepartment);
+            }
+        }
+        if(!viewAll){
+            if(!incharger){
+                //只能查看本人的数据
+                resultList=projectMapper.groupExpendProcessListForUser(user.getId(),companyId,startDate,endDate,null,null,projectIdList,groupNameList,deptIdList,start,size);
+                total=projectMapper.groupExpendProcessListForUserCount(user.getId(),companyId,startDate,endDate,null,null,projectIdList,groupNameList,deptIdList);
+            }else {
+                List<Department> departmentList = departmentMapper.selectList(new LambdaQueryWrapper<Department>().select(Department::getDepartmentId).eq(Department::getManagerId, user.getId()));
+                List<DepartmentOtherManager> departmentOtherManagerList = departmentOtherManagerMapper.selectList(new QueryWrapper<DepartmentOtherManager>().eq("other_manager_id", user.getId()));
+                List<Integer> deptIds=new ArrayList<>();
+                List<Integer> theCollect = departmentList.stream().map(dm -> dm.getDepartmentId()).distinct().collect(Collectors.toList());
+                theCollect.add(-1);
+                List<Integer> otherCollect = departmentOtherManagerList.stream().map(dom -> dom.getDepartmentId()).distinct().collect(Collectors.toList());
+                otherCollect.add(-1);
+                theCollect.addAll(otherCollect);
+                for (Integer integer : theCollect) {
+                    List<Integer> branchDepartment = getBranchDepartment(integer, allDeptList);
+                    deptIds.addAll(branchDepartment);
+                }
+                resultList=projectMapper.groupExpendProcessListForUser(null,companyId,startDate,endDate,deptIdList,regularDeptIds,projectIdList,groupNameList,deptIdList,start,size);
+                total=projectMapper.groupExpendProcessListForUserCount(null,companyId,startDate,endDate,deptIdList,regularDeptIds,projectIdList,groupNameList,deptIdList);
+            }
+        }else {
+            resultList=projectMapper.groupExpendProcessListForUser(null,companyId,startDate,endDate,null,regularDeptIds,projectIdList,groupNameList,deptIdList,start,size);
+            total=projectMapper.groupExpendProcessListForUserCount(null,companyId,startDate,endDate,null,regularDeptIds,projectIdList,groupNameList,deptIdList);
+        }
+        resultList.forEach(r->{
+            Optional<Department> department = departments.stream().filter(d -> d.getDepartmentId().equals(Integer.valueOf(String.valueOf(r.get("departmentId"))))).findFirst();
+            r.put("departmentName",departmentService.getSupDepartment(department.get(),departments));
+        });
+        Map<String,Object> map=new HashMap<>();
+        resultList=resultList.stream().filter(r->Double.valueOf(String.valueOf(r.get("totalWorkTime")))>0).collect(Collectors.toList());
+        map.put("record",resultList);
+        map.put("total",total);
+        msg.setData(map);
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg groupExpendProcessListForProject(String startDate, String endDate, String projectIds, String groupNames, String deptIdStr,Integer pageIndex,Integer pageSize) {
+        HttpRespMsg msg=new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        List<Department> departments = departmentMapper.selectList(new LambdaQueryWrapper<Department>().eq(Department::getCompanyId, user.getCompanyId()));
+        NumberFormat percentFormat = NumberFormat.getPercentInstance();
+        percentFormat.setMaximumFractionDigits(2);
+        Integer start=null;
+        Integer size=null;
+        if(pageIndex!=null&&pageSize!=null){
+            size=pageSize;
+            start=(pageIndex-1)*size;
+        }
+        Integer companyId = user.getCompanyId();
+        List<String> groupNameList=new ArrayList<>();
+        List<Integer> projectIdList=new ArrayList<>();
+        List<Integer> deptIdList=new ArrayList<>();
+        if(!StringUtils.isEmpty(groupNames)){
+            groupNameList = Arrays.asList(groupNames.split(","));
+        }
+        if(!StringUtils.isEmpty(projectIds)){
+            projectIdList=Arrays.asList(projectIds.split(",")).stream().map(i->Integer.valueOf(i)).collect(Collectors.toList());
+        }
+        if(!StringUtils.isEmpty(deptIdStr)){
+            deptIdList=Arrays.asList(deptIdStr.split(",")).stream().map(i->Integer.valueOf(i)).collect(Collectors.toList());
+        }
+        boolean viewAll = sysFunctionService.hasPriviledge(user.getRoleId(), "全部分组耗用进度表");
+        boolean incharger = sysFunctionService.hasPriviledge(user.getRoleId(), "负责部门分组耗用进度表");
+        List<Department> allDeptList = departmentMapper.selectList(new LambdaQueryWrapper<Department>().eq(Department::getCompanyId, companyId));
+        List<Map<String,Object>> resultList;
+        Integer total;
+        //是否具有查看全部数据的权限
+        //针对依斯呗 指定部门
+        List<Integer> regularDeptIds=new ArrayList<>();
+        if(user.getCompanyId()==3092){
+            List<String> nameString=new ArrayList<>();
+            nameString.add("4");
+            nameString.add("46");
+            nameString.add("45");
+            List<Department> departmentList = departmentMapper.selectList(new LambdaQueryWrapper<Department>().eq(Department::getCompanyId, user.getCompanyId()).in(Department::getDepartmentName, nameString));
+            List<Integer> theCollect = departmentList.stream().map(dm -> dm.getDepartmentId()).distinct().collect(Collectors.toList());
+            theCollect.add(-1);
+            for (Integer integer : theCollect) {
+                List<Integer> branchDepartment = getBranchDepartment(integer, allDeptList);
+                regularDeptIds.addAll(branchDepartment);
+            }
+        }
+        if(!viewAll){
+            if(!incharger){
+                //只能查看本人的数据
+                resultList=projectMapper.groupExpendProcessListForProject(user.getId(),companyId,startDate,endDate,null,null,projectIdList,groupNameList,deptIdList,start,size);
+                total=projectMapper.groupExpendProcessListForProjectCount(user.getId(),companyId,startDate,endDate,null,null,projectIdList,groupNameList,deptIdList);
+            }else {
+                List<Department> departmentList = departmentMapper.selectList(new LambdaQueryWrapper<Department>().select(Department::getDepartmentId).eq(Department::getManagerId, user.getId()));
+                List<DepartmentOtherManager> departmentOtherManagerList = departmentOtherManagerMapper.selectList(new QueryWrapper<DepartmentOtherManager>().eq("other_manager_id", user.getId()));
+                List<Integer> deptIds=new ArrayList<>();
+                List<Integer> theCollect = departmentList.stream().map(dm -> dm.getDepartmentId()).distinct().collect(Collectors.toList());
+                theCollect.add(-1);
+                List<Integer> otherCollect = departmentOtherManagerList.stream().map(dom -> dom.getDepartmentId()).distinct().collect(Collectors.toList());
+                otherCollect.add(-1);
+                theCollect.addAll(otherCollect);
+                for (Integer integer : theCollect) {
+                    List<Integer> branchDepartment = getBranchDepartment(integer, allDeptList);
+                    deptIds.addAll(branchDepartment);
+                }
+                resultList=projectMapper.groupExpendProcessListForProject(null,companyId,startDate,endDate,deptIdList,regularDeptIds,projectIdList,groupNameList,deptIdList,start,size);
+                total=projectMapper.groupExpendProcessListForProjectCount(null,companyId,startDate,endDate,deptIdList,regularDeptIds,projectIdList,groupNameList,deptIdList);
+            }
+        }else {
+            resultList=projectMapper.groupExpendProcessListForProject(null,companyId,startDate,endDate,null,regularDeptIds,projectIdList,groupNameList,deptIdList,start,size);
+            total=projectMapper.groupExpendProcessListForProjectCount(null,companyId,startDate,endDate,null,regularDeptIds,projectIdList,groupNameList,deptIdList);
+        }
+        //计算占比
+        double workTime = resultList.stream().mapToDouble(r -> Double.valueOf(String.valueOf(r.get("workTime")))).sum();
+        resultList.forEach(r->{
+            BigDecimal time = new BigDecimal(String.valueOf(r.get("workTime")));
+            time=time.divide(new BigDecimal(workTime),4,RoundingMode.HALF_UP);
+            time=time.multiply(new BigDecimal(100));
+//            String format = percentFormat.format(time.doubleValue());
+            r.put("percent",time.doubleValue()+"%");
+        });
+        Map<String,Object> map=new HashMap<>();
+        map.put("record",resultList);
+        map.put("total",total);
+        msg.setData(map);
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg exportGroupExpendProcessListForUser(String startDate, String endDate, String projectIds, String groupNames,String titleStr, String deptIdStr) {
+        User user = userMapper.selectById(request.getHeader("token"));
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, user.getCompanyId()));
+        List<List<String>> dataList=new ArrayList<>();
+        List<String> titleList=new ArrayList<>();
+        titleList.add("所属部门");
+        titleList.add("工号");
+        titleList.add("员工");
+        if(!StringUtils.isEmpty(titleStr)){
+            List<String> strings = Arrays.asList(titleStr.split(","));
+            titleList.addAll(strings);
+        }
+        dataList.add(titleList);
+        HttpRespMsg msg = groupExpendProcessListForUser(startDate, endDate, projectIds, groupNames, deptIdStr, null, null);
+        Map<String, Object> data = (Map<String, Object>)  msg.data;
+        List<Map<String, Object>> mapList = (List<Map<String, Object>>) data.get("record");
+        for (Map<String, Object> map : mapList) {
+            List<String> item=new ArrayList<>();
+            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                item.add("$departmentName="+String.valueOf(map.get("departmentName"))+"$");
+            }else {
+                item.add(String.valueOf(map.get("departmentName")));
+            }
+            item.add(String.valueOf(map.get("jobNumber")));
+            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                item.add("$userName="+String.valueOf(map.get("userName"))+"$");
+            }else {
+                item.add(String.valueOf(map.get("userName")));
+            }
+            for (String s : titleList) {
+                item.add(String.valueOf(map.get(s)));
+            }
+            dataList.add(item);
+        }
+        try {
+            return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,null,"人员分组耗用表",dataList,path);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return msg;
+    }
 }
 }

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

@@ -662,7 +662,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         Optional<TaskGroup> tgoup = taskGroups.stream().filter(tg->tg.getId().equals(r.getGroupId())).findFirst();
                         Optional<TaskGroup> tgoup = taskGroups.stream().filter(tg->tg.getId().equals(r.getGroupId())).findFirst();
                         if (tgoup.isPresent()) {
                         if (tgoup.isPresent()) {
                             TaskGroup curGroup = tgoup.get();
                             TaskGroup curGroup = tgoup.get();
-                            if (curGroup.getInchargerId() != null) {
+                            if (!StringUtils.isEmpty(curGroup.getInchargerId())) {
                                 User user = userMapper.selectById(curGroup.getInchargerId());
                                 User user = userMapper.selectById(curGroup.getInchargerId());
                                 HashMap map = new HashMap();
                                 HashMap map = new HashMap();
                                 map.put("auditorId", user.getId());
                                 map.put("auditorId", user.getId());
@@ -3045,17 +3045,14 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         if (list.size() > 0) {
         if (list.size() > 0) {
             //存在查看权限的部门
             //存在查看权限的部门
             //获取公司全部人员; 按照人员状态,如果是已经离职的,当前日期在离职日期以后的,不需要显示该人员
             //获取公司全部人员; 按照人员状态,如果是已经离职的,当前日期在离职日期以后的,不需要显示该人员
-
             QueryWrapper<User> queryWrapper = new QueryWrapper<User>().eq("company_id", companyId);
             QueryWrapper<User> queryWrapper = new QueryWrapper<User>().eq("company_id", companyId);
             queryWrapper.and(wrapper->wrapper.eq("is_active", 1).eq("report_status",0)
             queryWrapper.and(wrapper->wrapper.eq("is_active", 1).eq("report_status",0)
                     .or(wrapper2->wrapper2.eq("is_active", 0).gt("inactive_date", date)));
                     .or(wrapper2->wrapper2.eq("is_active", 0).gt("inactive_date", date)));
             List<User> userList = userMapper.selectList(queryWrapper);
             List<User> userList = userMapper.selectList(queryWrapper);
             long t3 = System.currentTimeMillis();
             long t3 = System.currentTimeMillis();
-            System.out.println("获取人员列表耗时:" + (t3 - t2) + "ms");
             List<LeaveSheet> leaveSheetList = leaveSheetMapper.selectList(
             List<LeaveSheet> leaveSheetList = leaveSheetMapper.selectList(
                     new QueryWrapper<LeaveSheet>().select("id, owner_id, start_date, end_date, leave_type, time_type, time_days, time_hours").eq("company_id", companyId));
                     new QueryWrapper<LeaveSheet>().select("id, owner_id, start_date, end_date, leave_type, time_type, time_days, time_hours").eq("company_id", companyId));
             long t4 = System.currentTimeMillis();
             long t4 = System.currentTimeMillis();
-            System.out.println("获取人员请假列表耗时:" + (t4 - t3) + "ms");
             LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
             LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
             List<HashMap> userMapList = new ArrayList<>();
             List<HashMap> userMapList = new ArrayList<>();
             LocalDate curDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
             LocalDate curDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
@@ -3063,7 +3060,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             //获取当日已填写的人员报告
             //获取当日已填写的人员报告
             List<Map<String, Object>> reportNameByDate = reportMapper.getReportNameByDate(date, companyId, null);
             List<Map<String, Object>> reportNameByDate = reportMapper.getReportNameByDate(date, companyId, null);
             long t5 = System.currentTimeMillis();
             long t5 = System.currentTimeMillis();
-            System.out.println("获取当日已填写的人员报告耗时:" + (t5 - t4) + "ms");
             Company company = companyMapper.selectById(companyId);
             Company company = companyMapper.selectById(companyId);
             TimeType timeType = timeTypeMapper.selectById(companyId);
             TimeType timeType = timeTypeMapper.selectById(companyId);
             //如果没有开通OA模块,有开通企业微信同步考勤,从user_corpwx_time表中获取请假时长
             //如果没有开通OA模块,有开通企业微信同步考勤,从user_corpwx_time表中获取请假时长

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.UserGroup;
+import com.management.platform.mapper.UserGroupMapper;
+import com.management.platform.service.UserGroupService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-07-29
+ */
+@Service
+public class UserGroupServiceImpl extends ServiceImpl<UserGroupMapper, UserGroup> implements UserGroupService {
+
+}

+ 10 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java

@@ -113,6 +113,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
     @Autowired
     @Autowired
     private RestTemplate restTemplate;
     private RestTemplate restTemplate;
     @Resource
     @Resource
+    private UserWorkbenchService userWorkbenchService;
+    @Resource
     ExpenseMainTypeService expenseMainTypeService;
     ExpenseMainTypeService expenseMainTypeService;
     @Resource
     @Resource
     private SysRoleModuleMapper sysRoleModuleMapper;
     private SysRoleModuleMapper sysRoleModuleMapper;
@@ -726,6 +728,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         } else {
         } else {
             user.setFunctionList(new ArrayList<>());
             user.setFunctionList(new ArrayList<>());
         }
         }
+
+        //设置用户的工作台模块
+        user.setUserWorkbench(userWorkbenchService.getMyWorkbench(user.getId()));
     }
     }
 
 
     private boolean judgeIsLeader(String userId) {
     private boolean judgeIsLeader(String userId) {
@@ -1327,7 +1332,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
     @Override
     @Override
     public HttpRespMsg insertUser(String targetId, String name, String phone, Integer onlyAuditOnce, Integer roleId, Double monthCost, Double cost,
     public HttpRespMsg insertUser(String targetId, String name, String phone, Integer onlyAuditOnce, Integer roleId, Double monthCost, Double cost,
                                   Integer departmentId, Integer salaryType, String costApplyDate, String position, String certJson, HttpServletRequest request,String inductionDate,
                                   Integer departmentId, Integer salaryType, String costApplyDate, String position, String certJson, HttpServletRequest request,String inductionDate,
-                                  String superiorId,   String plate1,String plate2,String plate3,String plate4,String plate5, String jobNumber, String inactiveDate,String reportDeptIds) {
+                                  String superiorId,   String plate1,String plate2,String plate3,String plate4,String plate5, String jobNumber, String inactiveDate,String reportDeptIds,Integer groupId) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
         try {
         try {
@@ -1384,7 +1389,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
                                 .setPlate3(plate3)
                                 .setPlate3(plate3)
                                 .setPlate4(plate4)
                                 .setPlate4(plate4)
                                 .setPlate5(plate5)
                                 .setPlate5(plate5)
-                                .setJobNumber(jobNumber);
+                                .setJobNumber(jobNumber)
+                                .setUserGroupId(groupId);
                         if(inductionDate!=null&&inductionDate!=""){
                         if(inductionDate!=null&&inductionDate!=""){
                             user.setInductionDate(LocalDate.parse(inductionDate,dtf));
                             user.setInductionDate(LocalDate.parse(inductionDate,dtf));
                         }
                         }
@@ -1477,7 +1483,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
                         .setPlate3(plate3)
                         .setPlate3(plate3)
                         .setPlate4(plate4)
                         .setPlate4(plate4)
                         .setPlate5(plate5)
                         .setPlate5(plate5)
-                        .setJobNumber(jobNumber));
+                        .setJobNumber(jobNumber)
+                        .setUserGroupId(groupId));
                 if (oldSuperiorId != null && superiorId == null) {
                 if (oldSuperiorId != null && superiorId == null) {
                     //清空直属审核人
                     //清空直属审核人
                     userMapper.setSuperiorNull(oldUser.getId());
                     userMapper.setSuperiorNull(oldUser.getId());

+ 73 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserWorkbenchServiceImpl.java

@@ -0,0 +1,73 @@
+package com.management.platform.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.UserWorkbench;
+import com.management.platform.mapper.UserWorkbenchMapper;
+import com.management.platform.service.UserWorkbenchService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-08-06
+ */
+@Service
+public class UserWorkbenchServiceImpl extends ServiceImpl<UserWorkbenchMapper, UserWorkbench> implements UserWorkbenchService {
+
+    @Resource
+    private UserWorkbenchMapper userWorkbenchMapper;
+
+    public final WorkBenchItem[] WORKBENCH_MODULES = new WorkBenchItem[]{
+            new WorkBenchItem(1, "我的工时日历", "basic"),
+            new WorkBenchItem(2, "我的工时统计", "basic"),
+            new WorkBenchItem(3, "团队项目工时统计", "basic"),//分为全部项目查看权限和负责项目查看权限
+            new WorkBenchItem(4, "工时状态统计", "basic"),
+            new WorkBenchItem(5, "我的近期执行任务", "project"),
+            new WorkBenchItem(6, "项目/非项目工时占比", "basic"),
+            new WorkBenchItem(7, "团队成员工时统计", "basic"),
+            new WorkBenchItem(9, "近期任务工时", "basic"),
+            new WorkBenchItem(10, "项目工时走势图", "basic")
+    };
+
+    class WorkBenchItem {
+        int id;
+        String name;
+        String module;
+
+        public WorkBenchItem(int id, String name, String module) {
+            this.id = id;
+            this.name = name;
+            this.module = module;
+        }
+    }
+    @Override
+    public JSONArray getMyWorkbench(String userId) {
+        UserWorkbench userWorkbench = userWorkbenchMapper.selectById(userId);
+        JSONArray array = new JSONArray();
+        if (userWorkbench == null) {
+            //返回默认的前四个模块
+            for (int i = 0; i < WORKBENCH_MODULES.length; i++) {
+                if (i < 4) {
+                    JSONObject object = new JSONObject();
+                    object.put("id", WORKBENCH_MODULES[i].id);
+                    object.put("position", i/2+","+(i)%2);
+                    object.put("size", 1);
+                    array.add(object);
+                }
+            }
+        } else {
+            String workbench = userWorkbench.getTableList();
+            array = JSONArray.parseArray(workbench);
+        }
+        return array;
+    }
+}

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/MessageUtils.java

@@ -21,7 +21,7 @@ public class MessageUtils {
     public static String message(String code, Object... args) {
     public static String message(String code, Object... args) {
         MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
         MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
         Locale locale = LocaleContextHolder.getLocale();
         Locale locale = LocaleContextHolder.getLocale();
-        System.out.println("本地为:" +locale.getDisplayName()+", code="+code);
+//        System.out.println("本地为:" +locale.getDisplayName()+", code="+code);
         return messageSource.getMessage(code, args, locale);
         return messageSource.getMessage(code, args, locale);
     }
     }
 
 

+ 4 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml

@@ -3,7 +3,7 @@ server:
   tomcat:
   tomcat:
     uri-encoding: utf-8
     uri-encoding: utf-8
     max-http-form-post-size: -1
     max-http-form-post-size: -1
-    connection-timeout: 18000000s
+    connection-timeout: 18000000
 spring:
 spring:
   servlet:
   servlet:
     multipart:
     multipart:
@@ -22,7 +22,9 @@ spring:
     hikari:
     hikari:
       maximum-pool-size: 60
       maximum-pool-size: 60
       minimum-idle: 10
       minimum-idle: 10
-      max-lifetime: 180000
+      # 空闲连接超时时间,3分钟
+      idle-timeout: 180000
+      max-lifetime: 1800000
       # 数据库连接超时时间,默认30秒,即30000
       # 数据库连接超时时间,默认30秒,即30000
       connection-timeout: 60000
       connection-timeout: 60000
       connection-test-query: SELECT 1
       connection-test-query: SELECT 1

+ 230 - 5
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml

@@ -1907,10 +1907,11 @@
         SELECT p.project_name AS projectName,p.id AS projectId,tg.id AS groupId,d.department_name,d.department_id AS deptId,d.corpwx_deptid AS corpwxDeptId,tg.name AS groupName,
         SELECT p.project_name AS projectName,p.id AS projectId,tg.id AS groupId,d.department_name,d.department_id AS deptId,d.corpwx_deptid AS corpwxDeptId,tg.name AS groupName,
         IFNULL(r.realHour,0) AS realHour,IFNULL(r.realCost,0) AS realCost,IFNULL(r.normalHour,0) as normalHour,IFNULL(r.overHour,0) as overHour,
         IFNULL(r.realHour,0) AS realHour,IFNULL(r.realCost,0) AS realCost,IFNULL(r.normalHour,0) as normalHour,IFNULL(r.overHour,0) as overHour,
         IFNULL(tg.man_day*8,0) AS planHour,IFNULL((SELECT SUM(change_man_day*8) FROM `group_budget_review` WHERE group_id=tg.`id` AND `status`=1),0) AS afterSetPlanHour
         IFNULL(tg.man_day*8,0) AS planHour,IFNULL((SELECT SUM(change_man_day*8) FROM `group_budget_review` WHERE group_id=tg.`id` AND `status`=1),0) AS afterSetPlanHour
-        FROM task_executor te
-        LEFT JOIN task t ON t.id=te.task_id
-        LEFT JOIN user u ON te.executor_id=u.id
-        LEFT JOIN task_group tg ON tg.id=t.group_id
+        FROM task_group tg
+        LEFT JOIN task t ON tg.id = t.group_id
+        LEFT JOIN task_executor te ON t.id = te.task_id
+        LEFT JOIN user u
+        ON te.executor_id = u.id
         LEFT JOIN project p ON p.id=tg.project_id
         LEFT JOIN project p ON p.id=tg.project_id
         LEFT JOIN department d ON d.department_id=u.department_id
         LEFT JOIN department d ON d.department_id=u.department_id
         LEFT JOIN (
         LEFT JOIN (
@@ -1920,7 +1921,7 @@
          AND create_date BETWEEN #{startDate} AND #{endDate}
          AND create_date BETWEEN #{startDate} AND #{endDate}
         </if>
         </if>
         AND project_id IS NOT NULL AND company_id=#{companyId} GROUP BY group_id,dept_id) r ON r.group_id=tg.`id` and r.dept_id=u.department_id
         AND project_id IS NOT NULL AND company_id=#{companyId} GROUP BY group_id,dept_id) r ON r.group_id=tg.`id` and r.dept_id=u.department_id
-        WHERE u.company_id=#{companyId}
+        WHERE p.company_id=#{companyId}
         AND tg.name IN ('生产部电气','生产部车间','工程部现场安装施工','工程部配合调试','研发部工艺设计','研发部结构设计','研发部BIM设计','研发部电气设计','研发部工艺调试验收','研发部电气调试验收')
         AND tg.name IN ('生产部电气','生产部车间','工程部现场安装施工','工程部配合调试','研发部工艺设计','研发部结构设计','研发部BIM设计','研发部电气设计','研发部工艺调试验收','研发部电气调试验收')
         <if test="userId!=null and userId!=''">
         <if test="userId!=null and userId!=''">
             and t.executor_id=#{userId}
             and t.executor_id=#{userId}
@@ -1969,6 +1970,230 @@
          GROUP BY t.groupName
          GROUP BY t.groupName
     </select>
     </select>
 
 
+    <select id="groupExpendProcessListForUser" resultType="java.util.Map">
+        SELECT departmentId, departmentName,jobNumber,userName,
+        SUM(CASE WHEN groupName='方案设计' THEN workTime ELSE 0 END) AS '方案设计' ,
+        SUM(CASE WHEN groupName='研发部' THEN workTime ELSE 0 END) AS '研发部' ,
+        SUM(CASE WHEN groupName='研发部工艺调试' THEN workTime ELSE 0 END) AS '研发部工艺调试',
+        SUM(CASE WHEN groupName='研发部工艺调试验收' THEN workTime ELSE 0 END) AS '研发部工艺调试验收' ,
+        SUM(CASE WHEN groupName='研发部工艺设计' THEN workTime ELSE 0 END) AS '研发部工艺设计' ,
+        SUM(CASE WHEN groupName='研发部结构设计' THEN workTime ELSE 0 END) AS '研发部结构设计' ,
+        SUM(CASE WHEN groupName='研发部BIM设计' THEN workTime ELSE 0 END) AS '研发部BIM设计' ,
+        SUM(CASE WHEN groupName='研发部电气调试验收' THEN workTime ELSE 0 END) AS '研发部电气调试验收' ,
+        SUM(CASE WHEN groupName='研发部电气设计' THEN workTime ELSE 0 END) AS '研发部电气设计' ,
+        SUM(CASE WHEN groupName='研发部售后' THEN workTime ELSE 0 END) AS '研发部售后' ,
+        SUM(CASE WHEN groupName='工程部配合运维' THEN workTime ELSE 0 END) AS '工程部配合运维' ,
+        SUM(CASE WHEN groupName='研发部运维' THEN workTime ELSE 0 END) AS '研发部运维' ,
+        SUM(CASE WHEN groupName='生产部' THEN workTime ELSE 0 END) AS '生产部' ,
+        SUM(CASE WHEN groupName='生产部车间' THEN workTime ELSE 0 END) AS '生产部车间' ,
+        SUM(CASE WHEN groupName='生产部电气' THEN workTime ELSE 0 END) AS '生产部电气' ,
+        SUM(CASE WHEN groupName='工程部配合调试' THEN workTime ELSE 0 END) AS '工程部配合调试' ,
+        SUM(CASE WHEN groupName='工程部' THEN workTime ELSE 0 END) AS '工程部' ,
+        SUM(CASE WHEN groupName='工程部售后' THEN workTime ELSE 0 END) AS '工程部售后' ,
+        SUM(CASE WHEN groupName='工程部现场安装施工' THEN workTime ELSE 0 END) AS '工程部现场安装施工',
+        IFNULL(SUM(workTime),0) AS totalWorkTime
+        FROM (
+            SELECT  d.`department_id` AS departmentId,d.`department_name` AS departmentName,u.`job_number` AS jobNumber,u.`name` AS userName ,tg.name AS groupName,rr.realHour AS workTime,u.id
+            FROM task_executor te
+            LEFT JOIN task t ON t.id=te.task_id
+            LEFT JOIN `user` u ON te.executor_id=u.id
+            LEFT JOIN task_group tg ON tg.id=t.group_id
+            LEFT JOIN project p ON p.id=tg.project_id
+            LEFT JOIN department d ON d.department_id=u.department_id
+            LEFT JOIN (
+            SELECT r.creator_id AS creatorId,SUM(r.working_time) AS realHour,tg.id AS groupId
+            FROM report r
+            LEFT JOIN task_group tg ON r.group_id=tg.`id`
+            WHERE r.state=1 AND r.project_id IS NOT NULL
+            <if test="startDate!=null and startDate!='' and endDate!=null and endDate!=''">
+                AND r.create_date  BETWEEN #{startDate} AND #{endDate}
+            </if>  AND r.company_id=#{companyId}
+            GROUP BY r.creator_id,tg.id ) rr ON rr.groupId=tg.`id` AND rr.creatorId=u.id
+            WHERE u.company_id=#{companyId}
+            <if test="listThird!=null and listThird.size()>0">
+                AND tg.project_id in
+                <foreach collection="listThird" separator="," open="(" close=")" item="item">
+                    #{item}
+                </foreach>
+            </if>
+            AND tg.name IN ('方案设计','研发部','生产部','工程部','生产部电气','生产部车间','工程部现场安装施工','工程部配合调试','研发部工艺设计','研发部结构设计','研发部BIM设计','研发部电气设计','研发部工艺调试验收','研发部电气调试验收')
+            <if test="listFour!=null and listFour.size()>0">
+                and tg.name in
+                <foreach collection="listFour" close=")" open="(" separator="," item="item">
+                    #{item}
+                </foreach>
+            </if>
+            GROUP BY u.`id`,tg.id
+            ) AS t
+            <where>
+            <if test="listFive!=null and listFive.size()>0">
+                t.departmentId in
+                <foreach collection="listFive" close=")" open="(" separator="," item="item">
+                    #{item}
+                </foreach>
+            </if>
+            </where>
+            GROUP BY t.id
+            <if test="start!=null and size!=null">
+                limit #{start},#{size}
+            </if>
+    </select>
+
+    <select id="groupExpendProcessListForUserCount" resultType="java.lang.Integer">
+        select count(1) from (
+        SELECT departmentId,departmentName,jobNumber,userName,IFNULL(SUM(workTime),0) AS totalWorkTime
+        FROM (
+            SELECT d.`department_id` AS departmentId,d.`department_name` AS departmentName,u.`job_number` AS jobNumber,u.`name` AS userName ,tg.name AS groupName,rr.realHour AS workTime,u.id
+            FROM task_executor te
+            LEFT JOIN task t ON t.id=te.task_id
+            LEFT JOIN `user` u ON te.executor_id=u.id
+            LEFT JOIN task_group tg ON tg.id=t.group_id
+            LEFT JOIN project p ON p.id=tg.project_id
+            LEFT JOIN department d ON d.department_id=u.department_id
+            LEFT JOIN (
+            SELECT r.creator_id AS creatorId,SUM(r.working_time) AS realHour,tg.id AS groupId
+            FROM report r
+            LEFT JOIN task_group tg ON r.group_id=tg.`id`
+            WHERE r.state=1 AND r.project_id IS NOT NULL
+            <if test="startDate!=null and startDate!='' and endDate!=null and endDate!=''">
+                AND r.create_date  BETWEEN #{startDate} AND #{endDate}
+            </if>  AND r.company_id=#{companyId}
+            GROUP BY r.creator_id,tg.id ) rr ON rr.groupId=tg.`id` AND rr.creatorId=u.id
+            WHERE u.company_id=#{companyId}
+            <if test="listThird!=null and listThird.size()>0">
+                AND tg.project_id in
+                <foreach collection="listThird" separator="," open="(" close=")" item="item">
+                    #{item}
+                </foreach>
+            </if>
+            AND tg.name IN ('方案设计','研发部','生产部','工程部','生产部电气','生产部车间','工程部现场安装施工','工程部配合调试','研发部工艺设计','研发部结构设计','研发部BIM设计','研发部电气设计','研发部工艺调试验收','研发部电气调试验收')
+            <if test="listFour!=null and listFour.size()>0">
+                and tg.name in
+                <foreach collection="listFour" close=")" open="(" separator="," item="item">
+                    #{item}
+                </foreach>
+            </if>
+            GROUP BY u.`id`,tg.id
+            ) AS t
+            <where>
+                <if test="listFive!=null and listFive.size()>0">
+                    t.departmentId in
+                    <foreach collection="listFive" close=")" open="(" separator="," item="item">
+                        #{item}
+                    </foreach>
+                </if>
+            </where>
+            GROUP BY t.id
+        ) as total
+    </select>
+
+    <select id="groupExpendProcessListForProject" resultType="java.util.Map">
+        SELECT projectName,projectId,projectCode,SUM(realHour) AS workTime  FROM (
+        SELECT p.project_name AS projectName,p.project_code as projectCode,p.id AS projectId,tg.id AS groupId,tg.name AS groupName,
+        IFNULL(r.realHour,0) AS realHour
+        FROM task_executor te
+        LEFT JOIN task t ON t.id=te.task_id
+        LEFT JOIN `user` u ON te.executor_id=u.id
+        LEFT JOIN task_group tg ON tg.id=t.group_id
+        LEFT JOIN project p ON p.id=tg.project_id
+        LEFT JOIN department d ON d.department_id=u.department_id
+        LEFT JOIN (
+        SELECT SUM(working_time) AS realHour,group_id,dept_id
+        FROM report  WHERE state=1
+        <if test="startDate!=null and startDate!='' and endDate!=null and endDate!=''">
+            AND create_date  BETWEEN #{startDate} AND #{endDate}
+        </if>
+        AND project_id IS NOT NULL AND company_id=#{companyId} GROUP BY group_id) r ON r.group_id=tg.`id`
+        WHERE u.company_id=#{companyId}
+        <if test="listThird!=null and listThird.size()>0">
+            AND tg.project_id in
+            <foreach collection="listThird" separator="," open="(" close=")" item="item">
+                #{item}
+            </foreach>
+        </if>
+        AND tg.name IN ('方案设计','研发部','生产部','工程部','生产部电气','生产部车间','工程部现场安装施工','工程部配合调试','研发部工艺设计','研发部结构设计','研发部BIM设计','研发部电气设计','研发部工艺调试验收','研发部电气调试验收')
+        <if test="listFour!=null and listFour.size()>0">
+            and tg.name in
+            <foreach collection="listFour" close=")" open="(" separator="," item="item">
+                #{item}
+            </foreach>
+        </if>
+        <if test="listFive!=null and listFive.size()>0">
+            and d.department_id in
+            <foreach collection="listFive" close=")" open="(" separator="," item="item">
+                #{item}
+            </foreach>
+        </if>
+        GROUP BY p.id,tg.id ORDER BY p.id,d.department_id) AS f
+        <where>
+            realHour>0
+            <if test="listThird!=null and listThird.size()>0">
+                and
+                projectId in
+                <foreach collection="listThird" separator="," open="(" close=")" item="item">
+                    #{item}
+                </foreach>
+            </if>
+        </where>
+        GROUP BY  projectId
+        <if test="start!=null and size!=null">
+            limit #{start},#{size}
+        </if>
+    </select>
+
+    <select id="groupExpendProcessListForProjectCount" resultType="java.lang.Integer">
+        select count(1) from (
+            SELECT projectName,projectId,projectCode,SUM(realHour) AS workTime  FROM (
+            SELECT p.project_name AS projectName,p.project_code as projectCode,p.id AS projectId,tg.id AS groupId,tg.name AS groupName,
+            IFNULL(r.realHour,0) AS realHour
+            FROM task_executor te
+            LEFT JOIN task t ON t.id=te.task_id
+            LEFT JOIN `user` u ON te.executor_id=u.id
+            LEFT JOIN task_group tg ON tg.id=t.group_id
+            LEFT JOIN project p ON p.id=tg.project_id
+            LEFT JOIN department d ON d.department_id=u.department_id
+            LEFT JOIN (
+            SELECT SUM(working_time) AS realHour,group_id,dept_id
+            FROM report  WHERE state=1
+            <if test="startDate!=null and startDate!='' and endDate!=null and endDate!=''">
+                AND create_date  BETWEEN #{startDate} AND #{endDate}
+            </if>
+            AND project_id IS NOT NULL AND company_id=#{companyId} GROUP BY group_id) r ON r.group_id=tg.`id`
+            WHERE u.company_id=#{companyId}
+            <if test="listThird!=null and listThird.size()>0">
+                AND tg.project_id in
+                <foreach collection="listThird" separator="," open="(" close=")" item="item">
+                    #{item}
+                </foreach>
+            </if>
+            AND tg.name IN ('方案设计','研发部','生产部','工程部','生产部电气','生产部车间','工程部现场安装施工','工程部配合调试','研发部工艺设计','研发部结构设计','研发部BIM设计','研发部电气设计','研发部工艺调试验收','研发部电气调试验收')
+            <if test="listFour!=null and listFour.size()>0">
+                and tg.name in
+                <foreach collection="listFour" close=")" open="(" separator="," item="item">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="listFive!=null and listFive.size()>0">
+                and d.department_id in
+                <foreach collection="listFive" close=")" open="(" separator="," item="item">
+                    #{item}
+                </foreach>
+            </if>
+            GROUP BY p.id,tg.id ORDER BY p.id,d.department_id) AS f
+            <where>
+                realHour>0
+                <if test="listThird!=null and listThird.size()>0">
+                    and
+                    projectId in
+                    <foreach collection="listThird" separator="," open="(" close=")" item="item">
+                        #{item}
+                    </foreach>
+                </if>
+            </where>
+            GROUP BY  projectId
+        ) as total
+    </select>
+
     <select id="projectExpendProcessList" resultType="java.util.Map">
     <select id="projectExpendProcessList" resultType="java.util.Map">
         select p.id AS projectId,p.project_name as projectName,DATE_FORMAT(p.`plan_start_date`,'%Y-%m-%d') AS planStartDate,DATE_FORMAT(p.`plan_end_date`,'%Y-%m-%d') AS planEndDate,pc.name as categoryName,p.project_code as projectCode,IFNULL(SUM(te.plan_hours),0) as planHour,
         select p.id AS projectId,p.project_name as projectName,DATE_FORMAT(p.`plan_start_date`,'%Y-%m-%d') AS planStartDate,DATE_FORMAT(p.`plan_end_date`,'%Y-%m-%d') AS planEndDate,pc.name as categoryName,p.project_code as projectCode,IFNULL(SUM(te.plan_hours),0) as planHour,
         IFNULL((select SUM(working_time) from report where project_id=p.id and create_date BETWEEN #{startDate} AND #{endDate} and state=1),0) as realHour, IFNULL((select SUM(cost) from report where project_id=p.id and create_date BETWEEN #{startDate} AND #{endDate} and state=1),0) as realCost,
         IFNULL((select SUM(working_time) from report where project_id=p.id and create_date BETWEEN #{startDate} AND #{endDate} and state=1),0) as realHour, IFNULL((select SUM(cost) from report where project_id=p.id and create_date BETWEEN #{startDate} AND #{endDate} and state=1),0) as realCost,

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

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

File diff suppressed because it is too large
+ 4 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserMapper.xml


+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserWorkbenchMapper.xml

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

BIN
fhKeeper/formulahousekeeper/management-platform/费用报销导入模板.xlsx


+ 17 - 10
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/WxCorpInfoController.java

@@ -12,6 +12,7 @@ import com.management.platform.util.DateTimeUtil;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.HttpRespMsg;
 import org.springframework.http.*;
 import org.springframework.http.*;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.client.RestTemplate;
 import org.springframework.web.client.RestTemplate;
@@ -250,6 +251,10 @@ public class WxCorpInfoController {
                 JSONObject apply_data = info.getJSONObject("apply_data");
                 JSONObject apply_data = info.getJSONObject("apply_data");
                 System.out.println("获取到的单据信息===========>"+apply_data);
                 System.out.println("获取到的单据信息===========>"+apply_data);
                 JSONArray contents = apply_data.getJSONArray("contents");
                 JSONArray contents = apply_data.getJSONArray("contents");
+                int count = planService.count(new LambdaQueryWrapper<Plan>().eq(Plan::getTaskChangeNoticeNum, info.getString("sp_no")));
+                if(count>0){
+                    continue;
+                }
                 //生成 车间插单计划
                 //生成 车间插单计划
                 Plan plan=new Plan();
                 Plan plan=new Plan();
                 plan.setCompanyId(7);
                 plan.setCompanyId(7);
@@ -347,17 +352,14 @@ public class WxCorpInfoController {
                             plan.setEndDate(localDateFromUnix);
                             plan.setEndDate(localDateFromUnix);
                         }
                         }
                     }
                     }
-                    if(title.getJSONObject(0).getString("text").equals("工作时长")){
+                    if(title.getJSONObject(0).getString("text").equals("结算总时长")){
                         if(control.equals("Number")){
                         if(control.equals("Number")){
-                            double new_number = value.getDoubleValue("new_number");
-                            workTime=new_number;
+                            double new_number = StringUtils.isEmpty(value.getString("new_number")) ?0.0:value.getDoubleValue("new_number");
+                            BigDecimal bigDecimal = new BigDecimal(new_number);
+                            workTime=bigDecimal.doubleValue();
                         }
                         }
                     }
                     }
-                    BigDecimal bigDecimal = new BigDecimal(plan.getPlanManNum()==null?0:plan.getPlanManNum());
-                    //工时以分钟为单位 *60
-                    bigDecimal=bigDecimal.multiply(new BigDecimal(workTime));
-                    bigDecimal=bigDecimal.multiply(new BigDecimal(60));
-                    plan.setPlanWorkHour(bigDecimal.doubleValue());
+                    plan.setPlanWorkHour(workTime*60);
                     if(title.getJSONObject(0).getString("text").equals("所属工位")){
                     if(title.getJSONObject(0).getString("text").equals("所属工位")){
                         if(control.equals("Contact")){
                         if(control.equals("Contact")){
                             JSONArray departments = value.getJSONArray("departments");
                             JSONArray departments = value.getJSONArray("departments");
@@ -389,7 +391,11 @@ public class WxCorpInfoController {
                             JSONObject formula = value.getJSONObject("formula");
                             JSONObject formula = value.getJSONObject("formula");
                             if(!formula.getString("value").equals("")){
                             if(!formula.getString("value").equals("")){
                                 double formulaDoubleValue = formula.getDoubleValue("value");
                                 double formulaDoubleValue = formula.getDoubleValue("value");
-                                plan.setMoneyOfJob(new BigDecimal(formulaDoubleValue));
+                                BigDecimal bigDecimal = new BigDecimal(formulaDoubleValue);
+                                if(workTime>0){
+                                    BigDecimal divide = bigDecimal.divide(new BigDecimal(workTime), 0, RoundingMode.HALF_UP);
+                                    plan.setMoneyOfJob(divide);
+                                }
                             }
                             }
                         }
                         }
                     }
                     }
@@ -411,9 +417,10 @@ public class WxCorpInfoController {
                         report.setCreatorId(user.get().getId());
                         report.setCreatorId(user.get().getId());
                         report.setCreateTime(LocalDateTime.now());
                         report.setCreateTime(LocalDateTime.now());
                         BigDecimal bigDecimal = new BigDecimal(workTime);
                         BigDecimal bigDecimal = new BigDecimal(workTime);
+                        bigDecimal=bigDecimal.divide(new BigDecimal(plan.getPlanManNum()==null?0:plan.getPlanManNum()),1,RoundingMode.HALF_UP);
+                        report.setWorkingTime(bigDecimal.doubleValue());
                         bigDecimal=bigDecimal.multiply(price);
                         bigDecimal=bigDecimal.multiply(price);
                         report.setCost(bigDecimal);
                         report.setCost(bigDecimal);
-                        report.setWorkingTime(workTime);
                         report.setStatus(2);
                         report.setStatus(2);
                         report.setPlanId(plan.getId());
                         report.setPlanId(plan.getId());
                         report.setCompanyId(7);
                         report.setCompanyId(7);

+ 13 - 11
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java

@@ -202,18 +202,20 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                             planList.forEach(p->{
                             planList.forEach(p->{
                                 boolean match=true;
                                 boolean match=true;
                                 Optional<Map<String, Object>> planId = planRealTimeProgressList.stream().filter(plan -> plan.get("planId").equals(p.getId())).findFirst();
                                 Optional<Map<String, Object>> planId = planRealTimeProgressList.stream().filter(plan -> plan.get("planId").equals(p.getId())).findFirst();
-                                Map<String, Object> map = planId.get();
-                                BigDecimal planWorkTime = new BigDecimal(map.get("planWorkTime") == null ? 0 : Double.valueOf(String.valueOf(map.get("planWorkTime"))));
-                                BigDecimal nowWorkTime = new BigDecimal(map.get("nowWorkTime") == null ? 0 : Double.valueOf(String.valueOf(map.get("nowWorkTime"))));
-                                if(nowWorkTime.compareTo(BigDecimal.ZERO)!=0){
-                                    BigDecimal divide = nowWorkTime.divide(planWorkTime, 4, RoundingMode.HALF_UP);
-                                    if(divide.doubleValue()>1){
-                                        match=false;
+                                if(planId.isPresent()){
+                                    Map<String, Object> map = planId.get();
+                                    BigDecimal planWorkTime = new BigDecimal(map.get("planWorkTime") == null ? 0 : Double.valueOf(String.valueOf(map.get("planWorkTime"))));
+                                    BigDecimal nowWorkTime = new BigDecimal(map.get("nowWorkTime") == null ? 0 : Double.valueOf(String.valueOf(map.get("nowWorkTime"))));
+                                    if(nowWorkTime.compareTo(BigDecimal.ZERO)!=0){
+                                        BigDecimal divide = nowWorkTime.divide(planWorkTime, 4, RoundingMode.HALF_UP);
+                                        if(divide.doubleValue()>1){
+                                            match=false;
+                                        }
+                                    }
+                                    if(match){
+                                        p.setForemanName(manager.getName());
+                                        p.setForemanId(manager.getId());
                                     }
                                     }
-                                }
-                                if(match){
-                                    p.setForemanName(manager.getName());
-                                    p.setForemanId(manager.getId());
                                 }
                                 }
                             });
                             });
                             planService.updateBatchById(planList);
                             planService.updateBatchById(planList);

+ 17 - 6
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -4300,7 +4300,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             u.setTotalResult(String.format("%.2f",bigDecimal.doubleValue()) + "分钟 " + String.format("%.2f", cost) + "元");
             u.setTotalResult(String.format("%.2f",bigDecimal.doubleValue()) + "分钟 " + String.format("%.2f", cost) + "元");
             u.setTotalPlanResult(String.format("%.2f",planBigDecimal.doubleValue()) + "分钟 " + String.format("%.2f", planCost) + "元");
             u.setTotalPlanResult(String.format("%.2f",planBigDecimal.doubleValue()) + "分钟 " + String.format("%.2f", planCost) + "元");
             u.setTotalSurplusResult(String.format("%.2f",surplusBigDecimal.doubleValue()) + "分钟 " + String.format("%.2f", surplusCost) + "元");
             u.setTotalSurplusResult(String.format("%.2f",surplusBigDecimal.doubleValue()) + "分钟 " + String.format("%.2f", surplusCost) + "元");
-            u.setTotalTempResult(String.format("%.2f",tempBigDecimal.doubleValue()) + "小时 " + String.format("%.2f", tempCost) + "元");
+            u.setTotalTempResult(String.format("%.2f",tempBigDecimal.doubleValue()) + "分钟 " + String.format("%.2f", tempCost) + "元");
         }
         }
         resultMap.put("total",userIPage.getTotal());
         resultMap.put("total",userIPage.getTotal());
         resultMap.put("records",userList);
         resultMap.put("records",userList);
@@ -5037,12 +5037,23 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             item.add("");
             item.add("");
 //            item.add(String.valueOf(map.get("progress"))+"%");
 //            item.add(String.valueOf(map.get("progress"))+"%");
             item.add(String.valueOf(map.get("finishNum")));
             item.add(String.valueOf(map.get("finishNum")));
-            item.add(String.valueOf(map.get("workingTime")));
-            item.add(String.valueOf(map.get("unitPrice")));
+            if(planType==0){
+                item.add(String.valueOf(map.get("workingTime")));
+                item.add(String.valueOf(map.get("unitPrice")));
+            }else {
+                item.add(String.valueOf(map.get("workingTime"))+" h");
+                item.add((map.get("unitPrice")==null?0:String.valueOf(map.get("unitPrice")))+" 元/h");
+            }
             String cost = String.valueOf(map.get("cost"));
             String cost = String.valueOf(map.get("cost"));
-            BigDecimal finishNum = new BigDecimal(map.get("finishNum")==null?String.valueOf(0):String.valueOf(map.get("finishNum")));
-            finishNum=finishNum.multiply(new BigDecimal(map.get("unitPrice")==null?String.valueOf(0):String.valueOf(map.get("unitPrice")))).setScale(2,RoundingMode.HALF_UP);
-            item.add(String.valueOf(finishNum.doubleValue()));
+            if(planType==0){
+                BigDecimal finishNum = new BigDecimal(map.get("finishNum")==null?String.valueOf(0):String.valueOf(map.get("finishNum")));
+                finishNum=finishNum.multiply(new BigDecimal(map.get("unitPrice")==null?String.valueOf(0):String.valueOf(map.get("unitPrice")))).setScale(2,RoundingMode.HALF_UP);
+                item.add(String.valueOf(finishNum.doubleValue()));
+            }else {
+                BigDecimal workingTime = new BigDecimal(map.get("workingTime")==null?String.valueOf(0):String.valueOf(map.get("workingTime")));
+                workingTime=workingTime.multiply(new BigDecimal(map.get("unitPrice")==null?String.valueOf(0):String.valueOf(map.get("unitPrice")))).setScale(2,RoundingMode.HALF_UP);
+                item.add(String.valueOf(workingTime.doubleValue()));
+            }
 //            item.add(cost);
 //            item.add(cost);
             item.add(String.valueOf(map.get("userName")));
             item.add(String.valueOf(map.get("userName")));
             item.add(String.valueOf(map.get("createDate")));
             item.add(String.valueOf(map.get("createDate")));

+ 17 - 11
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/task/TimingTask.java

@@ -356,7 +356,7 @@ public class TimingTask {
             return;
             return;
         }
         }
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
-        LocalDate start=LocalDate.now().minusDays(1);
+        LocalDate start=LocalDate.now().minusDays(7);
         LocalDate end=LocalDate.now();
         LocalDate end=LocalDate.now();
         JSONArray jsonArrayFilter = new JSONArray();
         JSONArray jsonArrayFilter = new JSONArray();
         JSONObject filter1 = new JSONObject();
         JSONObject filter1 = new JSONObject();
@@ -393,6 +393,10 @@ public class TimingTask {
                 System.out.println("获取到的单据信息===========>"+apply_data);
                 System.out.println("获取到的单据信息===========>"+apply_data);
                 JSONArray contents = apply_data.getJSONArray("contents");
                 JSONArray contents = apply_data.getJSONArray("contents");
                 //生成 车间插单计划
                 //生成 车间插单计划
+                int count = planService.count(new LambdaQueryWrapper<Plan>().eq(Plan::getTaskChangeNoticeNum, info.getString("sp_no")));
+                if(count>0){
+                    continue;
+                }
                 Plan plan=new Plan();
                 Plan plan=new Plan();
                 plan.setCompanyId(7);
                 plan.setCompanyId(7);
                 plan.setCreateTime(LocalDateTime.now());
                 plan.setCreateTime(LocalDateTime.now());
@@ -488,17 +492,14 @@ public class TimingTask {
                             plan.setEndDate(localDateFromUnix);
                             plan.setEndDate(localDateFromUnix);
                         }
                         }
                     }
                     }
-                    if(title.getJSONObject(0).getString("text").equals("工作时长")){
+                    if(title.getJSONObject(0).getString("text").equals("结算总时长")){
                         if(control.equals("Number")){
                         if(control.equals("Number")){
-                            double new_number = value.getDoubleValue("new_number");
-                            workTime=new_number;
+                            double new_number = StringUtils.isEmpty(value.getString("new_number")) ?0.0:value.getDoubleValue("new_number");
+                            BigDecimal bigDecimal = new BigDecimal(new_number);
+                            workTime=bigDecimal.doubleValue();
                         }
                         }
                     }
                     }
-                    BigDecimal bigDecimal = new BigDecimal(plan.getPlanManNum()==null?0:plan.getPlanManNum());
-                    //工时以分钟为单位 *60
-                    bigDecimal=bigDecimal.multiply(new BigDecimal(workTime));
-                    bigDecimal=bigDecimal.multiply(new BigDecimal(60));
-                    plan.setPlanWorkHour(bigDecimal.doubleValue());
+                    plan.setPlanWorkHour(workTime*60);
                     if(title.getJSONObject(0).getString("text").equals("所属工位")){
                     if(title.getJSONObject(0).getString("text").equals("所属工位")){
                         if(control.equals("Contact")){
                         if(control.equals("Contact")){
                             JSONArray departments = value.getJSONArray("departments");
                             JSONArray departments = value.getJSONArray("departments");
@@ -530,7 +531,11 @@ public class TimingTask {
                             JSONObject formula = value.getJSONObject("formula");
                             JSONObject formula = value.getJSONObject("formula");
                             if(!formula.getString("value").equals("")){
                             if(!formula.getString("value").equals("")){
                                 double formulaDoubleValue = formula.getDoubleValue("value");
                                 double formulaDoubleValue = formula.getDoubleValue("value");
-                                plan.setMoneyOfJob(new BigDecimal(formulaDoubleValue));
+                                BigDecimal bigDecimal = new BigDecimal(formulaDoubleValue);
+                                if(workTime>0){
+                                    BigDecimal divide = bigDecimal.divide(new BigDecimal(workTime), 0, RoundingMode.HALF_UP);
+                                    plan.setMoneyOfJob(divide);
+                                }
                             }
                             }
                         }
                         }
                     }
                     }
@@ -552,9 +557,10 @@ public class TimingTask {
                         report.setCreatorId(user.get().getId());
                         report.setCreatorId(user.get().getId());
                         report.setCreateTime(LocalDateTime.now());
                         report.setCreateTime(LocalDateTime.now());
                         BigDecimal bigDecimal = new BigDecimal(workTime);
                         BigDecimal bigDecimal = new BigDecimal(workTime);
+                        bigDecimal=bigDecimal.divide(new BigDecimal(plan.getPlanManNum()==null?0:plan.getPlanManNum()),1,RoundingMode.HALF_UP);
+                        report.setWorkingTime(bigDecimal.doubleValue());
                         bigDecimal=bigDecimal.multiply(price);
                         bigDecimal=bigDecimal.multiply(price);
                         report.setCost(bigDecimal);
                         report.setCost(bigDecimal);
-                        report.setWorkingTime(workTime);
                         report.setStatus(2);
                         report.setStatus(2);
                         report.setPlanId(plan.getId());
                         report.setPlanId(plan.getId());
                         report.setCompanyId(7);
                         report.setCompanyId(7);

+ 5 - 4
fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/ReportMapper.xml

@@ -139,10 +139,11 @@
         IFNULL(SUM(IF(a.`user_procedure_team_id`IS NOT NULL,a.cost,NULL)),0) AS cost,
         IFNULL(SUM(IF(a.`user_procedure_team_id`IS NOT NULL,a.cost,NULL)),0) AS cost,
         IFNULL(SUM(IF(a.`user_procedure_team_id` IS NOT NULL,a.working_time,NULL)),0) AS workTime,
         IFNULL(SUM(IF(a.`user_procedure_team_id` IS NOT NULL,a.working_time,NULL)),0) AS workTime,
         IFNULL(SUM(IF(a.`user_procedure_team_id`IS NULL,a.cost,NULL)),0) AS tempCost,
         IFNULL(SUM(IF(a.`user_procedure_team_id`IS NULL,a.cost,NULL)),0) AS tempCost,
-        IFNULL(SUM(IF(a.`user_procedure_team_id` IS NULL,a.working_time,NULL)),0) AS tempWorkTime
+        IFNULL(SUM(IF(a.`user_procedure_team_id` IS NULL,a.working_time*60,NULL)),0) AS tempWorkTime
         from report a
         from report a
         left join user b on a.creator_id=b.id
         left join user b on a.creator_id=b.id
         left join department c on c.department_id=b.department_id
         left join department c on c.department_id=b.department_id
+        left join plan p on p.id=a.plan_id
         where a.company_id=#{companyId}
         where a.company_id=#{companyId}
         <if test="list!=null and list.size()>0">
         <if test="list!=null and list.size()>0">
             and c.department_id in
             and c.department_id in
@@ -171,7 +172,7 @@
         left join plan on plan.id=r.plan_id
         left join plan on plan.id=r.plan_id
         left join user u on r.checker_id=u.id
         left join user u on r.checker_id=u.id
         left join user u2 on r.creator_id=u2.id
         left join user u2 on r.creator_id=u2.id
-        where r.company_id=#{companyId}  and r.finish_num &gt; 0
+        where r.company_id=#{companyId}  and ((plan.plan_type=0 and r.finish_num &gt; 0) || plan.plan_type=1)
         <if test="date!=null and date!=''">
         <if test="date!=null and date!=''">
             and r.create_date=#{date}
             and r.create_date=#{date}
         </if>
         </if>
@@ -191,7 +192,7 @@
     </select>
     </select>
 
 
     <select id="getPersonWorkHoursWagesDetailForTemp" resultType="java.util.Map">
     <select id="getPersonWorkHoursWagesDetailForTemp" resultType="java.util.Map">
-        select r.cost,r.working_time,r.finish_num, r.creator_id,DATE_FORMAT(r.create_date,'%Y%m%d') as createDate,
+        select r.cost,(r.working_time*60) as working_time,r.finish_num, r.creator_id,DATE_FORMAT(r.create_date,'%Y%m%d') as createDate,
         p.name as productName,DATE_FORMAT(plan.start_date,'%Y%m%d') as planStartDate,DATE_FORMAT(plan.end_date,'%Y%m%d') as planEndDate ,
         p.name as productName,DATE_FORMAT(plan.start_date,'%Y%m%d') as planStartDate,DATE_FORMAT(plan.end_date,'%Y%m%d') as planEndDate ,
         plan.task_change_notice_num as taskChangeNoticeNum,plan.plan_type as planType,u.name as checkerName,u2.name as creatorName,plan.task_name as taskName,plan.task_type_name
         plan.task_change_notice_num as taskChangeNoticeNum,plan.plan_type as planType,u.name as checkerName,u2.name as creatorName,plan.task_name as taskName,plan.task_type_name
         from report r
         from report r
@@ -255,7 +256,7 @@
         LEFT JOIN prod_procedure pp ON ppt.prod_procedure_id=pp.id
         LEFT JOIN prod_procedure pp ON ppt.prod_procedure_id=pp.id
         LEFT JOIN product p ON p.id=plan.product_id
         LEFT JOIN product p ON p.id=plan.product_id
         WHERE ppt2.company_id=#{companyId}
         WHERE ppt2.company_id=#{companyId}
-        AND r.sumReport &lt; ppt2.work_time
+        AND IFNULL(r.sumReport,0) &lt; ppt2.work_time AND ppt.total_progress &lt; 100
         <if test="date!=null and date!=''">
         <if test="date!=null and date!=''">
             and ppt2.distribute_date=#{date}
             and ppt2.distribute_date=#{date}
         </if>
         </if>

+ 92 - 0
fhKeeper/formulahousekeeper/timesheet-workshop/src/views/plan/orderInsert.vue

@@ -15,6 +15,8 @@
           </div>
           </div>
         </div>
         </div>
         <div class="OutSide_right">
         <div class="OutSide_right">
+          <el-link type="primary" :underline="false" @click="showReportingDialog()">{{ "同步临时报工"
+          }}</el-link>
           <el-link type="primary" :underline="false" @click="(taskTypeDialog = true)">{{ "任务类型管理"
           <el-link type="primary" :underline="false" @click="(taskTypeDialog = true)">{{ "任务类型管理"
           }}</el-link>
           }}</el-link>
           <el-link type="primary" :underline="false" @click="addPlan()">{{
           <el-link type="primary" :underline="false" @click="addPlan()">{{
@@ -222,6 +224,29 @@
       </span>
       </span>
     </el-dialog>
     </el-dialog>
 
 
+    <!-- 同步临时报工 -->
+    <el-dialog title="同步临时报工" :visible.sync="synchronousReportingDialog" width="600px" :before-close="handleClose">
+      <div class="tongbu">
+        <div :style="`color: ${reportWorkDayDisable ? 'red' : '#999'}`">选择的日期在三十天内</div>
+        <el-date-picker
+          v-model="reportWorkDay"
+          type="daterange"
+          value-format="yyyy-MM-dd"
+          :clearable="false"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          @change="handleDateChange">
+        </el-date-picker>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="
+          (synchronousReportingDialog = false)
+          ">取 消</el-button>
+        <el-button type="primary" :loading="reportWorkLoading" :disabled="reportWorkDayDisable" @click="reportWorkCli()">确定</el-button>
+      </span>
+    </el-dialog>
+
     <!-- 任务类型新增 -->
     <!-- 任务类型新增 -->
     <el-dialog title="新增任务类型" :visible.sync="taskTypeAddDialog" width="800" :before-close="handleClose">
     <el-dialog title="新增任务类型" :visible.sync="taskTypeAddDialog" width="800" :before-close="handleClose">
       <div>
       <div>
@@ -290,6 +315,10 @@ export default {
   },
   },
   data() {
   data() {
     return {
     return {
+      synchronousReportingDialog: false, 
+      reportWorkDay: [],
+      reportWorkDayDisable: false,
+      reportWorkLoading: false,
       steelStampNumber: "",
       steelStampNumber: "",
       todayDate: this.dayjs().format('YYYY-MM-DD'),
       todayDate: this.dayjs().format('YYYY-MM-DD'),
       planDate: this.dayjs().format('YYYY-MM-DD'),
       planDate: this.dayjs().format('YYYY-MM-DD'),
@@ -390,6 +419,55 @@ export default {
       this.getTaskTypeList();
       this.getTaskTypeList();
   },
   },
   methods: {
   methods: {
+    reportWorkCli() {
+      this.reportWorkLoading = true;
+      this.http.post(
+        "/wx-corp-info/testSyncTemporaryJobApplication",
+        { startDate: this.reportWorkDay[0], endDate: this.reportWorkDay[1] },
+        (res) => {
+          this.reportWorkLoading = false;
+          if (res.code == "ok") {
+            this.synchronousReportingDialog = false
+            this.$message({
+              message: '同步成功',
+              type: "success",
+            });
+            this.getTableData()
+          } else {
+            this.$message({
+              message: res.msg,
+              type: "error",
+            });
+          }
+        },
+        (error) => {
+          this.reportWorkLoading = false;
+          this.$message({
+            message: error,
+            type: "error",
+          });
+        }
+      );
+    },
+    // 显示临时报工
+    showReportingDialog() {
+      this.reportWorkDay = [this.dayjs().format('YYYY-MM-DD'), this.dayjs().format('YYYY-MM-DD')]
+      this.synchronousReportingDialog = true
+    },
+    handleDateChange(value) {
+      const startDate = value[0];
+      const endDate = value[1];
+      const d1 = this.dayjs(startDate);
+      const d2 = this.dayjs(endDate);
+      const diffDays = Math.abs(d1.diff(d2, 'day'));
+      if (diffDays > 30) {
+        this.reportWorkDayDisable = true
+        console.log('日期相隔超过三十天');
+      } else {
+        console.log('日期相隔不超过三十天');
+        this.reportWorkDayDisable = false
+      }
+    },
     // 初始化 Form
     // 初始化 Form
     initTodayPlanForm() {
     initTodayPlanForm() {
       this.todayPlanForm = {
       this.todayPlanForm = {
@@ -1058,6 +1136,20 @@ export default {
 };
 };
 </script>
 </script>
 <style scoped lang='scss'>
 <style scoped lang='scss'>
+
+.tongbu {
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  &>div {
+    margin-bottom: 15px;
+    color: #999;
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+}
 .colorText {
 .colorText {
   color: #02a7f0;
   color: #02a7f0;
   cursor: pointer;
   cursor: pointer;

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

@@ -94,7 +94,7 @@
                               <!-- <div @click.stop="showReportDetail(scope.row,item,0)" v-if="items.workTime>0">已填 {{items.workTime}}分钟  {{items.cost}}元 </div>{{items.leave}}
                               <!-- <div @click.stop="showReportDetail(scope.row,item,0)" v-if="items.workTime>0">已填 {{items.workTime}}分钟  {{items.cost}}元 </div>{{items.leave}}
                               <div style="color: green;" @click.stop="showTempReportDetail(scope.row,item,0)" v-if="items.tempWorkTime>0||items.tempCost>0">临时报工 {{items.tempWorkTime}}分钟  {{items.tempCost}}元</div> -->
                               <div style="color: green;" @click.stop="showTempReportDetail(scope.row,item,0)" v-if="items.tempWorkTime>0||items.tempCost>0">临时报工 {{items.tempWorkTime}}分钟  {{items.tempCost}}元</div> -->
                               <div  v-if="items.workTime>0">已填 {{items.workTime}}分钟  {{items.cost}}元 </div>{{items.leave}}
                               <div  v-if="items.workTime>0">已填 {{items.workTime}}分钟  {{items.cost}}元 </div>{{items.leave}}
-                              <div style="color: green;" v-if="items.tempWorkTime>0||items.tempCost>0">临时报工 {{items.tempWorkTime}}小时  {{items.tempCost}}元</div>
+                              <div style="color: green;" v-if="items.tempWorkTime>0||items.tempCost>0">临时报工 {{items.tempWorkTime}}分钟  {{items.tempCost}}元</div>
                               <div style="color: red;" v-if="items.surplusTime">剩余 {{items.surplusTime}}分钟  {{items.surplusCost}}元</div>
                               <div style="color: red;" v-if="items.surplusTime">剩余 {{items.surplusTime}}分钟  {{items.surplusCost}}元</div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -393,7 +393,7 @@
               <el-table-column prop="checkerName" label="质检人" width="180"></el-table-column>
               <el-table-column prop="checkerName" label="质检人" width="180"></el-table-column>
               <el-table-column prop="working_time" label="工作时长" width="180">
               <el-table-column prop="working_time" label="工作时长" width="180">
                 <template slot-scope="scope" v-if="scope.row.working_time">
                 <template slot-scope="scope" v-if="scope.row.working_time">
-                  {{scope.row.working_time}}{{scope.row.planType==0?'分钟':'小时'}}
+                  {{scope.row.working_time}}{{'分钟'}}
                 </template>
                 </template>
               </el-table-column>
               </el-table-column>
             </el-table>
             </el-table>

+ 5 - 0
fhKeeper/formulahousekeeper/timesheet/src/components/echartsEchar.vue

@@ -53,6 +53,11 @@ export default {
       return new Date().getTime();
       return new Date().getTime();
     },
     },
   },
   },
+  beforeDestroy() {
+    if (this.myChart) {
+      this.myChart.dispose();
+    }
+  }
 };
 };
 </script>
 </script>
 
 

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/http.js

@@ -2,7 +2,7 @@ import axios from 'axios'
 import qs from 'qs'
 import qs from 'qs'
 import imgPath from "@/assets/image/jiazai.gif"
 import imgPath from "@/assets/image/jiazai.gif"
 
 
-const TIME_OUT_MS = 180 * 1000 // 默认请求超时时间
+const TIME_OUT_MS = 600 * 1000 // 默认请求超时时间
 
 
 function prompt() {
 function prompt() {
     window.ELEMENT.Message({
     window.ELEMENT.Message({

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

@@ -29,7 +29,8 @@
     "caiwushenhe": "Financial review",
     "caiwushenhe": "Financial review",
     "basicDataManagement": "Basic data management",
     "basicDataManagement": "Basic data management",
     "budgetReview": "Estimated working hours review",
     "budgetReview": "Estimated working hours review",
-    "projectFormSettings": "Project Form Settings"
+    "projectFormSettings": "Project Form Settings",
+    "userGroupManagement": "User group management"
   },
   },
   "role": {
   "role": {
     "ordinaryEmployees": "Ordinary employees",
     "ordinaryEmployees": "Ordinary employees",

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

@@ -29,7 +29,8 @@
     "projectFormSettings": "项目表单设置",
     "projectFormSettings": "项目表单设置",
     "budgetReview": "预估工时审核",
     "budgetReview": "预估工时审核",
     "gongshitongji": "工时统计表",
     "gongshitongji": "工时统计表",
-    "caiwushenhe": "财务审核"
+    "caiwushenhe": "财务审核",
+    "userGroupManagement": "用户分组管理"
   },
   },
   "role": {
   "role": {
     "ordinaryEmployees": "普通员工",
     "ordinaryEmployees": "普通员工",

+ 5 - 0
fhKeeper/formulahousekeeper/timesheet/src/permissions.js

@@ -145,6 +145,9 @@ const StringUtil = {
         importAudit: false, // 查看导审记录 //
         importAudit: false, // 查看导审记录 //
 
 
         customDataAll: false,// 查看全公司数值-自定义数值统计模块
         customDataAll: false,// 查看全公司数值-自定义数值统计模块
+
+        // 用户分组管理
+        userGroupManage: false,
         
         
     }
     }
     // console.log(arr);
     // console.log(arr);
@@ -277,6 +280,8 @@ const StringUtil = {
         arr[i] == '查看全部立项申请'  ? obj.projectApprovalView = true : ''
         arr[i] == '查看全部立项申请'  ? obj.projectApprovalView = true : ''
         arr[i] == '管理全部立项申请'  ? obj.projectApprovalEdit = true : ''
         arr[i] == '管理全部立项申请'  ? obj.projectApprovalEdit = true : ''
         arr[i] == '审核立项申请' ? obj.projectApprovalCheck = true : ''
         arr[i] == '审核立项申请' ? obj.projectApprovalCheck = true : ''
+
+        arr[i] == '用户分组管理' ? obj.userGroupManage = true : ''
     }
     }
     return obj
     return obj
   }
   }

+ 4 - 0
fhKeeper/formulahousekeeper/timesheet/src/routes.js

@@ -96,6 +96,9 @@ import budgetReview from './views/project/budgetReview'
 // 财务审核
 // 财务审核
 import financeAudit from './views/financeAudit/financeAudit.vue'
 import financeAudit from './views/financeAudit/financeAudit.vue'
 
 
+// 用户分组管理
+import userGrouping from './views/userGrouping/userGrouping.vue'
+
 Vue.use(Router)
 Vue.use(Router)
 
 
 export const fixedRouter = [
 export const fixedRouter = [
@@ -505,6 +508,7 @@ export const allRouters = [//组织架构
         children: [
         children: [
             { path: '/timetype', component: timetype, name: '系统基础设置', iconCls: 'iconfont firerock-iconxitong-', meta: { text: 'navigation.basicSystemSettings' }},
             { path: '/timetype', component: timetype, name: '系统基础设置', iconCls: 'iconfont firerock-iconxitong-', meta: { text: 'navigation.basicSystemSettings' }},
             { path: '/role', component: quanx, name: '角色权限管理', iconCls: 'iconfont firerock-iconquanxian1', meta: { text: 'navigation.roleRightsManagement' } },
             { path: '/role', component: quanx, name: '角色权限管理', iconCls: 'iconfont firerock-iconquanxian1', meta: { text: 'navigation.roleRightsManagement' } },
+            { path: '/userGrouping', component: userGrouping, name: '用户分组管理', iconCls: 'iconfont firerock-iconquanxian1', meta: { text: 'navigation.userGroupManagement' } },
             { path: '/projectForm', component: projectForm, name: '项目表单设置', iconCls: 'iconfont firerock-iconquanxian1', meta: { text: 'navigation.projectFormSettings' } },
             { path: '/projectForm', component: projectForm, name: '项目表单设置', iconCls: 'iconfont firerock-iconquanxian1', meta: { text: 'navigation.projectFormSettings' } },
         ],
         ],
         // 其他信息
         // 其他信息

+ 283 - 7
fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/echartsData.js

@@ -38,12 +38,6 @@ export function getGroupConsumption(nameList = [], actualPlan = [], actualSupple
           formatter: "{value} (h)",
           formatter: "{value} (h)",
         },
         },
       },
       },
-      {
-        type: "value",
-        axisLabel: {
-          formatter: "{value} (h)",
-        },
-      },
     ],
     ],
     series: [
     series: [
       {
       {
@@ -73,7 +67,6 @@ export function getGroupConsumption(nameList = [], actualPlan = [], actualSupple
       {
       {
         name: "汇总",
         name: "汇总",
         type: "line",
         type: "line",
-        yAxisIndex: 1,
         lineStyle: {
         lineStyle: {
           normal: {
           normal: {
             width: 3,
             width: 3,
@@ -84,4 +77,287 @@ export function getGroupConsumption(nameList = [], actualPlan = [], actualSupple
       },
       },
     ],
     ],
   }
   }
+}
+
+export function getPieEchartOption(titleName, datas = []) {
+  return {
+    title: {
+      text: titleName,
+      left: 'center',
+      top: 40
+    },
+    tooltip: {
+      trigger: 'item'
+    },
+    legend: {
+      orient: 'vertical',
+      left: 'left'
+    },
+    series: [
+      {
+        name: titleName,
+        type: 'pie',
+        radius: '50%',
+        data: datas,
+        emphasis: {
+          itemStyle: {
+            shadowBlur: 10,
+            shadowOffsetX: 0,
+            shadowColor: 'rgba(0, 0, 0, 0.5)'
+          }
+        }
+      }
+    ]
+  }
+}
+
+export function debounce(func, delay) {
+  let timer;
+  return function() {
+    const context = this;
+    const args = arguments;
+    clearTimeout(timer);
+    timer = setTimeout(() => {
+      func.apply(context, args);
+    }, delay);
+  };
+}
+
+export const fixedTaskGrouping = ['工程部现场安装施工', '工程部配合调试', '生产部电气', '生产部车间', '研发部BIM设计', '研发部工艺设计', '研发部工艺调试验收', '研发部电气设计', '研发部电气调试验收', '研发部结构设计']
+
+// 固定分组数据
+export const fixedGrouping = {
+  technology: { // 研发工艺
+    tableFileds: [
+      { label: '方案设计', filed: '方案设计' },
+      { label: '研发部', filed: '研发部' },
+      { label: '研发部工艺调试', filed: '研发部工艺调试' },
+      { label: '研发部工艺调试验收', filed: '研发部工艺调试验收' },
+      { label: '研发部工艺设计', filed: '研发部工艺设计' },
+      { label: '报价占比', filed: '报价占比', unit: '%' },
+      { label: '行政占比', filed: '行政占比', unit: '%'  },
+      { label: '项目设计占比', filed: '项目设计占比', unit: '%'  },
+    ],
+    tabPicFileds: [
+      { label: '方案设计', filed: '方案设计', title: '报价项目占比' },
+      // { label: '研发部', filed: '研发部', title: '行政项目占比' },
+      { label: '研发部工艺调试', filed: '研发部工艺调试', title: '项目设计占比' }
+    ],
+    proportion: [
+      { key: '报价占比', value: '方案设计' },
+      { key: '行政占比', value: '研发部' },
+      { key: '项目设计占比', value: '研发部工艺设计' },
+    ],
+    deptIds: '8754,8768',
+    name: '研发工艺',
+    tableKey: 1001
+  },
+  bim: { // 研发BIM
+    tableFileds: [
+      { label: '研发部', filed: '研发部' },
+      { label: '研发部BIM设计', filed: '研发部BIM设计' },
+      { label: '行政占比', filed: '行政占比', unit: '%'  },
+      { label: '设计占比', filed: '设计占比', unit: '%'  },
+    ],
+    tabPicFileds: [
+      // { label: '研发部', filed: '研发部', title: 'BIM行政工时占比' },
+      { label: '研发部BIM设计', filed: '研发部BIM设计', title: 'BIM设计项目占比' }
+    ],
+    proportion: [
+      { key: '行政占比', value: '研发部' },
+      { key: '设计占比', value: '研发部BIM设计' },
+    ],
+    deptIds: '8757',
+    name: '研发BIM',
+    tableKey: 1002,
+  },
+  structure: { // 研发结构
+    tableFileds: [
+      { label: '研发部', filed: '研发部' },
+      { label: '研发部结构设计', filed: '研发部结构设计' },
+      { label: '行政占比', filed: '行政占比', unit: '%'  },
+      { label: '设计占比', filed: '设计占比', unit: '%'  },
+    ],
+    tabPicFileds: [
+      // { label: '研发部', filed: '研发部', title: '研发行政工时占比' },
+      { label: '研发部结构设计', filed: '研发部结构设计', title: '结构设计项目占比' }
+    ],
+    proportion: [
+      { key: '行政占比', value: '研发部' },
+      { key: '设计占比', value: '研发部结构设计' },
+    ],
+    deptIds: '8758,8769',
+    name: '研发结构',
+    tableKey: 1003
+  },
+  electrical: { // 研发电气
+    tableFileds: [
+      { label: '研发部', filed: '研发部' },
+      { label: '研发部电气调试验收', filed: '研发电气调试验收' },
+      { label: '研发部电气设计', filed: '研发部电气设计' },
+      { label: '研发部售后', filed: '研发部售后' },
+      { label: '行政占比', filed: '行政占比', unit: '%'  },
+      { label: '设计占比', filed: '设计占比', unit: '%'  },
+      { label: '调试占比', filed: '调试占比', unit: '%'  },
+    ],
+    tabPicFileds: [
+      // { label: '研发部', filed: '研发部', title: '电气行政工时占比' },
+      { label: '研发部电气设计', filed: '研发部电气设计', title: '电气设计项目占比' },
+      { label: '研发部电气调试验收', filed: '研发部电气调试验收', title: '电气调试项目占比' }
+    ],
+    proportion: [
+      { key: '行政占比', value: '研发部' },
+      { key: '设计占比', value: '研发部电气设计' },
+      { key: '调试占比', value: '研发部电气调试验收' },
+    ],
+    deptIds: '8756,8770',
+    name: '研发电气',
+    tableKey: 1004
+  },
+  shakedown: { // 研发调试
+    tableFileds: [
+      { label: '研发部', filed: '研发部' },
+      { label: '研发部工艺调试', filed: '研发部工艺调试' },
+      { label: '研发部工艺调试验收', filed: '研发部工艺调试验收' },
+      { label: '研发部工艺设计', filed: '研发部工艺设计' },
+      { label: '研发部售后', filed: '研发部售后' },
+      { label: '研发部运维', filed: '研发部运维' },
+      { label: '行政占比', filed: '行政占比', unit: '%'  },
+      { label: '项目调试占比', filed: '项目调试占比', unit: '%'  },
+      { label: '售后占比', filed: '售后占比', unit: '%'  },
+    ],
+    tabPicFileds: [
+      // { label: '研发部', filed: '研发部', title: '研发调试行政工时占比' },
+      { label: '研发部工艺调试验收', filed: '研发部工艺调试验收', title: '调试项目占比' },
+      { label: '研发部售后', filed: '研发部售后', title: '售后项目占比' }
+    ],
+    proportion: [
+      { key: '行政占比', value: '研发部' },
+      { key: '项目调试占比', value: '研发部工艺调试验收' },
+      { key: '售后占比', value: '研发部售后' },
+    ],
+    deptIds: '8755',
+    name: '研发调试',
+    tableKey: 1005
+  },
+  produce: { // 生产部
+    tableFileds: [
+      { label: '生产部', filed: '生产部' },
+      { label: '生产部车间', filed: '生产部车间' },
+      { label: '生产部电气', filed: '生产部电气' },
+      { label: '行政占比', filed: '行政占比', unit: '%'  },
+      { label: '项目占比', filed: '项目占比', unit: '%'  },
+    ],
+    tabPicFileds: [
+      // { label: '研发部', filed: '研发部', title: '生产部行政工时占比' },
+      { label: '生产部车间,生产部电气', filed: '生产部车间,生产部电气', title: '生产项目占比' }
+    ],
+    proportion: [
+      { key: '行政占比', value: '生产部' },
+      { key: '项目占比', value: '生产部车间' },
+      { key: '项目占比', value: '生产部电气' },
+    ],
+    deptIds: '8762,8760,8761,8737,7903',
+    name: '生产部',
+    tableKey: 1006
+  },
+  engineering: { // 工程部
+    tableFileds: [
+      { label: '工程部', filed: '工程部' },
+      { label: '工程部配合调试', filed: '工程部配合调试' },
+      { label: '工程部配合运维', filed: '工程部配合运维' },
+      { label: '工程部售后', filed: '工程部售后' },
+      { label: '工程部现场安装施工', filed: '工程部现场安装施工' },
+      { label: '生产部', filed: '生产部' },
+      { label: '生产部车间', filed: '生产部车间' },
+      { label: '生产部电气', filed: '生产部电气' },
+      { label: '项目阶段', filed: '项目阶段' },
+      { label: '研发部工艺调试验收', filed: '研发部工艺调试验收' },
+      { label: '研发部运维', filed: '研发部运维' },
+      { label: '行政占比', filed: '行政占比', unit: '%'  },
+      { label: '配合调试占比', filed: '配合调试占比', unit: '%'  },
+      { label: '运维占比', filed: '运维占比', unit: '%'  },
+      { label: '售后占比', filed: '售后占比', unit: '%'  },
+      { label: '施工占比', filed: '施工占比', unit: '%'  },
+      { label: '施工占配合生产占比', filed: '施工占配合生产占比', unit: '%'  },
+      { label: '配合生产占比', filed: '配合生产占比', unit: '%'  },
+    ],
+    tabPicFileds: [
+      // { label: '工程部', filed: '工程部', title: '工程部行政工时占比' },
+      { label: '工程部配合调试', filed: '工程部配合调试', title: '配合调试工时占比' },
+      { label: '工程部售后', filed: '工程部售后', title: '售后占比' },
+      { label: '工程部配合运维', filed: '工程部配合运维', title: '运维占比' },
+      { label: '工程部现场安装施工', filed: '工程部现场安装施工', title: '施工占比' },
+      { label: '生产部,生产部车间,生产部电气', filed: '生产部,生产部车间,生产部电气', title: '配合生产占比' },
+    ],
+    proportion: [
+      { key: '行政占比', value: '工程部' },
+      { key: '配合调试占比', value: '工程部配合调试' },
+      { key: '运维占比', value: '工程部配合运维' },
+      { key: '售后占比', value: '工程部售后' },
+      { key: '施工占比', value: '工程部现场安装施工' },
+      { key: '配合生产占比', value: '生产部' },
+      { key: '配合生产占比', value: '生产部车间' },
+      { key: '配合生产占比', value: '生产部电气' },
+    ],
+    deptIds: '7460,8763,8764,8765,8766',
+    name: '工程部',
+    tableKey: 1007
+  },
+}
+
+// 更具计算返回对应的占比
+export const getProportion = (list, fixedKey) => {
+  const newList = JSON.parse(JSON.stringify(list))
+  const listItem = fixedGrouping[fixedKey]
+  const proportion = listItem.proportion
+  newList.forEach(item => {
+    proportion.forEach(proportionItem => {
+      if(!item[proportionItem.key]) {
+        item[proportionItem.key] = item[proportionItem.value]
+      } else {
+        item[proportionItem.key] += item[proportionItem.value]
+      }
+    })
+  })
+  newList.forEach(item => {
+    proportion.forEach(proportionItem => {
+      if(item[proportionItem.key] != 0) {
+        let num = (item[proportionItem.key] / item.totalWorkTime) * 100
+        item[proportionItem.key] = Number(num.toFixed(2))
+      }
+    })
+  })
+  return newList
+}
+
+// 汇总计算
+export const collectNUm = (list, fixedKey) => {
+  const newList = JSON.parse(JSON.stringify(list))
+  const listItem = fixedGrouping[fixedKey]
+  const proportion = listItem.proportion
+  let totalNum = list.reduce((prev, curr) => { // 总计值
+      return { totalWorkTime: prev.totalWorkTime + curr.totalWorkTime };
+  }, { totalWorkTime: 0 }).totalWorkTime
+  let returnedValue = {}
+  newList.forEach(item => {
+    proportion.forEach(proportionItem => {
+      if(!item[proportionItem.key]) {
+        item[proportionItem.key] = item[proportionItem.value]
+      } else {
+        item[proportionItem.key] += item[proportionItem.value]
+      }
+    })
+  })
+
+  proportion.forEach(proportionItem => {
+    returnedValue[proportionItem.key] = newList.reduce((prev, curr) => { // 总计值
+        return { [proportionItem.key]: prev[proportionItem.key] + curr[proportionItem.key] };
+    }, { [proportionItem.key]: 0 })[proportionItem.key]
+  })
+
+  return {
+    ...returnedValue,
+    totalNum: totalNum
+  }
 }
 }

+ 189 - 49
fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue

@@ -121,7 +121,7 @@
         <template v-if="ins == 24">
         <template v-if="ins == 24">
           <el-radio-group v-model="tabPosition" size="small" @input="getGroupConsumptionData">
           <el-radio-group v-model="tabPosition" size="small" @input="getGroupConsumptionData">
             <el-radio-button label="0">表格</el-radio-button>
             <el-radio-button label="0">表格</el-radio-button>
-            <el-radio-button label="1">柱状图</el-radio-button>
+            <el-radio-button label="1">图</el-radio-button>
           </el-radio-group>
           </el-radio-group>
         </template>
         </template>
           
           
@@ -139,7 +139,7 @@
           </el-option>
           </el-option>
         </el-select>
         </el-select>
 
 
-        <el-select v-if="ins == 24 && tabPosition == 1" v-model="groupConsumptionName" placeholder="请选择任务分组" clearable filterable size="small" @change="getList(true)" multiple collapse-tags style="margin-left:10px; width: 250px">
+        <el-select v-if="ins == 24 && tabPosition == 1" v-model="groupConsumptionName" placeholder="请选择任务分组" :clearable="tabsType == 'all' ? true : false" filterable size="small" @change="getList(true)" :multiple="tabsType == 'all' ? true : false" collapse-tags style="margin-left:10px; width: 250px" :key="groupTaskKey">
           <el-option v-for="(item, index) in groupConsumptionList" :key="item.id" :label="item" :value="item"> </el-option>
           <el-option v-for="(item, index) in groupConsumptionList" :key="item.id" :label="item" :value="item"> </el-option>
         </el-select>
         </el-select>
 
 
@@ -217,7 +217,7 @@
       </div>
       </div>
       <!-- <p :style="ins == 9 ? 'float: right;margin-right: 25px;width:20%' : 'float: right;margin-right: 25px;width:10%'" > -->
       <!-- <p :style="ins == 9 ? 'float: right;margin-right: 25px;width:20%' : 'float: right;margin-right: 25px;width:10%'" > -->
       <p :style="`${ins == 9 || ins == 14 || ins == 21 ? 'width: 20%' : 'width: 10%'}`" class="tableRightBtn">
       <p :style="`${ins == 9 || ins == 14 || ins == 21 ? 'width: 20%' : 'width: 10%'}`" class="tableRightBtn">
-        <el-button type="primary" @click="exportExcel" size="mini">{{ $t('reporderived') }}</el-button>
+        <el-button type="primary" :loading="exportReportLoading" @click="exportExcel" size="mini">{{ $t('reporderived') }}</el-button>
         <el-button type="primary" @click="fillAll" size="mini" v-if="ins == 14">{{ $t('quanBuBuZu') }}</el-button>
         <el-button type="primary" @click="fillAll" size="mini" v-if="ins == 14">{{ $t('quanBuBuZu') }}</el-button>
         <el-button type="primary" @click="exportExcelByQuarter" size="mini" v-if="ins == 9 && user.companyId == 876">{{ $t('an-ji-du-dao-chu') }}</el-button>
         <el-button type="primary" @click="exportExcelByQuarter" size="mini" v-if="ins == 9 && user.companyId == 876">{{ $t('an-ji-du-dao-chu') }}</el-button>
         <el-button type="primary" @click="setWarning" size="mini" v-if="ins == 21">{{ $t('sheZhiYuJing') }}</el-button>
         <el-button type="primary" @click="setWarning" size="mini" v-if="ins == 21">{{ $t('sheZhiYuJing') }}</el-button>
@@ -1170,39 +1170,115 @@
               <el-table-column align="center" prop="projectCode" :label="$t('Itemno')"></el-table-column>
               <el-table-column align="center" prop="projectCode" :label="$t('Itemno')"></el-table-column>
               <el-table-column align="center" prop="residueTime" :label="$t('shengYuGongShiH')" width="150"></el-table-column>
               <el-table-column align="center" prop="residueTime" :label="$t('shengYuGongShiH')" width="150"></el-table-column>
             </el-table>
             </el-table>
+            <div class="packetConsumption" v-if="ins == 24" :style="`height:${tabPosition == 0 ? tableHeight : tableHeight + 50}px`" v-loading="listLoading">
+              <el-tabs v-model="tabsType" :tab-position="'left'" @tab-click="handleClick" 
+              :style="`height: 100%;width: 100%;margin-right: 20px`">
+                <el-tab-pane name="all" label="分组耗用表">
+                  <PackTables :datas="{ 
+                    type: tabsType, 
+                    tabPosition: tabPosition,
+                    list: isbeCustomReport.consumptionSchedule,
+                    height: tableHeight,
+                    listArr1,
+                    listArr2,
+                    listArr3,
+                    params: {
+                      groupNames: groupConsumptionName,
+                      projectIds: proJuctId,
+                      pageIndex: page,
+                      pageSize: size,
+                      dataTime: rangeDatas
+                    },
+                    echartsData: groupConsumptionOption
+                  }" />
+                </el-tab-pane>
+                <el-tab-pane name="technology" label="研发工艺">
+                  <PackTables :datas="{ type: tabsType, regular: 'technology', height: tableHeight, tabPosition, params: {
+                    projectIds: proJuctId,
+                    groupNames: groupConsumptionName,
+                    dataTime: rangeDatas
+                  } }" />
+                </el-tab-pane>
+                <el-tab-pane name="bim" label="研发BIM">
+                  <PackTables :datas="{ type: tabsType, regular: 'bim', height: tableHeight, tabPosition, params: {
+                    projectIds: proJuctId,
+                    groupNames: groupConsumptionName,
+                    dataTime: rangeDatas
+                  } }" />
+                </el-tab-pane>
+                <el-tab-pane name="structure" label="研发结构">
+                  <PackTables :datas="{ type: tabsType, regular: 'structure', height: tableHeight, tabPosition, params: {
+                    projectIds: proJuctId,
+                    groupNames: groupConsumptionName,
+                    dataTime: rangeDatas
+                  } }" />
+                </el-tab-pane>
+                <el-tab-pane name="electrical" label="研发电气">
+                  <PackTables :datas="{ type: tabsType, regular: 'electrical', height: tableHeight, tabPosition, params: {
+                    projectIds: proJuctId,
+                    groupNames: groupConsumptionName,
+                    dataTime: rangeDatas
+                  } }" />
+                </el-tab-pane>
+                <el-tab-pane name="shakedown" label="研发调试">
+                  <PackTables :datas="{ type: tabsType, regular: 'shakedown', height: tableHeight, tabPosition, params: {
+                    projectIds: proJuctId,
+                    groupNames: groupConsumptionName,
+                    dataTime: rangeDatas
+                  } }" />
+                </el-tab-pane>
+                <el-tab-pane name="produce" label="生产部">
+                  <PackTables :datas="{ type: tabsType, regular: 'produce', height: tableHeight, tabPosition, params: {
+                    projectIds: proJuctId,
+                    groupNames: groupConsumptionName,
+                    dataTime: rangeDatas
+                  } }" />
+                </el-tab-pane>
+                <el-tab-pane name="engineering" label="工程部">
+                  <PackTables :datas="{ type: tabsType, regular: 'engineering', height: tableHeight, tabPosition, params: {
+                    projectIds: proJuctId,
+                    groupNames: groupConsumptionName,
+                    dataTime: rangeDatas
+                  } }" />
+                </el-tab-pane>
+              </el-tabs>
+              <!-- <div>
 
 
-            <!-- 分组耗用进度表 -->
-            <el-table  v-if="ins == 24 && tabPosition==0" :key="24" border :data="isbeCustomReport.consumptionSchedule" highlight-current-row v-loading="listLoading" :height="(+tableHeight - 0) - 1" style="width: 100%;" :span-method="objectSpanMethod">
-              <el-table-column align="center" prop="projectName" :label="$t('headerTop.projectName')" min-width="200"></el-table-column>
-              <el-table-column align="center" prop="department_name" :label="$t('fuZeBuMen')" min-width="150">
-                <template slot-scope="scope">
-                  <div>
-                    <span v-if="user.userNameNeedTranslate == '1'">
-                      <TranslationOpenDataText type='departmentName' :openid='scope.row.corpwxDeptId'></TranslationOpenDataText>
-                    </span>
-                    <span v-if="user.userNameNeedTranslate != '1'">
-                      {{scope.row.departmentName}}
-                    </span>
-                    <!-- {{ scope.row.corpwxDeptId }} -->
-                  </div>
-                </template>
-              </el-table-column>
-              <el-table-column align="center" prop="groupName" :label="$t('lable.taskGrouping')" min-width="150"></el-table-column>
-              <el-table-column align="center" prop="planHour" :label="$t('jiHuaGongShiCaiWu')" width="120"></el-table-column>
-              <el-table-column align="center" :label="$t('shiJiGongShiChengBen')">
-                <el-table-column align="center" prop="afterSetPlanHour" :label="$t('zengBuGongShiH')" width="120"></el-table-column>
-                <el-table-column align="center" prop="normalHour" :label="$t('zhengChangGongShiH')" width="100"></el-table-column>
-                <el-table-column align="center" prop="overHour" :label="$t('jiaBanGongShiH')" width="100"></el-table-column>
-                <el-table-column align="center" prop="realHour" :label="$t('heJiGongShiH')" width="100"></el-table-column>
-                <el-table-column align="center" prop="realCost" :label="$t('heJiGongShiChengBen')" width="140"></el-table-column>
-              </el-table-column>
-              <el-table-column align="center" prop="process" :label="$t('gongShiHaoYongShuai')" width="150"></el-table-column>
-            </el-table>
+              </div>
+              <div class="packetConsumption-flex"></div> -->
+              <!-- 分组耗用进度表 -->
+              <!-- <el-table  v-if="ins == 24 && tabPosition==0" :key="24" border :data="isbeCustomReport.consumptionSchedule" highlight-current-row v-loading="listLoading" :height="(+tableHeight - 0) - 1" style="width: 100%;" :span-method="objectSpanMethod">
+                <el-table-column align="center" prop="projectName" :label="$t('headerTop.projectName')" min-width="200"></el-table-column>
+                <el-table-column align="center" prop="department_name" :label="$t('fuZeBuMen')" min-width="150">
+                  <template slot-scope="scope">
+                    <div>
+                      <span v-if="user.userNameNeedTranslate == '1'">
+                        <TranslationOpenDataText type='departmentName' :openid='scope.row.corpwxDeptId'></TranslationOpenDataText>
+                      </span>
+                      <span v-if="user.userNameNeedTranslate != '1'">
+                        {{scope.row.departmentName}}
+                      </span>
+                    </div>
+                  </template>
+                </el-table-column>
+                <el-table-column align="center" prop="groupName" :label="$t('lable.taskGrouping')" min-width="150"></el-table-column>
+                <el-table-column align="center" prop="planHour" :label="$t('jiHuaGongShiCaiWu')" width="120"></el-table-column>
+                <el-table-column align="center" :label="$t('shiJiGongShiChengBen')">
+                  <el-table-column align="center" prop="afterSetPlanHour" :label="$t('zengBuGongShiH')" width="120"></el-table-column>
+                  <el-table-column align="center" prop="normalHour" :label="$t('zhengChangGongShiH')" width="100"></el-table-column>
+                  <el-table-column align="center" prop="overHour" :label="$t('jiaBanGongShiH')" width="100"></el-table-column>
+                  <el-table-column align="center" prop="realHour" :label="$t('heJiGongShiH')" width="100"></el-table-column>
+                  <el-table-column align="center" prop="realCost" :label="$t('heJiGongShiChengBen')" width="140"></el-table-column>
+                </el-table-column>
+                <el-table-column align="center" prop="process" :label="$t('gongShiHaoYongShuai')" width="150"></el-table-column>
+              </el-table> -->
 
 
-            <!-- 分组耗用进度图表 -->
-            <div v-if="ins == 24 && tabPosition!=0" class="useASchedule" :style="`height:${tableHeight + 50}px`" v-loading="groupConsumptionLoading">
-              <EchartsEchar :options="groupConsumptionOption"></EchartsEchar>
+              <!-- 分组耗用进度图表 -->
+              <!-- <div v-if="ins == 24 && tabPosition == 1 && tabsType == 'all'" class="useASchedule" :style="`height:${tableHeight + 50}px;width: 100%`" v-loading="groupConsumptionLoading">
+                <EchartsEchar :options="groupConsumptionOption"></EchartsEchar>
+              </div> -->
             </div>
             </div>
+            
 
 
             <!-- 项目耗用进度表 -->
             <!-- 项目耗用进度表 -->
             <el-table  v-if="ins == 25" :key="25" border :data="isbeCustomReport.consumptionScheduleTwo" highlight-current-row v-loading="listLoading" :height="(+tableHeight) - 1" style="width: 100%;" >
             <el-table  v-if="ins == 25" :key="25" border :data="isbeCustomReport.consumptionScheduleTwo" highlight-current-row v-loading="listLoading" :height="(+tableHeight) - 1" style="width: 100%;" >
@@ -1330,7 +1406,7 @@
               <el-table-column align="center" prop="onTimePercent" :label="$t('anShiWanChengShuai')" min-width="150"></el-table-column>
               <el-table-column align="center" prop="onTimePercent" :label="$t('anShiWanChengShuai')" min-width="150"></el-table-column>
             </el-table>
             </el-table>
         <!--工具条-->
         <!--工具条-->
-        <el-col :span="24" class="toolbar" v-if="ins != 6 && ins != 20 && ins != 21 && tabPosition==0">
+        <el-col :span="24" class="toolbar" v-if="ins != 6 && ins != 20 && ins != 21 && tabPosition==0 && tabsType == 'all'">
           <el-pagination
           <el-pagination
                 v-if="ins == 12"
                 v-if="ins == 12"
                 @size-change="groupSizeChange"
                 @size-change="groupSizeChange"
@@ -1647,14 +1723,16 @@ import selectCat from "@/components/select.vue"
 // 引入自定义级联组件
 // 引入自定义级联组件
 import vueCascader from "@/components/cascader.vue"
 import vueCascader from "@/components/cascader.vue"
 import EchartsEchar from "@/components/echartsEchar.vue"
 import EchartsEchar from "@/components/echartsEchar.vue"
-import { getGroupConsumption } from "./echartsData"
+import { getGroupConsumption, fixedTaskGrouping, fixedGrouping } from "./echartsData"
+import PackTables from "./packetConsumption/tables.vue"
 
 
 export default {
 export default {
   name: "expense",
   name: "expense",
   components: {
   components: {
     selectCat,
     selectCat,
     vueCascader,
     vueCascader,
-    EchartsEchar
+    EchartsEchar,
+    PackTables
   },
   },
   props: {},
   props: {},
   data() {
   data() {
@@ -1885,9 +1963,13 @@ export default {
       // 分组耗用进度图表
       // 分组耗用进度图表
       groupConsumptionOption: {},
       groupConsumptionOption: {},
       groupConsumptionLoading: false,
       groupConsumptionLoading: false,
-      groupConsumptionList: ['工程部现场安装施工', '工程部配合调试', '生产部电气', '生产部车间', '研发部BIM设计', '研发部工艺设计', '研发部工艺调试验收', '研发部电气设计', '研发部电气调试验收', '研发部结构设计'],
+      groupConsumptionList: fixedTaskGrouping,
       groupConsumptionName: [],
       groupConsumptionName: [],
-      groupConsumptionTimer: null
+      groupConsumptionTimer: null,
+      tabsType: 'all',
+      tabParams: {},
+      groupTaskKey: 1,
+      exportReportLoading: false
     };
     };
   },
   },
   computed: {},
   computed: {},
@@ -1968,6 +2050,26 @@ export default {
       }
       }
   },
   },
   methods: {
   methods: {
+    handleClick() {
+      console.log(this.tabsType, '<==== 返回的书')
+      this.groupTaskKey++
+      if(this.tabsType == 'all') {
+        this.$set(this, 'groupConsumptionName', '')
+        this.$set(this, 'groupConsumptionList', fixedTaskGrouping)
+        this.$set(this, 'rangeDatas', null)
+        if(this.tabPosition == 1) {
+          this.getGroupConsumptionData()
+        } else {
+          this.getConsumptionSchedule()
+        }
+        return
+      }
+      this.rangeDatas = this.getCurrentRangeTime()
+      const type = this.tabsType
+      const list = fixedGrouping[type].tabPicFileds
+      this.groupConsumptionName = list[0].filed
+      this.groupConsumptionList = list.map(item => item.filed)
+    },
     authorityToJudge() {
     authorityToJudge() {
       if(this.permissions.reportProject || this.permissions.reportAllProject) {this.ssl(0);this.defaultActive = '1-1';return} else
       if(this.permissions.reportProject || this.permissions.reportAllProject) {this.ssl(0);this.defaultActive = '1-1';return} else
       if(this.permissions.reportTask || this.permissions.reportAllTask) {this.ssl(1);this.defaultActive = '1-2';return} else
       if(this.permissions.reportTask || this.permissions.reportAllTask) {this.ssl(1);this.defaultActive = '1-2';return} else
@@ -2273,7 +2375,9 @@ export default {
             getList(e) {
             getList(e) {
               let noUserList = [16, 17, 18, 19, 20, 21, 22, 24, 25, 26,27]
               let noUserList = [16, 17, 18, 19, 20, 21, 22, 24, 25, 26,27]
               if(this.ins == 24) {
               if(this.ins == 24) {
-                this.rangeDatas = []
+                if(this.tabsType == 'all') {
+                  this.rangeDatas = []
+                }
               } else if(this.ins == 15) {
               } else if(this.ins == 15) {
                 this.rangeDatas = null
                 this.rangeDatas = null
               } else if(!e){
               } else if(!e){
@@ -2535,11 +2639,24 @@ export default {
           this.userId ? sl.userId = this.userId : ''
           this.userId ? sl.userId = this.userId : ''
           dept ? sl.deptId = dept : ''
           dept ? sl.deptId = dept : ''
         } else if(this.ins == 24) {
         } else if(this.ins == 24) {
-          fName = this.$t('fenZuHaoYongJinDuBiao') + '.xlsx'
-          url = "/project/exportGroupExpendProcessList"
-          this.proJuctId ? sl.projectId = this.proJuctId : ''
-          sl.startDate = this.rangeDatas[0]
-          sl.endDate = this.rangeDatas[1]
+          this.exportReportLoading = true
+          if(this.tabsType == 'all') {
+            fName = this.$t('fenZuHaoYongJinDuBiao') + '.xlsx'
+            url = "/project/exportGroupExpendProcessList"
+            this.proJuctId ? sl.projectId = this.proJuctId : ''
+            sl.startDate = this.rangeDatas[0]
+            sl.endDate = this.rangeDatas[1]
+          } else {
+            const type = this.tabsType
+            const row = fixedGrouping[type]
+            const listText = row.tableFileds.map(item => item.label).join(',')
+            fName = row + '表' + '.xlsx'
+            url = "/project/exportGroupExpendProcessListForUser"
+            this.proJuctId ? sl.projectId = this.proJuctId : ''
+            sl.startDate = this.rangeDatas[0]
+            sl.endDate = this.rangeDatas[1]
+            sl.titleStr = (listText || '')+',所属部门,工号,员工,总计'
+          }
         } else if(this.ins == 25) {
         } else if(this.ins == 25) {
           fName = this.$t('xiangMuHaoYongJinDuBiao') + '.xlsx'
           fName = this.$t('xiangMuHaoYongJinDuBiao') + '.xlsx'
           url = "/project/exportProjectExpendProcessList"
           url = "/project/exportProjectExpendProcessList"
@@ -2572,6 +2689,7 @@ export default {
         }
         }
           this.http.post(url, sl,
           this.http.post(url, sl,
             res => {
             res => {
+                this.exportReportLoading = false
                 if (res.code == "ok") {
                 if (res.code == "ok") {
                     var filePath = res.data;
                     var filePath = res.data;
                     const a = document.createElement('a'); // 创建a标签
                     const a = document.createElement('a'); // 创建a标签
@@ -2587,6 +2705,7 @@ export default {
                 }
                 }
             },
             },
             error => {
             error => {
+                this.exportReportLoading = false
                 this.$message({
                 this.$message({
                     message: error,
                     message: error,
                     type: "error"
                     type: "error"
@@ -2651,6 +2770,7 @@ export default {
       this.userId = null
       this.userId = null
       this.selUserList = this.userList
       this.selUserList = this.userList
       this.tabPosition="0"
       this.tabPosition="0"
+      this.tabsType = 'all'
       this.getList();
       this.getList();
     },
     },
     stateKeySel(){
     stateKeySel(){
@@ -4176,6 +4296,9 @@ export default {
     },
     },
     // 分组耗用进度表
     // 分组耗用进度表
     async getConsumptionSchedule() {
     async getConsumptionSchedule() {
+      if(this.tabsType != 'all') {
+        return
+      }
       let parameter = {
       let parameter = {
         // startDate: this.rangeDatas[0],
         // startDate: this.rangeDatas[0],
         // endDate: this.rangeDatas[1],
         // endDate: this.rangeDatas[1],
@@ -4293,23 +4416,29 @@ export default {
         clearTimeout(this.groupConsumptionTimer)
         clearTimeout(this.groupConsumptionTimer)
       }
       }
       this.groupConsumptionTimer = setTimeout(async () => {
       this.groupConsumptionTimer = setTimeout(async () => {
+        if(this.tabsType != 'all') {
+          return
+        }
         if(this.tabPosition == 0) {
         if(this.tabPosition == 0) {
           this.proJuctId = ''
           this.proJuctId = ''
           return
           return
         }
         }
-        this.groupConsumptionLoading = true
+        // this.groupConsumptionLoading = true
+        this.listLoading = true
         let { data } = await this.postData('/project/groupExpendProcessListForChart', {
         let { data } = await this.postData('/project/groupExpendProcessListForChart', {
           startDate: this.rangeDatas[0],
           startDate: this.rangeDatas[0],
           endDate: this.rangeDatas[1],
           endDate: this.rangeDatas[1],
           projectIds: this.proJuctId,
           projectIds: this.proJuctId,
           groupNames: this.groupConsumptionName.join(',')
           groupNames: this.groupConsumptionName.join(',')
         })
         })
-        this.groupConsumptionLoading = false
+        // this.groupConsumptionLoading = false
+        this.listLoading = false
         let nameList = data.map(item => (item.groupName || ''))
         let nameList = data.map(item => (item.groupName || ''))
         let realHourList = data.map(item => returnNum((item.realHour || 0)))
         let realHourList = data.map(item => returnNum((item.realHour || 0)))
-        let actualPlan = data.map(item => returnNum((item.planHour || 0)))
-        let actualSupplement = data.map(item => returnNum((item.afterSetPlanHour || 0)))
-        let summary = data.map(item => returnNum((item.planHour || 0)) + returnNum((item.realHour || 0)))
+        let actualPlan = data.map(item => returnNum((item.planHour || 0))) // 实际计划
+        let actualSupplement = data.map(item => returnNum((item.afterSetPlanHour || 0))) // 实际增补
+        let summary = data.map(item => returnNum((item.realHour || 0))) // 汇总
+        // let summary = data.map(item => returnNum((item.planHour || 0)) + returnNum((item.realHour || 0))) // 汇总
         this.groupConsumptionOption = getGroupConsumption(nameList, actualPlan, actualSupplement, summary, realHourList)
         this.groupConsumptionOption = getGroupConsumption(nameList, actualPlan, actualSupplement, summary, realHourList)
 
 
         function returnNum(num) {
         function returnNum(num) {
@@ -4548,4 +4677,15 @@ export default {
 .useASchedule {
 .useASchedule {
   width: 100%;
   width: 100%;
 }
 }
+
+.packetConsumption {
+  width: 100%;
+  display: flex;
+  &>div {
+    height: 100%;
+  }
+  .packetConsumption-flex {
+    flex: 1;
+  }
+}
 </style>
 </style>

+ 370 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/packetConsumption/tables.vue

@@ -0,0 +1,370 @@
+<template>
+  <div class="tabless">
+    <!-- 表格 -->
+    <template v-if="tabPosition != '1'">
+      <template v-if="types != 'all'">
+        <el-table :key="typesDataObj[types].tableKey" border :data="tableList" highlight-current-row :height="(+tableHeight - 0) - 1" style="width: 100%;" :span-method="objectSpanMethod" show-summary :summary-method="getSummaries" v-loading="tableLoading">
+          <el-table-column align="center" prop="departmentName" :label="'所属部门'" min-width="200" fixed="left">
+            <template slot-scope="scope">
+              <template v-for="(list, listIndex) in scope.row.departmentNameList">
+                <TranslationOpenDataText type='departmentName' :openid='list'></TranslationOpenDataText> <template v-if="listIndex < scope.row.departmentNameList.length - 1">/</template>
+              </template>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="userName" :label="'员工'" min-width="150" fixed="left">
+            <template slot-scope="scope">
+              <TranslationOpenDataText type='userName' :openid='scope.row.userName'></TranslationOpenDataText>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="jobNumber" :label="'工号'" min-width="150"></el-table-column>
+          <template v-for="(item, index) in typesDataObj[types].tableFileds">
+            <el-table-column align="center" :prop="item.filed" :label="`${item.label}${item.unit ? '' : '(h)'}`" min-width="170">
+              <template slot-scope="scope">
+                <div>
+                  <span v-if="!item.unit">{{ scope.row[item.filed] }}</span> 
+                  <el-progress :text-inside="true" :stroke-width="26" :percentage="scope.row[item.filed] || 0" :color="'#a7cef9'" v-else></el-progress>
+                </div>
+              </template>
+            </el-table-column>
+          </template>
+          <el-table-column align="center" prop="totalWorkTime" :label="'总计(h)'" min-width="150">
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row['totalWorkTime'] }}
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </template>
+
+      <!-- 单个 -->
+      <template v-if="types == 'all'">
+        <el-table :key="24" border :data="tableList" highlight-current-row :height="(+tableHeight - 0) - 1" style="width: 100%;" :span-method="objectSpanMethod">
+          <el-table-column align="center" prop="projectName" :label="$t('headerTop.projectName')" min-width="200"></el-table-column>
+          <el-table-column align="center" prop="department_name" :label="$t('fuZeBuMen')" min-width="150">
+            <template slot-scope="scope">
+              <div>
+                <span v-if="user.userNameNeedTranslate == '1'">
+                  <TranslationOpenDataText type='departmentName' :openid='scope.row.corpwxDeptId'></TranslationOpenDataText>
+                </span>
+                <span v-if="user.userNameNeedTranslate != '1'">
+                  {{scope.row.departmentName}}
+                </span>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="groupName" :label="$t('lable.taskGrouping')" min-width="150"></el-table-column>
+          <el-table-column align="center" prop="planHour" :label="$t('jiHuaGongShiCaiWu')" width="120"></el-table-column>
+          <el-table-column align="center" :label="$t('shiJiGongShiChengBen')">
+            <el-table-column align="center" prop="afterSetPlanHour" :label="$t('zengBuGongShiH')" width="120"></el-table-column>
+            <el-table-column align="center" prop="normalHour" :label="$t('zhengChangGongShiH')" width="100"></el-table-column>
+            <el-table-column align="center" prop="overHour" :label="$t('jiaBanGongShiH')" width="100"></el-table-column>
+            <el-table-column align="center" prop="realHour" :label="$t('heJiGongShiH')" width="100"></el-table-column>
+            <el-table-column align="center" prop="realCost" :label="$t('heJiGongShiChengBen')" width="140"></el-table-column>
+          </el-table-column>
+          <el-table-column align="center" prop="process" :label="$t('gongShiHaoYongShuai')" width="150"></el-table-column>
+        </el-table>
+      </template>
+    </template>
+
+    <!-- 图表 -->
+    <template v-if="tabPosition == '1'">
+      <template v-if="echartTableType == '图表'">
+        <div ref="echartsRef" :style="`width: 100%;height: ${tableHeight - 0}px;`" v-loading="echartsLoading">
+          <EchartsEchar :options="echartsEcharData" :key="echartsKey"></EchartsEchar>
+        </div>
+      </template>
+      <template v-if="echartTableType == '表格'">
+        <el-table :data="echartsTableData" border style="width: 100%" :height="(+tableHeight - 0) - 1" v-loading="echartsLoading" show-summary :summary-method="getSummaries">
+          <el-table-column prop="projectCode" label="项目编号"></el-table-column>
+          <el-table-column prop="projectName" label="项目名称"></el-table-column>
+          <el-table-column prop="workTime" label="时长(h)" width="180"></el-table-column>
+        </el-table>
+      </template>
+      <div class="echarts-table" v-if="types != 'all'">
+        <el-radio-group v-model="echartTableType" size="small">
+          <el-radio-button label="表格"></el-radio-button>
+          <el-radio-button label="图表"></el-radio-button>
+        </el-radio-group>
+        </div>
+    </template>
+  </div>
+</template>
+
+<script>
+import { debounce, fixedGrouping, getPieEchartOption, getProportion, collectNUm } from "../echartsData.js";
+import EchartsEchar from "@/components/echartsEchar.vue"
+export default {
+  props: {
+    datas: { type: Object, default: () => {} },
+    tabType: { type: String, default: () => "all" },
+  },
+  components: {
+    EchartsEchar
+  },
+  data() {
+    return {
+      user: JSON.parse(sessionStorage.user),
+      permissions: JSON.parse(sessionStorage.getItem("permissions")),
+      types: "all",
+      tableList: [],
+      timer: null,
+      tableHeight: 0,
+      tabPosition: '0',
+      list1: [],
+      listArr1: [],
+      listArr2: [],
+      listArr3: [],
+      echartsWidth: 0,
+      listPosition1: [],
+      tableLoading: false,
+      echartsLoading: false,
+      echartsEcharData: {},
+      typesDataObj: fixedGrouping,
+      echartsTableData: [],
+      echartsKey: 1,
+      echartTableType: '图表',
+      returnedValueItem: {}
+    };
+  },
+  computed: {},
+  watch: {
+    datas(newVal) {
+      const { type, regular, tabPosition } = newVal
+      this.types = type;
+      this.tabPosition = tabPosition
+      this.handleWatchTabDatas(newVal);
+    },
+  },
+  created() {},
+  mounted() {
+  },
+  methods: {
+    handleWatchTabDatas(newVal) {
+      const { type, list, regular, height, tabPosition, params, listArr1, listArr2, listArr3, echartsData = {} } = newVal;
+      this.tableHeight = height;
+      this.tableList = []
+      this.echartTableType = '图表'
+      if(type == regular && tabPosition == '0') {
+        this.getTableList(params)
+      }
+      if(type == regular && tabPosition == '1') {
+        this.getEchartsData(params)
+      }
+      if (type == "all") {
+        this.echartsKey++
+        this.listArr1 = listArr1
+        this.listArr2 = listArr2
+        this.listArr3 = listArr3
+        this.echartsEcharData = echartsData
+        setTimeout(() => {  
+          this.tableList = list;
+        }, 200)
+      }
+    },
+    async getEchartsData(params) {
+      const { groupNames, dataTime = [], projectIds } = params
+      const type = this.types
+      const row = fixedGrouping[type]
+      this.echartsLoading = true
+      let res = await this.postData('/project/groupExpendProcessListForProject', {
+        projectIds,
+        startDate: dataTime[0] || '',
+        endDate: dataTime[1] || '',
+        deptIdStr: row.deptIds,
+        groupNames
+      })
+      this.echartsKey++
+      this.echartsLoading = false
+      const dataList = res.data.record
+      this.echartsTableData = dataList
+      const list = fixedGrouping[type].tabPicFileds
+      const item = list.find(item => item.filed == groupNames)
+      const strList = fixedGrouping[type].proportion.map(item => item.key)
+      const datas = dataList.map(item => {
+        return {
+          name: `${item.projectName} ${item.percent}`,
+          value: item.workTime,
+          fledStrList: [...new Set(strList)]
+        }
+      })
+      this.echartsEcharData = getPieEchartOption(item.title, datas)
+    },
+    async getTableList(params) {
+      const { dataTime = [], projectIds } = params
+      const type = this.types
+      const row = fixedGrouping[type]
+      this.tableLoading = true
+      let groupNames = this.typesDataObj[this.types].tableFileds.map(item => item.label).join(',')
+      let { data } = await this.postData('/project/groupExpendProcessListForUser', {
+        projectIds,
+        startDate: dataTime[0] || '',
+        endDate: dataTime[1] || '',
+        deptIdStr: row.deptIds,
+        groupNames
+      })
+      this.tableLoading = false
+      this.listArr1 = []
+      this.listArr2 = []
+      this.listArr3 = []
+      this.listPosition1 = 0
+      this.listPosition2 = 0
+      this.listPosition3 = 0
+      const strList = fixedGrouping[type].proportion.map(item => item.key)
+      let dataList = data.record.map(item => {
+        return {
+          ...item,
+          departmentNameList: item.departmentName.split('/'),
+          fledStrList: [...new Set(strList)]
+        }
+      })
+      // console.log(collectNUm(dataList, this.types), '<===== 返回的数据 ============>')
+      this.returnedValueItem = collectNUm(dataList, this.types)
+      this.tableList = getProportion(dataList, this.types)
+      this.typesDataObj[this.types].tableKey = this.randomInt()
+      console.log(this.tableList, '<====== 返回最终的数据')
+    },
+    objectSpanMethod({ row, column, rowIndex, columnIndex }){
+      const { companyId } = this.user
+      if(columnIndex == 0 && this.listArr1.length > 0){
+        const _row = this.listArr1[rowIndex]
+        const _col = _row > 0 ? 1 : 0
+        return {
+          rowspan: _row,
+          colspan: _col
+        }
+      }
+      if(columnIndex == 1 && this.listArr2.length > 0){
+        const _row = this.listArr2[rowIndex]
+        const _col = _row > 0 ? 1 : 0
+        return {
+          rowspan: _row,
+          colspan: _col
+        }
+      }
+      if(columnIndex == 2 && companyId == '3092' && this.listArr3.length > 0) {
+        const _row = this.listArr3[rowIndex]
+        const _col = _row > 0 ? 1 : 0
+        return {
+          rowspan: _row,
+          colspan: _col
+        }
+      }
+    },
+    // 单独封装请求
+    async postData(urls, param) {
+      return new Promise((resolve, reject) => {
+        this.http.post(urls, { ...param },
+          res => {
+            if(res.code == 'ok') {
+              resolve(res)
+            } else {
+              this.$message({
+                message: res.msg,
+                type: 'error'
+              })
+              reject(res)
+            }
+            resolve(res)
+          },
+          error => {
+            this.$message({
+              message: error,
+              type: "error"
+            });
+            reject(error)
+          }
+        )
+      });
+    },
+    groupByJobNumber(data) {
+        let groupedData = [];
+        data.reduce((acc, obj) => {
+            let found = acc.find(item => item.jobNumber === obj.jobNumber);
+            if (found) {
+                found.list.push(obj);
+            } else {
+                acc.push({ 
+                  jobNumber: obj.jobNumber, 
+                  userName: obj.userName, 
+                  departmentName: obj.departmentName, 
+                  workTime: obj.workTime,
+                  list: [obj],
+                });
+            }
+            return acc;
+        }, groupedData);
+        return groupedData;
+    },
+    rowspan(spanArr,position,spanName,dataItem = [],fields=false){
+      let newArray = dataItem.length > 0 ? dataItem : this.tableList
+      newArray.forEach((item,index) => {
+        if(index == 0){
+          spanArr.push(1)
+          position = 0
+        }else {
+          let newArrFlag = newArray[index][spanName] == newArray[index-1][spanName] && (!fields || newArray[index][fields] == newArray[index-1][fields]);
+          // if(newArray[index][spanName] == newArray[index-1][spanName]){
+          if(newArrFlag){
+            spanArr[position] += 1
+            spanArr.push(0)
+          }else {
+            spanArr.push(1)
+            position = index
+          }
+        }
+      })
+    },
+    // 随机整数
+    randomInt(min = 1, max = 10000) {
+      return Math.floor(Math.random() * (max - min + 1) + min);
+    },
+    getSummaries(param) {
+      const { columns, data } = param;
+      const sums = [];
+      const strList = (data[0] && data[0].fledStrList) || []
+      const totalNum = this.returnedValueItem.totalNum
+      columns.forEach((column, index) => {
+        if (index === 0) {
+          sums[index] = '总计';
+          return;
+        }
+        if (strList.includes(column.property)) {
+          let val = this.returnedValueItem[column.property]
+          let num = (val / totalNum) * 100
+          sums[index] = Number(num.toFixed(2)) + '%';
+          return
+        }
+        const values = data.map(item => Number(item[column.property]));
+        if (!values.every(value => isNaN(value))) {
+          sums[index] = values.reduce((prev, curr) => {
+            const value = Number(curr);
+            if (!isNaN(value)) {
+              return prev + curr;
+            } else {
+              return prev;
+            }
+          }, 0);
+          sums[index] += ' h';
+        } else {
+          sums[index] = ' ';
+        }
+      });
+
+      return sums;
+    }
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.tabless {
+  width: 100%;
+  height: 100%;
+}
+.echarts-table {
+  position: fixed;
+  bottom: 15px;
+  right: 38px;
+}
+</style>

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

@@ -127,8 +127,12 @@
                         <span v-if="user.userNameNeedTranslate != 1">{{project.reviwerName}}</span>
                         <span v-if="user.userNameNeedTranslate != 1">{{project.reviwerName}}</span>
                         <span v-else><TranslationOpenDataText type='userName' :openid='project.reviwerName'></TranslationOpenDataText></span>
                         <span v-else><TranslationOpenDataText type='userName' :openid='project.reviwerName'></TranslationOpenDataText></span>
                     </el-link></div>
                     </el-link></div>
-                    <div v-if="user.timeType.reportAuditType != 8" style="margin-top:10px;color:#999;">{{ user.timeType.reportCc == 1?'日报抄送人':$t('newspaperauditor') }}</div>
-                    <div v-if="user.timeType.reportAuditType != 8">
+                    <!-- <div v-if="user.timeType.reportAuditType != 8" style="margin-top:10px;color:#999;"> -->
+                    <div v-if="user.timeType.reportAuditType == 0 || user.timeType.reportAuditType == 4 || user.timeType.reportAuditType == 6" style="margin-top:10px;color:#999;">
+                        {{ user.timeType.reportCc == 1?'日报抄送人':$t('newspaperauditor') }}
+                    </div>
+                    <!-- <div v-if="user.timeType.reportAuditType != 8"> -->
+                    <div v-if="user.timeType.reportAuditType == 0 || user.timeType.reportAuditType == 4 || user.timeType.reportAuditType == 6">
                         <span v-if="project.auditorList.length == 0" style="margin:10px;">-</span>
                         <span v-if="project.auditorList.length == 0" style="margin:10px;">-</span>
                         <el-link v-for="item in project.auditorList" :key="item.id" style="margin:10px;" @click="showUser(item.auditorId)">
                         <el-link v-for="item in project.auditorList" :key="item.id" style="margin:10px;" @click="showUser(item.auditorId)">
                             <span v-if="user.userNameNeedTranslate != 1">
                             <span v-if="user.userNameNeedTranslate != 1">
@@ -222,7 +226,7 @@
                         </el-col>
                         </el-col>
                         <el-col :span="4" style="text-align:center;">
                         <el-col :span="4" style="text-align:center;">
                             <p style="color:#666;font-size:12px;">{{ $t('dai-ren-ling') }}</p>
                             <p style="color:#666;font-size:12px;">{{ $t('dai-ren-ling') }}</p>
-                            <p style="font-size:20px;color:#orange;font-weight:bold;">{{taskSum.unassignCount}}</p>
+                            <p style="font-size:20px;color:orange;font-weight:bold;">{{taskSum.unassignCount}}</p>
                         </el-col>
                         </el-col>
                         <el-col :span="4" style="text-align:center;">
                         <el-col :span="4" style="text-align:center;">
                             <p style="color:#666;font-size:12px;">{{ $t('duetoday') }}</p>
                             <p style="color:#666;font-size:12px;">{{ $t('duetoday') }}</p>

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

@@ -236,6 +236,7 @@
                 <el-table-column :label="$t('jiao-se')" width="100">
                 <el-table-column :label="$t('jiao-se')" width="100">
                     <template slot-scope="scope">{{scope.row.roleName}}</template>
                     <template slot-scope="scope">{{scope.row.roleName}}</template>
                 </el-table-column>
                 </el-table-column>
+                <el-table-column label="分组" prop="groupName" width="150" v-if="permissions.userGroupManage"></el-table-column>
                 <el-table-column prop="monthCost" :label="$t('monthcost')" align="right" v-if="permissions.structurePersonnel" width="140">
                 <el-table-column prop="monthCost" :label="$t('monthcost')" align="right" v-if="permissions.structurePersonnel" width="140">
                     <template slot-scope="scope">{{user.timeType.isSecretSalary==0?(scope.row.monthCost==null?0:scope.row.monthCost.toFixed(2)):'*'}} {{ $t('yuan') }}</template>
                     <template slot-scope="scope">{{user.timeType.isSecretSalary==0?(scope.row.monthCost==null?0:scope.row.monthCost.toFixed(2)):'*'}} {{ $t('yuan') }}</template>
                 </el-table-column>
                 </el-table-column>
@@ -279,6 +280,7 @@
                 <el-button size="small" type="primary" @click="handJue">{{ $t('modifyingRoles') }}</el-button>
                 <el-button size="small" type="primary" @click="handJue">{{ $t('modifyingRoles') }}</el-button>
                 <el-button size="small" type="primary" @click="workingHoursDialogClick()">{{ $t('xiuZhengGongShiSuoShuBuMen') }}</el-button>
                 <el-button size="small" type="primary" @click="workingHoursDialogClick()">{{ $t('xiuZhengGongShiSuoShuBuMen') }}</el-button>
                 <el-button size="small" type="primary" @click="handleSelectionUser()">{{ $t('piLiangQiYongYuanGong') }}</el-button>
                 <el-button size="small" type="primary" @click="handleSelectionUser()">{{ $t('piLiangQiYongYuanGong') }}</el-button>
+                <el-button size="small" type="primary" v-if="permissions.userGroupManage" @click="showUserGroupVisable()">批量修改分组</el-button>
                
                
                 
                 
                 
                 
@@ -348,6 +350,21 @@
             </div>
             </div>
         </el-dialog>
         </el-dialog>
 
 
+        <!-- 批量修改用户分组 -->
+        <el-dialog :title="$t('changes')" :visible.sync="userGroupVisable" v-if="userGroupVisable" width="600px">
+            <el-form model="" label-width="20%">
+                <el-form-item label="用户分组">
+                    <el-select v-model="userGroupId" :placeholder="$t('defaultText.pleaseChoose')" style="width: 100%">
+                        <el-option v-for="(item, index) in userGroupList" :key="index" :label="item.groupName" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click="userGroupVisable = false">{{ $t('btn.cancel') }}</el-button>
+                <el-button type="primary" :disabled="!userGroupId" :loading="userGroupLoading" @click="editUserGroup()">{{ $t('btn.determine') }}</el-button>
+            </div>
+        </el-dialog>
+
         <!-- 新增部门 -->
         <!-- 新增部门 -->
         <el-dialog :title="depTitle" :visible.sync="departmentVisible" width="500px" >
         <el-dialog :title="depTitle" :visible.sync="departmentVisible" width="500px" >
             <el-form ref="depForm" :model="depForm" :rules="depRules" label-width="100px">
             <el-form ref="depForm" :model="depForm" :rules="depRules" label-width="100px">
@@ -478,6 +495,11 @@
                           </el-option>
                           </el-option>
                       </el-select>
                       </el-select>
                   </el-form-item>
                   </el-form-item>
+                  <el-form-item label="用户分组" prop="groupId" v-if="permissions.userGroupManage">
+                    <el-select v-model="insertForm.groupId" :placeholder="$t('defaultText.pleaseChoose')" style="width: 100%">
+                      <el-option v-for="item in userGroupList" :label="item.groupName" :value="item.id" :key="item.id"></el-option>
+                    </el-select>
+                  </el-form-item>
                   <el-form-item :label="item.name" v-for="item,index in userCustomConfig" :key="item.id">
                   <el-form-item :label="item.name" v-for="item,index in userCustomConfig" :key="item.id">
                       <el-select v-if="item.type == 0" v-model="insertForm[suoying[index]]" :placeholder="$t('defaultText.pleaseChoose')" clearable style="width: 100%">
                       <el-select v-if="item.type == 0" v-model="insertForm[suoying[index]]" :placeholder="$t('defaultText.pleaseChoose')" clearable style="width: 100%">
                           <el-option v-for="option in item.itemList" :label="option.name" :value="option.name" :key="option.id">
                           <el-option v-for="option in item.itemList" :label="option.name" :value="option.name" :key="option.id">
@@ -1170,6 +1192,12 @@ export default {
       whiteListAll: [],
       whiteListAll: [],
       whiteListAllTwo: [],
       whiteListAllTwo: [],
       specialHolidaysDialog: false,
       specialHolidaysDialog: false,
+
+      // 用户分组
+      userGroupList: [],
+      userGroupId: '',
+      userGroupVisable: false,
+      userGroupLoading: false,
     };
     };
   },
   },
   watch: {
   watch: {
@@ -2861,7 +2889,8 @@ export default {
                 plate5: res.data.plate5,
                 plate5: res.data.plate5,
                 jobNumber: res.data.jobNumber,
                 jobNumber: res.data.jobNumber,
                 onlyAuditOnce: res.data.onlyAuditOnce,
                 onlyAuditOnce: res.data.onlyAuditOnce,
-                reportDeptIdsList: res.data.userReportDeptList || []
+                reportDeptIdsList: res.data.userReportDeptList || [],
+                groupId: res.data.userGroupId || ''
               };
               };
               this.$set(this.insertForm, 'inductionDate', res.data.inductionDate)
               this.$set(this.insertForm, 'inductionDate', res.data.inductionDate)
               this.getUserCustomConfig(1);
               this.getUserCustomConfig(1);
@@ -2977,6 +3006,9 @@ export default {
           // }
           // }
 
 
           // console.log(form, 'form')
           // console.log(form, 'form')
+          if(this.permissions.userGroupManage) {
+            form.groupId = this.insertForm.groupId;
+          } 
 
 
           if (this.insertForm.id != null) {
           if (this.insertForm.id != null) {
             form.id = this.insertForm.id;
             form.id = this.insertForm.id;
@@ -3867,6 +3899,15 @@ export default {
             }
             }
         },error => {})
         },error => {})
     },
     },
+    getUserGrpupList() {
+      this.http.post('/user-group/list',{
+        },res => {
+            if(res.code == 'ok'){
+                let list = res.data
+                this.userGroupList = list
+            }
+        },error => {})
+    },
     // 企业微信选人搜索
     // 企业微信选人搜索
     echartDepartment() {
     echartDepartment() {
         if(this.wxFilterText != '') {
         if(this.wxFilterText != '') {
@@ -3932,6 +3973,34 @@ export default {
         if (!value) return true;
         if (!value) return true;
         return data.label.indexOf(value) !== -1;
         return data.label.indexOf(value) !== -1;
     },
     },
+    showUserGroupVisable() {
+      if (this.handleSelectionZzjgDate.length == 0) {
+        this.$message(this.$t('pleaseselectpersonnel'));
+        return;
+      }
+      this.userGroupId = ''
+      this.userGroupVisable = true
+    },
+    editUserGroup() {
+      this.userGroupLoading = true
+      let ids = this.handleSelectionZzjgDate.map(item => item.id).join(',')
+      this.http.post("/user/batchSetUserGroup", {
+        userIds: ids,
+        groupId: this.userGroupId
+      },
+      res => {
+        this.userGroupLoading = false
+        if (res.code == "ok") {
+          this.$message({
+              message: this.$t('caoZuoChengGong'),
+              type: "success"
+          });
+          this.userGroupVisable = false
+          this.getUser()
+        }
+      },
+      error => { this.userGroupLoading = false });
+    }
   },
   },
   mounted() {
   mounted() {
     this.deactiveDate = util.formatDate.format(new Date(), "yyyy-MM-dd");
     this.deactiveDate = util.formatDate.format(new Date(), "yyyy-MM-dd");
@@ -3951,6 +4020,9 @@ export default {
     }
     }
     this.statesPush();
     this.statesPush();
     this.getWhiteListAll()
     this.getWhiteListAll()
+    if(this.permissions.userGroupManage) {
+      this.getUserGrpupList()
+    }
     // 获取企业微信的参数
     // 获取企业微信的参数
     // if(this.user.companyId == '1081' || this.user.companyId == '7') {
     // if(this.user.companyId == '1081' || this.user.companyId == '7') {
     //   this.agentConfig()
     //   this.agentConfig()

+ 231 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/userGrouping/userGrouping.vue

@@ -0,0 +1,231 @@
+<template>
+  <div class="userGroping">
+    <div class="userGroping-title">
+      <div>用户分组管理</div>
+      <div>
+        <el-button type="text" icon="el-icon-circle-plus-outline" @click="showGroupVisable()">创建分组</el-button>
+      </div>
+    </div>
+    <div class="userGroping-table">
+      <el-table :data="tableData" border v-loading="tableLoading" style="width: 100%; height: 100%">
+        <el-table-column align="center" prop="groupName" label="分组名称"></el-table-column>
+        <el-table-column align="center" prop="noProjectPercent" label="非项目工时占比上限(%)"></el-table-column>
+        <el-table-column align="center" prop="operation" label="操作" width="160">
+          <template slot-scope="scope">
+            <el-button size="small" @click="showGroupVisable(scope.row)">编辑</el-button>
+            <el-button size="small" type="danger" @click="deteleGroup(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- 创建/编辑分组 -->
+    <el-dialog title="新增/编辑分组" :visible.sync="editGroupVisable" width="800px" :before-close="handleClose">
+      <div class="groupForm">
+        <div class="groupFormItem">
+          <div class="label">分组名称</div>
+          <el-input v-model.trim="editGroupForm.groupName" size="small" placeholder="请输入" clearable
+            class="flex1"></el-input>
+        </div>
+        <div class="groupFormItem">
+          <div class="label">非项目占比(%)</div>
+          <el-input-number v-model="editGroupForm.noProjectPercent" size="small" controls-position="right"
+            :precision="0" :min="0" :max="100" class="flex1 textNumber" style="text-align: left;"></el-input-number>
+        </div>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="editGroupVisable = false">取 消</el-button>
+        <el-button type="primary" @click="editGroup()" :loading="editGroupBtnLoading"
+          :disabled="editGroupForm.groupName && !editGroupForm.noProjectPercent">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {},
+  components: {},
+  data() {
+    return {
+      prefix: "/user-group/",
+      tableLoading: false,
+      editGroupVisable: false,
+      editGroupBtnLoading: false,
+      tableData: [],
+      editGroupForm: {
+        id: '',
+        companyId: '',
+        groupName: '',
+        noProjectPercent: 0,
+      }
+    };
+  },
+  computed: {},
+  watch: {},
+  created() { },
+  mounted() {
+    this.getTableList()
+  },
+  methods: {
+    deteleGroup(row) {
+      this.$confirm(`确定删除【${row.groupName}】?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.postData("delete", { id: row.id }).then(res => {
+          if (res.code != 'ok') {
+            this.messages(res.msg)
+            return
+          }
+          this.messages('删除成功', 'success')
+          this.getTableList()
+        })
+      });
+    },
+    editGroup() {
+      let formVal = this.getFromValue(this.editGroupForm)
+      this.editGroupBtnLoading = true
+      this.postData("addOrUpdate", { ...formVal }).then(res => {
+        if (res.code != 'ok') {
+          this.messages(res.msg)
+          return
+        }
+        this.messages('创建成功', 'success')
+        this.editGroupVisable = false
+        this.getTableList()
+      }).finally(() => {
+        this.editGroupBtnLoading = false
+      });
+    },
+    getTableList() {
+      this.tableLoading = true
+      this.postData("list", {}).then(res => {
+        if (res.code != 'ok') {
+          this.messages(res.msg)
+          return
+        }
+        this.tableData = res.data
+      }).finally(() => {
+        this.tableLoading = false
+      });
+    },
+    showGroupVisable(row = false) {
+      if (!row) {
+        // 清空
+        this.editGroupForm = {
+          id: '',
+          companyId: '',
+          groupName: '',
+          noProjectPercent: 0,
+        }
+        this.editGroupVisable = true
+        return
+      }
+
+      this.editGroupForm = {
+        ...row,
+        noProjectPercent: row.noProjectPercent || 0
+      }
+      this.editGroupVisable = true
+    },
+
+    messages(test = '', type = "error") {
+      this.$message({
+        message: test,
+        type: type,
+      });
+    },
+    getFromValue(formData) {
+      const result = {};
+      for (const key in formData) {
+        if (formData[key]) {
+          result[key] = formData[key];
+        }
+      }
+      return result;
+    },
+    // 封装 post 请求
+    postData(url, params) {
+      return new Promise((resolve, reject) => {
+        this.http.post(`${this.prefix}${url}`, { ...params }, (res) => {
+          resolve(res);
+        }, (error) => {
+          this.$message({
+            message: error,
+            type: "error",
+          });
+          this.messages(error)
+          reject(error);
+        }
+        );
+      });
+    },
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.userGroping {
+  width: 100%;
+  height: 100%;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+
+  .userGroping-title {
+    background: #f2f2f2;
+    padding: 10px 20px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  .userGroping-table {
+    flex: 1;
+  }
+
+  .groupForm {
+    .groupFormItem {
+      margin-bottom: 15px;
+      display: flex;
+      align-items: center;
+      flex-direction: row;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+
+      .label {
+        width: 120px;
+        text-align: right;
+        margin-right: 10px;
+      }
+
+      .textNumber {
+        text-align: left;
+      }
+
+      .flex1 {
+        flex: 1;
+      }
+    }
+  }
+
+  div {
+    box-sizing: border-box;
+  }
+
+
+}
+</style>
+<style lang="scss">
+.userGroping {
+  .groupFormItem {
+    .el-input-number .el-input__inner {
+      text-align: left !important;
+    }
+  }
+}
+</style>

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

@@ -915,7 +915,7 @@
                         }
                         }
                         this.listBackup = JSON.parse(JSON.stringify(res.data));
                         this.listBackup = JSON.parse(JSON.stringify(res.data));
                         console.log(this.listBackup, "《====== 赋值")
                         console.log(this.listBackup, "《====== 赋值")
-                        this.list = this.currentChangePage(10, 1, res.data);
+                        this.list = this.currentChangePage(this.reviewTableObj.reviewTableSize, 1, res.data);
                         let total = res.data.length || 0
                         let total = res.data.length || 0
                         this.reviewTableObj = {
                         this.reviewTableObj = {
                             reviewTableTotal: total,
                             reviewTableTotal: total,