浏览代码

Merge remote-tracking branch 'origin/master'

yusm 1 年之前
父节点
当前提交
cba42ecf06
共有 89 个文件被更改,包括 6213 次插入624 次删除
  1. 1 0
      fhKeeper/formulahousekeeper/inva_4_tivo/about.html
  2. 86 0
      fhKeeper/formulahousekeeper/inva_4_tivo/css/dynamic.css
  3. 86 0
      fhKeeper/formulahousekeeper/inva_4_tivo/css/dynamic.less
  4. 1 0
      fhKeeper/formulahousekeeper/inva_4_tivo/css/element-uiCss.css
  5. 二进制
      fhKeeper/formulahousekeeper/inva_4_tivo/css/fonts/element-icons.ttf
  6. 二进制
      fhKeeper/formulahousekeeper/inva_4_tivo/css/fonts/element-icons.woff
  7. 1 0
      fhKeeper/formulahousekeeper/inva_4_tivo/customer.html
  8. 170 0
      fhKeeper/formulahousekeeper/inva_4_tivo/dynamic.html
  9. 1 0
      fhKeeper/formulahousekeeper/inva_4_tivo/followup.html
  10. 1 0
      fhKeeper/formulahousekeeper/inva_4_tivo/index.html
  11. 1 0
      fhKeeper/formulahousekeeper/inva_4_tivo/js/element-ui.js
  12. 6 0
      fhKeeper/formulahousekeeper/inva_4_tivo/js/vue.min.js
  13. 1 0
      fhKeeper/formulahousekeeper/inva_4_tivo/mobile.html
  14. 1 0
      fhKeeper/formulahousekeeper/inva_4_tivo/project.html
  15. 1 0
      fhKeeper/formulahousekeeper/inva_4_tivo/workshop.html
  16. 24 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java
  17. 30 9
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  18. 40 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SapSyncLogController.java
  19. 10 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java
  20. 23 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java
  21. 5 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Report.java
  22. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeType.java
  23. 11 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectMapper.java
  24. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  25. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ExcelExportService.java
  26. 8 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java
  27. 3 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  28. 49 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ExcelExportServiceImpl.java
  29. 306 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  30. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportBatchServiceImpl.java
  31. 190 102
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  32. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  33. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/BeiSenUtils.java
  34. 64 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/SyncSapUtils.java
  35. 70 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/ActualEmployeeTime.java
  36. 22 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/ActualEmployeeTimeSelectionByElements.java
  37. 7 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/ProcessingConditions.java
  38. 33 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/SelectionByDate.java
  39. 29 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/SelectionByEmployeeID.java
  40. 6 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/XmlRequestData.java
  41. 6 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/XmlResponseData.java
  42. 97 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml
  43. 4 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  44. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TimeTypeMapper.xml
  45. 4 4
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/DepartmentController.java
  46. 21 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/DepartmentQualityManagerController.java
  47. 7 2
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/PlanController.java
  48. 5 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/ReportController.java
  49. 48 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/DepartmentQualityManager.java
  50. 3 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/Plan.java
  51. 1 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/vo/DepartmentVO.java
  52. 16 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/mapper/DepartmentQualityManagerMapper.java
  53. 16 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/DepartmentQualityManagerService.java
  54. 2 2
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/DepartmentService.java
  55. 3 1
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/PlanService.java
  56. 2 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/ReportService.java
  57. 20 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/DepartmentQualityManagerServiceImpl.java
  58. 33 12
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java
  59. 146 57
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/PlanServiceImpl.java
  60. 179 32
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  61. 18 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/DepartmentQualityManagerMapper.xml
  62. 16 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5/src/views/planView/component/planComponent.vue
  63. 16 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5/src/views/workView/fillReport.vue
  64. 4 4
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/Home.vue
  65. 274 116
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/plan/orderInsert.vue
  66. 272 59
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/plan/planComponent.vue
  67. 40 6
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/product/list.vue
  68. 68 51
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/statistic/index.vue
  69. 27 1
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/team/index.vue
  70. 5 3
      fhKeeper/formulahousekeeper/timesheet/src/i18n/en.json
  71. 7 5
      fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json
  72. 69 1
      fhKeeper/formulahousekeeper/timesheet/src/views/Home.vue
  73. 2 2
      fhKeeper/formulahousekeeper/timesheet/src/views/expense/expense.vue
  74. 3 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/cost.vue
  75. 17 3
      fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue
  76. 112 43
      fhKeeper/formulahousekeeper/timesheet/src/views/task/list.vue
  77. 52 7
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  78. 32 13
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list.vue
  79. 1 0
      fhKeeper/formulahousekeeper/timesheet_h5/package.json
  80. 6 0
      fhKeeper/formulahousekeeper/timesheet_h5/src/components/Element.js
  81. 1 0
      fhKeeper/formulahousekeeper/timesheet_h5/src/main.js
  82. 7 0
      fhKeeper/formulahousekeeper/timesheet_h5/src/router/index.js
  83. 12 3
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue
  84. 2651 0
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit-02.vue
  85. 202 43
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue
  86. 99 0
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/editPerfect/editPerfect.vue
  87. 9 3
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/index/index.vue
  88. 266 13
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue
  89. 10 10
      fhKeeper/formulahousekeeper/timesheet_h5/vue.config.js

+ 1 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/about.html

@@ -52,6 +52,7 @@
                             <li class="til"><a href="./mobile.html">手机版</a></li>
                             <li class="til"><a href="./index.html#pricing">产品定价</a></li>
                             <li class="til ons"><a href="./about.html">关于我们</a></li>
+                            <li class="til"><a href="./dynamic.html">企业动态</a></li>
                         </ul>
                     </div>
                 </div>

+ 86 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/css/dynamic.css

@@ -0,0 +1,86 @@
+.enterpriseDynamics {
+  display: flex;
+  justify-content: center;
+  margin-top: 10em;
+}
+.enterpriseDynamics .content {
+  width: 1140px;
+}
+.enterpriseDynamics .bifJournal {
+  width: 100%;
+}
+.enterpriseDynamics .bifJournal .headline {
+  margin: 10px 0 20px 0;
+  font-size: 40px;
+}
+.enterpriseDynamics .bifJournal .eachItem {
+  margin-left: 60px;
+  border-bottom: 1px solid #D7D7D7;
+  padding: 30px 20px;
+  display: flex;
+  justify-content: space-between;
+}
+.enterpriseDynamics .bifJournal .eachItem .eachItemImg {
+  width: 300px;
+  height: 200px;
+}
+.enterpriseDynamics .bifJournal .eachItem .eachItemImg img {
+  width: 100%;
+  height: 100%;
+}
+.enterpriseDynamics .bifJournal .eachItem .eachItemRight {
+  margin-left: 40px;
+  flex: 1;
+}
+.enterpriseDynamics .bifJournal .eachItem .eachItemRight .eachItemRightTilt {
+  font-size: 26px;
+}
+.enterpriseDynamics .bifJournal .eachItem .eachItemRight .eachItemRightText {
+  font-size: 18px;
+  margin-top: 10px;
+  margin-bottom: 10px;
+  line-height: 22px;
+  height: 135px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.enterpriseDynamics .bifJournal .eachItem .eachItemRight .eachItemRightBum {
+  display: flex;
+  justify-content: space-between;
+  font-size: 16px;
+}
+.enterpriseDynamics .bifJournal .eachItem .eachItemRight .eachItemRightBum .ons {
+  color: #31B7F2;
+  cursor: pointer;
+}
+.enterpriseDynamics .bifJournal .paging {
+  display: flex;
+  justify-content: flex-end;
+  margin: 20px 0 30px 0;
+}
+.enterpriseDynamics .details {
+  margin: 20px 0px 40px 0;
+  min-height: 300px;
+}
+.enterpriseDynamics .details .detailsTil {
+  font-size: 26px;
+  text-align: center;
+  margin-bottom: 15px;
+  position: relative;
+}
+.enterpriseDynamics .details .detailsData {
+  display: flex;
+  justify-content: flex-end;
+  font-size: 18px;
+  margin-bottom: 15px;
+}
+.enterpriseDynamics .details .detailstext {
+  font-size: 18px;
+}
+.enterpriseDynamics .details .detailsBack {
+  position: absolute;
+  left: 0;
+  top: 0;
+  color: #31B7F2;
+  cursor: pointer;
+}

+ 86 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/css/dynamic.less

@@ -0,0 +1,86 @@
+.enterpriseDynamics {
+    display: flex;
+    justify-content: center;
+    margin-top: 10em;
+    .content {
+        width: 1140px;
+    }
+    .bifJournal {
+        width: 100%;
+        .headline {
+            margin: 10px 0 20px 0;
+            font-size: 40px;
+        }
+        .eachItem {
+            margin-left: 60px;
+            border-bottom: 1px solid #D7D7D7;
+            padding: 30px 20px;
+            display: flex;
+            justify-content: space-between;
+            .eachItemImg {
+                width: 300px;
+                height: 200px;
+                img {
+                    width: 100%;
+                    height: 100%;
+                }
+            }
+            .eachItemRight {
+                margin-left: 40px;
+                flex: 1;
+                .eachItemRightTilt {
+                    font-size: 26px;
+                }
+                .eachItemRightText {
+                    font-size: 18px;
+                    margin-top: 10px;
+                    margin-bottom: 10px;
+                    line-height: 22px;
+                    height: 135px;
+                    overflow: hidden;
+                    text-overflow: ellipsis;
+                }
+                .eachItemRightBum {
+                    display: flex;
+                    justify-content: space-between;
+                    font-size: 16px;
+                    .ons {
+                        color: #31B7F2;
+                        cursor: pointer;
+                    }
+                }
+            }
+        }
+        .paging {
+            display: flex;
+            justify-content: flex-end;
+            margin: 20px 0 30px 0;
+        }
+    }
+    .details {
+        margin: 20px 0px 40px 0;
+        min-height: 300px;
+        .detailsTil {
+            font-size: 26px;
+            text-align: center;
+            margin-bottom: 15px;
+            position: relative;
+        }
+        .detailsData {
+            display: flex;
+            justify-content: flex-end;
+            font-size: 18px;
+            margin-bottom: 15px;
+        }
+        .detailstext {
+            font-size: 18px;
+        }
+        .detailsBack {
+            position: absolute;
+            left: 0;
+            top: 0;
+            color: #31B7F2;
+            cursor: pointer;
+        }
+    }
+}

文件差异内容过多而无法显示
+ 1 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/css/element-uiCss.css


二进制
fhKeeper/formulahousekeeper/inva_4_tivo/css/fonts/element-icons.ttf


二进制
fhKeeper/formulahousekeeper/inva_4_tivo/css/fonts/element-icons.woff


+ 1 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/customer.html

@@ -28,6 +28,7 @@
                             <li class="til"><a href="./mobile.html">手机版</a></li>
                             <li class="til"><a href="#pricing">产品定价</a></li>
                             <li class="til"><a href="./about.html">关于我们</a></li>
+                            <li class="til"><a href="./dynamic.html">企业动态</a></li>
                         </ul>
                     </div>
                 </div>

文件差异内容过多而无法显示
+ 170 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/dynamic.html


+ 1 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/followup.html

@@ -28,6 +28,7 @@
                             <li class="til"><a href="./mobile.html">手机版</a></li>
                             <li class="til"><a href="#pricing">产品定价</a></li>
                             <li class="til"><a href="./about.html">关于我们</a></li>
+                            <li class="til"><a href="./dynamic.html">企业动态</a></li>
                         </ul>
                     </div>
                 </div>

+ 1 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/index.html

@@ -65,6 +65,7 @@
                             <li class="til"><a href="./mobile.html">手机版</a></li>
                             <li class="til"><a href="#pricing">产品定价</a></li>
                             <li class="til"><a href="./about.html">关于我们</a></li>
+                            <li class="til"><a href="./dynamic.html">企业动态</a></li>
                         </ul>
                     </div>
                 </div>

文件差异内容过多而无法显示
+ 1 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/js/element-ui.js


文件差异内容过多而无法显示
+ 6 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/js/vue.min.js


+ 1 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/mobile.html

@@ -64,6 +64,7 @@
                             <li class="til ons"><a href="./mobile.html">手机版</a></li>
                             <li class="til"><a href="./index.html#pricing">产品定价</a></li>
                             <li class="til"><a href="./about.html">关于我们</a></li>
+                            <li class="til"><a href="./dynamic.html">企业动态</a></li>
                         </ul>
                     </div>
                 </div>

+ 1 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/project.html

@@ -28,6 +28,7 @@
                             <li class="til"><a href="./mobile.html">手机版</a></li>
                             <li class="til"><a href="#pricing">产品定价</a></li>
                             <li class="til"><a href="./about.html">关于我们</a></li>
+                            <li class="til"><a href="./dynamic.html">企业动态</a></li>
                         </ul>
                     </div>
                 </div>

+ 1 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/workshop.html

@@ -70,6 +70,7 @@
                           <li class="til"><a href="./mobile.html">手机版</a></li>
                           <li class="til"><a href="#pricing">产品定价</a></li>
                           <li class="til"><a href="./about.html">关于我们</a></li>
+                          <li class="til"><a href="./dynamic.html">企业动态</a></li>
                       </ul>
                   </div>
               </div>

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

@@ -1445,5 +1445,29 @@ public class ProjectController {
     public HttpRespMsg getMembProjectCateRatio(String startDate,String endDate, Integer onlyShowWarning){
         return projectService.getMembProjectCateRatio(startDate,endDate, onlyShowWarning);
     }
+
+    //依斯倍定制 员工项目进度表
+    @RequestMapping("/userProjectProcessList")
+    public HttpRespMsg userProjectProcessList(Integer deptId,String userId,Integer projectId,Integer pageIndex,Integer pageSize){
+        return projectService.userProjectProcessList(deptId,userId,projectId,pageIndex,pageSize);
+    }
+
+    //依斯倍定制 导出员工项目进度表
+    @RequestMapping("/exportUserProjectProcessList")
+    public HttpRespMsg exportUserProjectProcessList(Integer deptId,String userId,Integer projectId){
+        return projectService.exportUserProjectProcessList(deptId,userId,projectId);
+    }
+
+    //依斯倍定制 分组耗用进度表
+    @RequestMapping("/groupExpendProcessList")
+    public HttpRespMsg groupExpendProcessList(String startDate,String endDate,Integer pageIndex,Integer pageSize){
+        return projectService.groupExpendProcessList(startDate,endDate,pageIndex,pageSize);
+    }
+
+    //依斯倍定制 导出分组耗用进度表
+    @RequestMapping("/exportGroupExpendProcessList")
+    public HttpRespMsg exportGroupExpendProcessList(String startDate,String endDate){
+        return projectService.exportGroupExpendProcessList(startDate,endDate);
+    }
 }
 

+ 30 - 9
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -1159,7 +1159,7 @@ public class ReportController {
         }
         //校验工作时长
         for (Report report : reportList) {
-            if (report.getWorkingTime() == null || report.getWorkingTime() <= 0.0) {
+            if (report.getWorkingTime() == null) {
                 HttpRespMsg httpRespMsg = new HttpRespMsg();
                 //httpRespMsg.setError("请填写工作时长");
                 httpRespMsg.setError(MessageUtils.message("profession.duration"));
@@ -1285,21 +1285,35 @@ public class ReportController {
         }
 
         //如果锁定工作时长上限的话,需要校验每日的合计工作时长
-        if (comTimeType.getLockWorktime() == 1) {
-            for (Report report : reportList) {
-                String creatorId = report.getCreatorId();
-                LocalDate cDate = report.getCreateDate();
-                //查找同一个人同一天的日报合计工作时长
-                double dailyWorktime = reportList.stream().filter(r->r.getCreatorId().equals(creatorId) && r.getCreateDate().isEqual(cDate)).mapToDouble(Report::getWorkingTime).sum();
-
+        for (Report report : reportList) {
+            String creatorId = report.getCreatorId();
+            LocalDate cDate = report.getCreateDate();
+            //查找同一个人同一天的日报合计工作时长
+            double dailyWorktime = reportList.stream().filter(r->r.getCreatorId().equals(creatorId) && r.getCreateDate().isEqual(cDate)).mapToDouble(Report::getWorkingTime).sum();
+            if (comTimeType.getLockWorktime() == 1) {
                 if (dailyWorktime > comTimeType.getAllday()) {
                     HttpRespMsg httpRespMsg = new HttpRespMsg();
                     //httpRespMsg.setError("每日工作时长不得超过"+comTimeType.getAllday()+"小时");
                     httpRespMsg.setError(MessageUtils.message("profession.MaxReportTimeError",comTimeType.getAllday()));
                     return httpRespMsg;
                 }
+            } else {
+                //校验上下限
+                if (dailyWorktime < comTimeType.getMinReportTime()) {
+                    HttpRespMsg httpRespMsg = new HttpRespMsg();
+                    //httpRespMsg.setError("每日工作时长不得超过"+comTimeType.getAllday()+"小时");
+                    httpRespMsg.setError("每日工作时长不得少于" + comTimeType.getMinReportTime() + "小时");
+                    return httpRespMsg;
+                } else if (dailyWorktime > comTimeType.getMaxReportTime()) {
+                    HttpRespMsg httpRespMsg = new HttpRespMsg();
+                    //httpRespMsg.setError("每日工作时长不得超过"+comTimeType.getAllday()+"小时");
+                    httpRespMsg.setError("每日工作时长不得超过" + comTimeType.getMaxReportTime() + "小时");
+                    return httpRespMsg;
+                }
             }
         }
+
+
         //校验填报工时
         List<Report> checkedUserDayList = new ArrayList<>();
         for (Report report : reportList) {
@@ -1799,10 +1813,11 @@ public class ReportController {
                                       String startDate,
                                       String endDate,
                                       String userId,
+                                      String auditUserId,
                                       HttpServletRequest request) {
         return reportService.getListByState(state, departmentId,
                 projectId,
-                date, startDate, endDate, userId,
+                date, startDate, endDate, userId,auditUserId,
                 request);
     }
 
@@ -2341,6 +2356,12 @@ public class ReportController {
         return reportService.pushProjectReportToSap(pushDate);
     }
 
+    //todo:查询已推送到SAP的工时管家工时考勤数据 并撤销推送
+    @RequestMapping("/getHasPushForSap")
+    public HttpRespMsg getHasPushForSap(String startDate,String endDate,String employeeID){
+        return reportService.getHasPushForSap(startDate,endDate,employeeID);
+    }
+
     //todo: 提供接口(威派格) 获取项目工时数据
     @RequestMapping("/getProjectTimeCostByThird")
     public HttpRespMsg getProjectTimeCostByThird(@RequestBody String json){

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

@@ -6,7 +6,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.management.platform.entity.SapSyncLog;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.SapSyncLogService;
+import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.HttpRespMsg;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
@@ -16,6 +18,7 @@ import javax.servlet.http.HttpServletRequest;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -36,13 +39,15 @@ public class SapSyncLogController {
     private HttpServletRequest request;
     @Resource
     private UserMapper userMapper;
+    @Value("${upload.path}")
+    private String path;
 
-    @RequestMapping("list")
+    @RequestMapping("/list")
     public HttpRespMsg list(){
         //只返回最近7天的数据
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         LocalDate endDate=LocalDate.now();
-        LocalDate startDate=endDate.minusDays(7);
+        LocalDate startDate=endDate.minusDays(3);
         HttpRespMsg msg=new HttpRespMsg();
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
         List<SapSyncLog> list = sapSyncLogService.list(new LambdaQueryWrapper<SapSyncLog>().eq(SapSyncLog::getCompanyId, companyId).between(SapSyncLog::getSyncTime,df.format(startDate)+" 00:00:00",df.format(endDate)+" 23:59:59").orderByDesc(SapSyncLog::getSyncTime));
@@ -50,5 +55,38 @@ public class SapSyncLogController {
         return msg;
     }
 
+    @RequestMapping("/export")
+    public HttpRespMsg export(){
+        //只返回最近7天的数据
+        DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        DateTimeFormatter df2=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        LocalDate endDate=LocalDate.now();
+        LocalDate startDate=endDate.minusDays(3);
+        HttpRespMsg msg=new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        List<SapSyncLog> list = sapSyncLogService.list(new LambdaQueryWrapper<SapSyncLog>().eq(SapSyncLog::getCompanyId, companyId).between(SapSyncLog::getSyncTime,df.format(startDate)+" 00:00:00",df.format(endDate)+" 23:59:59").orderByDesc(SapSyncLog::getSyncTime));
+        List<List<String>> dataList=new ArrayList<>();
+        List<String> titleList=new ArrayList<>();
+        titleList.add("推送时间");
+        titleList.add("推送名称");
+        titleList.add("操作人员");
+        titleList.add("推送方式");
+        titleList.add("推送结果");
+        titleList.add("备注");
+        dataList.add(titleList);
+        for (SapSyncLog sapSyncLog : list) {
+            List<String> item=new ArrayList<>();
+            item.add(df2.format(sapSyncLog.getSyncTime()));
+            item.add(sapSyncLog.getRemark());
+            item.add(sapSyncLog.getOperator()==null?"":sapSyncLog.getOperator());
+            item.add(sapSyncLog.getSyncType());
+            item.add(sapSyncLog.getResult());
+            item.add(sapSyncLog.getResultRemark()==null?"":sapSyncLog.getResultRemark());
+            dataList.add(item);
+        }
+        String resp = ExcelUtil.exportGeneralExcelByTitleAndList("推送日志", dataList, path);
+        msg.data=resp;
+        return msg;
+    }
 }
 

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

@@ -931,7 +931,7 @@ public class TaskController {
      * @return
      */
     @RequestMapping("/listByPage")
-    public HttpRespMsg listByPage(Integer status, Integer viewId, @RequestParam(required = false, defaultValue = "1") Integer pageIndex, Integer pageSize,Integer type,Integer dateType,String startDate,String endDate,Integer deptId) {
+    public HttpRespMsg listByPage(Integer status, Integer viewId, @RequestParam(required = false, defaultValue = "1") Integer pageIndex, Integer pageSize,Integer type,Integer dateType,String startDate,String endDate,Integer deptId,Integer projectId,Integer groupId,String targetUserId) {
         HttpRespMsg msg = new HttpRespMsg();
         String userId = request.getHeader("Token");
         User user = userMapper.selectById(userId);
@@ -960,6 +960,15 @@ public class TaskController {
                     break;
             }
         }
+        if(projectId!=null){
+            queryWrapper.eq("task.project_id",projectId);
+        }
+        if(groupId!=null){
+            queryWrapper.eq("task.group_id",groupId);
+        }
+        if(!StringUtils.isEmpty(targetUserId)){
+            queryWrapper.like("task.executorId",targetUserId);
+        }
 //        else if (viewId == 3) {
 //            //今天的任务
 //            queryWrapper.eq("end_date", LocalDate.now());

+ 23 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java

@@ -3,6 +3,7 @@ package com.management.platform.controller;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.constant.Constant;
 import com.management.platform.entity.*;
@@ -87,6 +88,8 @@ public class UserController {
     private String dcFirst;
     @Value("${spring.ldap.base.dcSecond}")
     private String dcSecond;
+    @Resource
+    private UserWithBeisenMapper userWithBeisenMapper;
 
     /**
      * 登录网页端
@@ -460,5 +463,25 @@ public class UserController {
         return excludeService.insertUserExclude(userId);
     }
 
+    @RequestMapping("/updateUserJobNumber")
+    public HttpRespMsg updateUserJobNumber(String userId,String jobNumber) {
+        HttpRespMsg msg=new HttpRespMsg();
+        User user = userService.getById(userId);
+        if(user!=null){
+            UserWithBeisen userWithBeisen = userWithBeisenMapper.selectOne(new LambdaQueryWrapper<UserWithBeisen>().eq(UserWithBeisen::getJobNumber, jobNumber));
+            if(userWithBeisen==null){
+                msg.setError("工号["+jobNumber+"]在HR系统中不存在,请重新输入");
+                return msg;
+            }
+            user.setJobNumber(jobNumber);
+            if(!userService.updateById(user)){
+                msg.setError("验证失败");
+                return msg;
+            }
+        }
+        msg.setError("人员不存在");
+        return msg;
+    }
+
 }
 

+ 5 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Report.java

@@ -409,6 +409,11 @@ public class Report extends Model<Report> {
     @TableField(exist = false)
     private List<SapProjectService> serviceList;
 
+    @TableField(exist = false)
+    private String projectName;
+    @TableField(exist = false)
+    private String taskName;
+
     @Override
     protected Serializable pkVal() {
         return this.id;

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

@@ -13,7 +13,7 @@ import lombok.experimental.Accessors;
 
 /**
  * <p>
- * 
+ *
  * </p>
  *
  * @author Seyason
@@ -388,6 +388,12 @@ public class TimeType extends Model<TimeType> {
     @TableField("max_report_time")
     private Float maxReportTime;
 
+    /**
+     * 填报工作时长下限
+     */
+    @TableField("min_report_time")
+    private Float minReportTime;
+
     /**
      * 是否同步泛微考勤打卡和出差
      */

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

@@ -165,4 +165,15 @@ public interface ProjectMapper extends BaseMapper<Project> {
     List<Map<String, Object>> getTimeCostByToken(Integer companyId, String startDate, String endDate);
 
     List<UserCateTimeVo> getMembProjectCateTime(Integer companyId, String startDate, String endDate);
+
+    @Update("update project set incharger_id = null, finish_date = null, plan_start_date = null, plan_end_date=null, level=null,contract_amount=0.0,man_day=null where id = #{id} and is_public = 1")
+    void cleanPublicProjectData(Integer id);
+
+    List<Map<String, Object>> userProjectProcessList(Integer deptId, String userId, Integer projectId, Integer companyId,@Param("list") List<Integer> deptIds, Integer start, Integer size);
+
+    Long userProjectProcessCount(Integer deptId, String userId, Integer projectId, Integer companyId,@Param("list") List<Integer> deptIds);
+
+    List<Map<String, Object>> groupExpendProcessList(String userId, Integer companyId,@Param("list") List<Integer> deptIds, Integer start, Integer size);
+
+    Long groupExpendProcessListCount(String userId, Integer companyId,@Param("list") List<Integer> deptIds);
 }

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

@@ -72,7 +72,8 @@ public interface ReportMapper extends BaseMapper<Report> {
                                                  @Param("isEngeering") Integer isEngeering,
                                                  @Param("startDate") String startDate,
                                                  @Param("endDate") String endDate,
-                                                 @Param("targetUserId") List<String> targetUserId
+                                                 @Param("targetUserId") List<String> targetUserId,
+                                                 @Param("auditUserId")String auditUserId
                                                  );
 
     //获取本人负责的专业的相关的日报

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

@@ -11,6 +11,7 @@ public interface ExcelExportService {
     public HttpRespMsg exportGeneralExcelByTitleAndList(WxCorpInfo wxCorpInfo, String title, List<List<String>> list, String downloadPath) throws Exception;
     public HttpRespMsg exportGeneralExcelByTitleAndList2(WxCorpInfo wxCorpInfo, String title, List<List<String>> list, String downloadPath) throws Exception;
     public HttpRespMsg exportMultiSheetGeneralExcelByTitleAndList(WxCorpInfo wxCorpInfo,String title, List<List<String>>[] multiSheetList, String downloadPath,String[] sheetsName) throws Exception;
+    public HttpRespMsg exportTranForwx(WxCorpInfo wxCorpInfo,String title) throws Exception;
     void testAdd(String jobId);
 
     HttpRespMsg exportGeneralExcelForExpense(WxCorpInfo wxCorpInfo, String fileName, List<List<String>> allList, List<Map> mapList, String path) throws Exception;

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

@@ -272,4 +272,12 @@ public interface ProjectService extends IService<Project> {
     HttpRespMsg getProjectFillTime(HttpServletRequest request, Integer projectId);
 
     HttpRespMsg getMembProjectCateRatio(String startDate, String endDate, Integer onlyShowWarning);
+
+    HttpRespMsg userProjectProcessList(Integer deptId, String userId, Integer projectId, Integer pageIndex, Integer pageSize);
+
+    HttpRespMsg exportUserProjectProcessList(Integer deptId, String userId, Integer projectId);
+
+    HttpRespMsg groupExpendProcessList(String startDate, String endDate, Integer pageIndex, Integer pageSize);
+
+    HttpRespMsg exportGroupExpendProcessList(String startDate, String endDate);
 }

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

@@ -42,7 +42,7 @@ public interface ReportService extends IService<Report> {
                                String date,
                                String startDate,
                                String endDate,
-                               String userId,
+                               String userId,String auditUserId,
                                HttpServletRequest request);
 
     HttpRespMsg approveReport(String reportIds, Integer isDepartment, HttpServletRequest request,String evaluate);
@@ -145,4 +145,6 @@ public interface ReportService extends IService<Report> {
     HttpRespMsg exportUserWorkTimeByCategory(Integer categoryId, Integer deptId, String userId, String startDate, String endDate);
 
     HttpRespMsg cannelAllReport();
+
+    HttpRespMsg getHasPushForSap(String startDate, String endDate, String employeeID);
 }

+ 49 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ExcelExportServiceImpl.java

@@ -76,6 +76,7 @@ public class ExcelExportServiceImpl implements ExcelExportService {
         if(wxCorpInfo != null && wxCorpInfo.getSaasSyncContact() == 1){
             String mediaId = wxCorpInfoService.getTranslationMediaId(fileUrlSuffix);
             String jobId = wxCorpInfoService.syncTranslation(wxCorpInfo.getCorpid(),mediaId,fileUrlSuffix, null);
+            System.out.println("上传待转译文件到企业微信, jobId==" + jobId);
             int i = 0;
             String syncTranslationResult = null;
             /**
@@ -86,8 +87,10 @@ public class ExcelExportServiceImpl implements ExcelExportService {
             while (i < 30) {
                 if (i < 10) {
                     Thread.sleep(300);
-                } else {
+                } else if (i < 20){
                     Thread.sleep(1000);
+                } else {
+                    Thread.sleep(3000);
                 }
                 System.out.println("i=="+i+", "+LocalDateTime.now());
                 CorpwxJobResult corpwxJobResult = corpwxJobCenter.get(jobId);
@@ -264,6 +267,51 @@ public class ExcelExportServiceImpl implements ExcelExportService {
         return httpRespMsg;
     }
 
+    public  HttpRespMsg exportTranForwx(WxCorpInfo wxCorpInfo,String title) throws Exception {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        if (title.contains("/")) {
+            //文件名不能含有路径,得替换掉
+            title = title.replace("/", "@");
+        }
+        if (title.contains("\\")) {
+            //文件名不能含有路径,得替换掉
+            title = title.replace("\\", "@");
+        }
+        String fileUrlSuffix = title + ".xlsx";
+        if(wxCorpInfo != null && wxCorpInfo.getSaasSyncContact() == 1){
+            String mediaId = wxCorpInfoService.getTranslationMediaId(fileUrlSuffix);
+            String jobId = wxCorpInfoService.syncTranslation(wxCorpInfo.getCorpid(),mediaId,fileUrlSuffix, null);
+            int i = 0;
+            String syncTranslationResult = null;
+            /**
+             * 异步上传转译文件的任务完成时会触发回调,在WeiXinCorpController中的commonDevCallbackPost实现了对回调的处理,存储到corpwxJobResult表中
+             * 此处轮询查询本地数据库,检测到有任务的回调数据时继续执行查询操作
+             */
+            while (i < 10) {
+                Thread.sleep(300);
+                CorpwxJobResult corpwxJobResult = corpwxJobCenter.get(jobId);
+                if (corpwxJobResult != null) {
+                    if (corpwxJobResult.getErrCode() == 0) {
+                        syncTranslationResult = wxCorpInfoService.getSyncTranslationResult(jobId);
+                        corpwxJobCenter.remove(jobId);
+                    } else {
+                        httpRespMsg.setError(corpwxJobResult.getErrMsg());
+                        return httpRespMsg;
+                    }
+                    break;
+                }
+                i++;
+            }
+            if (syncTranslationResult != null) {
+                httpRespMsg.data = syncTranslationResult;
+            } else {
+                //httpRespMsg.setError("处理超时...");
+                httpRespMsg.setError(MessageUtils.message("request.outTime"));
+            }
+        }
+        return httpRespMsg;
+    }
+
     @Override
     public void testAdd(String jobId) {
         CorpwxJobResult corpwxJobResult = new CorpwxJobResult();

+ 306 - 5
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -32,11 +32,13 @@ import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.ss.usermodel.CellType;
-import org.apache.poi.xssf.usermodel.XSSFCell;
-import org.apache.poi.xssf.usermodel.XSSFRow;
-import org.apache.poi.xssf.usermodel.XSSFSheet;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.streaming.SXSSFCell;
+import org.apache.poi.xssf.streaming.SXSSFRow;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.*;
 import org.assertj.core.util.Lists;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Value;
@@ -693,6 +695,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         User user = userMapper.selectById(request.getHeader("Token"));
         Integer companyId = user.getCompanyId();
         TimeType timeType = timeTypeMapper.selectById(user.getCompanyId());
+        Company company = companyMapper.selectById(companyId);
         boolean isNew = true;
         //检查负责人要在参与人中
         if (!StringUtils.isEmpty(inchargerId)) {
@@ -1252,6 +1255,10 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
 
                 }
             }
+            //针对启用了简单非项目模式的情况,确保项目经理,级别,合同金额,开始日期,截止日期,预估工时都是null
+            if (company.getNonProjectSimple() == 1 && isPublic == 1) {
+                projectMapper.cleanPublicProjectData(id);
+            }
         }
         return httpRespMsg;
     }
@@ -12122,4 +12129,298 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             }
         }
     }
+
+    @Override
+    public HttpRespMsg userProjectProcessList(Integer deptId, String userId, Integer projectId,Integer pageIndex, Integer pageSize) {
+        HttpRespMsg msg=new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        Integer companyId = user.getCompanyId();
+        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;
+        Long total;
+        Integer size=null;
+        Integer start=null;
+        if(pageIndex!=null&&pageSize!=null){
+            size=pageSize;
+            start=(pageIndex-1)*size;
+        }
+        //是否具有查看全部数据的权限
+        if(!viewAll){
+            if(!incharger){
+                //只能查看本人的数据
+                resultList=projectMapper.userProjectProcessList(deptId,user.getId(),projectId,companyId,null,start,size);
+                total=projectMapper.userProjectProcessCount(deptId,user.getId(),projectId,companyId,null);
+            }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.userProjectProcessList(deptId,userId,projectId,companyId,deptIds,start,size);
+                total=projectMapper.userProjectProcessCount(deptId,userId,projectId,companyId,deptIds);
+            }
+        }else {
+            resultList=projectMapper.userProjectProcessList(deptId,userId,projectId,companyId,null,start,size);
+            total=projectMapper.userProjectProcessCount(deptId,userId,projectId,companyId,null);
+        }
+        Map<String,Object> resultMap=new HashMap<>();
+        resultMap.put("record",resultList);
+        resultMap.put("total",total);
+        msg.setData(resultMap);
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg exportUserProjectProcessList(Integer deptId, String userId, Integer projectId) {
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        HttpRespMsg resultMsg = userProjectProcessList(deptId, userId, projectId, null, null);
+        Map<String, Object> msgData = (Map<String, Object>) resultMsg.getData();
+        List<Map<String, Object>> mapList = (List<Map<String, Object>>) msgData.get("record");
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, companyId));
+        Company company = companyMapper.selectById(companyId);
+        //1.创建一个workbook,对应一个excel文件
+        SXSSFWorkbook workBook = new SXSSFWorkbook();
+        //2.在workbook中添加一个sheet,对应Excel中的sheet
+        SXSSFSheet sheet = workBook.createSheet("员工项目进度表");
+        //设置每一列的列宽
+        sheet.setColumnWidth(0,256*15);
+        sheet.setColumnWidth(1,256*15);
+        //3.设置样式以及字体样式
+        //设置冻结
+        sheet.createFreezePane(0, 2);
+        sheet.setDefaultColumnWidth(16);
+        //设置字体样式
+        Font headFont = workBook.createFont();
+        headFont.setBold(true);
+        headFont.setFontHeightInPoints((short) 10);
+        headFont.setFontName("黑体");
+
+        Font titleFont = workBook.createFont();
+        titleFont.setBold(true);
+        titleFont.setFontHeightInPoints((short) 10);
+        titleFont.setFontName("黑体");
+
+        Font font = workBook.createFont();
+        font.setFontHeightInPoints((short) 10);
+        font.setFontName("宋体");
+
+        //设置单元格样式
+        XSSFCellStyle headStyle = (XSSFCellStyle) workBook.createCellStyle();
+        headStyle.setFont(headFont);
+        headStyle.setAlignment(HorizontalAlignment.CENTER);
+        headStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+        headStyle.setWrapText(true);
+        headStyle.setBorderBottom(BorderStyle.THIN); //下边框
+        headStyle.setBorderLeft(BorderStyle.THIN);//左边框
+        headStyle.setBorderTop(BorderStyle.THIN);//上边框
+        headStyle.setBorderRight(BorderStyle.THIN);//右边框
+
+        String color = "c0c0c0";    //此处得到的color为16进制的字符串
+        //转为RGB码
+        int r = Integer.parseInt((color.substring(0,2)),16);   //转为16进制
+        int g = Integer.parseInt((color.substring(2,4)),16);
+        int b = Integer.parseInt((color.substring(4,6)),16);
+
+        //设置自定义颜色
+        XSSFColor xssfColor = new XSSFColor();
+        byte[] colorRgb = { (short)9, (byte) r, (byte) g, (byte) b };
+        xssfColor.setRGB(colorRgb);
+
+        headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index);
+        headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 填充模式(和背景颜色成对使用)
+        /*headStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex());*/ //设置自带的颜色
+
+        CellStyle titleStyle = workBook.createCellStyle();
+        titleStyle.setFont(titleFont);
+        titleStyle.setAlignment(HorizontalAlignment.CENTER);
+        titleStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+        titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);  //填充单元格
+        titleStyle.setFillForegroundColor((short)9);    //填色
+        titleStyle.setWrapText(true);
+        titleStyle.setBorderBottom(BorderStyle.THIN); //下边框
+        titleStyle.setBorderLeft(BorderStyle.THIN);//左边框
+        titleStyle.setBorderTop(BorderStyle.THIN);//上边框
+        titleStyle.setBorderRight(BorderStyle.THIN);//右边框
+
+        CellStyle cellStyle = workBook.createCellStyle();
+        cellStyle.setFont(font);
+        cellStyle.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+        cellStyle.setWrapText(true);
+        cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
+        cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
+        cellStyle.setBorderTop(BorderStyle.THIN);//上边框
+        cellStyle.setBorderRight(BorderStyle.THIN);//右边框
+        //行号
+        int rowNum = 0;
+        //第一行
+        SXSSFRow row0 = sheet.createRow(rowNum++);
+        row0.setHeight((short)500);
+        List<String> row_first =new ArrayList<>();
+        row_first.add("部门");
+        row_first.add("员工");
+        row_first.add("项目");
+        row_first.add("");
+        row_first.add("");
+        for (int i = 0; i < row_first.size(); i++) {
+            SXSSFCell tempCell = row0.createCell(i);
+            tempCell.setCellValue(row_first.get(i));
+            tempCell.setCellStyle(headStyle);
+        }
+        sheet.addMergedRegion(new CellRangeAddress(0,0,2,4));
+        sheet.addMergedRegion(new CellRangeAddress(0,1,0,0));
+        sheet.addMergedRegion(new CellRangeAddress(0,1,1,1));
+        //第二行
+        SXSSFRow row1 = sheet.createRow(rowNum++);
+        row1.setHeight((short)500);
+        List<String> row_second =new ArrayList<>();
+        row_second.add("");
+        row_second.add("");
+        row_second.add("项目名称");
+        row_second.add("项目编号");
+        row_second.add("剩余工时");
+        for (int i = 0; i < row_second.size(); i++) {
+            SXSSFCell tempCell = row1.createCell(i);
+            tempCell.setCellValue(row_second.get(i));
+            tempCell.setCellStyle(headStyle);
+        }
+        List<String> list=new ArrayList<>();
+        Map<String, List<Map<String, Object>>> listMapGroupList = mapList.stream().collect(Collectors.groupingBy(m -> String.valueOf(m.get("departmentName"))));
+        List<String> departmentNameList = mapList.stream().map(m -> String.valueOf(m.get("departmentName"))).distinct().collect(Collectors.toList());
+        //根据每个部门下数据长度合并部门名称列
+        int deptIndex=rowNum;
+        for (String deptName : departmentNameList) {
+            List<Map<String, Object>> maps = listMapGroupList.get(deptName);
+            //再根据每个部门下员工数据长度合并人员名称列
+            Map<String, List<Map<String, Object>>> listMapGroupList2 = maps.stream().collect(Collectors.groupingBy(m -> String.valueOf(m.get("jobNumber"))));
+            List<String> userNameList = maps.stream().map(m -> String.valueOf(m.get("jobNumber"))).distinct().collect(Collectors.toList());
+            if(maps.size()>1){
+                sheet.addMergedRegion(new CellRangeAddress(deptIndex,deptIndex+maps.size()-1,0,0));
+                int userIndex=deptIndex;
+                for (String userName : userNameList) {
+                    List<Map<String, Object>> mapList1 = listMapGroupList2.get(userName);
+                    if(mapList1.size()>1){
+                        sheet.addMergedRegion(new CellRangeAddress(userIndex,userIndex+mapList1.size()-1,1,1));
+                    }
+                    userIndex+=mapList1.size();
+                }
+            }
+            deptIndex+=maps.size();
+            for (int i = 0; i < maps.size(); i++) {
+                list.add("$departmentName="+String.valueOf(maps.get(i).get("corpwxDeptId"))+"$");
+                list.add("$userName="+maps.get(i).get("corpwxUserId")+"$");
+                list.add(String.valueOf(maps.get(i).get("projectName")));
+                list.add(String.valueOf(maps.get(i).get("projectCode")));
+                list.add(String.valueOf(maps.get(i).get("residueTime")));
+            }
+        }
+        int k=0;
+        for(int i = 0;i<mapList.size();i++){
+            SXSSFRow tempRow = sheet.createRow(rowNum++);
+            tempRow.setHeight((short)500);
+            for(int j=0;j<5;j++){
+                SXSSFCell tempCell = tempRow.createCell(j);
+                String cellValue = "";
+                tempCell.setCellStyle(cellStyle);
+                if(k>=list.size()){
+                    continue;
+                }
+                cellValue=list.get(k);
+                tempCell.setCellValue(cellValue);
+                k++;
+            }
+        }
+
+        //导出excel
+        String result="系统提示:Excel文件导出成功!";
+        String title= "员工项目进度表_"+company.getCompanyName()+System.currentTimeMillis();
+        String fileName= title+".xlsx";
+        try {
+            File dir = null;
+            dir = new File(path);
+            if (!dir.exists()) {
+                dir.mkdirs();
+            }
+            FileOutputStream os = new FileOutputStream(path+fileName);//保存到本地
+            workBook.write(os);
+            os.flush();
+            os.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        if(wxCorpInfo != null && wxCorpInfo.getSaasSyncContact() == 1){
+
+            try {
+                return excelExportService.exportTranForwx(wxCorpInfo, title);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        httpRespMsg.data ="/upload/"+fileName;
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg groupExpendProcessList(String startDate, String endDate, Integer pageIndex, Integer pageSize) {
+        HttpRespMsg msg=new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        Integer companyId = user.getCompanyId();
+        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;
+        Long total;
+        Integer size=null;
+        Integer start=null;
+        if(pageIndex!=null&&pageSize!=null){
+            size=pageSize;
+            start=(pageIndex-1)*size;
+        }
+        //是否具有查看全部数据的权限
+        if(!viewAll){
+            if(!incharger){
+                //只能查看本人的数据
+                resultList=projectMapper.groupExpendProcessList(user.getId(),companyId,null,start,size);
+                total=projectMapper.groupExpendProcessListCount(user.getId(),companyId,null);
+            }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.groupExpendProcessList(null,companyId,deptIds,start,size);
+                total=projectMapper.groupExpendProcessListCount(null,companyId,deptIds);
+            }
+        }else {
+            resultList=projectMapper.groupExpendProcessList(null,companyId,null,start,size);
+            total=projectMapper.groupExpendProcessListCount(null,companyId,null);
+        }
+        Map<String,Object> resultMap=new HashMap<>();
+        resultMap.put("record",resultList);
+        resultMap.put("total",total);
+        msg.setData(resultMap);
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg exportGroupExpendProcessList(String startDate, String endDate) {
+        return null;
+    }
 }

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

@@ -58,7 +58,7 @@ public class ReportBatchServiceImpl extends ServiceImpl<ReportBatchMapper, Repor
             if (!StringUtils.isEmpty(userId)) {
                 targetUids = ListUtil.convertLongIdsArrayToList(userId);
             }
-            List<Map<String, Object>> auditReportList = reportMapper.getAuditReportList(date, companyId, departmentId, projectId, leaderId, 0, startDate, endDate, targetUids);
+            List<Map<String, Object>> auditReportList = reportMapper.getAuditReportList(date, companyId, departmentId, projectId, leaderId, 0, startDate, endDate, targetUids,null);
             List<Integer> batchIds = new ArrayList<>();
             for (Map<String, Object> map : auditReportList) {
                 Integer batchId = (Integer)map.get("batchId");

+ 190 - 102
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -1604,7 +1604,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                       String date,
                                       String startDate,
                                       String endDate,
-                                      String userId,HttpServletRequest request) {
+                                      String userId,String auditUserId,HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             User curUser = userMapper.selectById(request.getHeader("Token"));
@@ -1620,7 +1620,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             if (!StringUtils.isEmpty(userId)) {
                 targetUids = ListUtil.convertLongIdsArrayToList(userId);
             }
-            List<Map<String, Object>> auditReportList = reportMapper.getAuditReportList(date, companyId, departmentId, projectId, leaderId, isEngeering, startDate, endDate, targetUids);
+            List<Map<String, Object>> auditReportList = reportMapper.getAuditReportList(date, companyId, departmentId, projectId, leaderId, isEngeering, startDate, endDate, targetUids,auditUserId);
             //针对依斯贝增加服务名称显示
             if (companyId == 3092) {
                 List<SapProjectService> serviceList = sapProjectServiceMapper.selectList(new QueryWrapper<SapProjectService>().eq("company_id", companyId));
@@ -2807,7 +2807,10 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         }
 
         if(timeType.getSyncSap()==1){
-            cancelReportPushSap(reportIds,user);
+            List<Integer> reportIdList = ListUtil.convertIntegerIdsArrayToList(reportIds);
+            List<ReportPushLog> reportPushLogs = reportPushLogService.list(new LambdaQueryWrapper<ReportPushLog>().in(ReportPushLog::getReportId, reportIdList));
+            String uuids = reportPushLogs.stream().map(ReportPushLog::getUuid).collect(Collectors.toList()).stream().collect(Collectors.joining(","));
+            cancelReportPushSap(uuids,user);
         }
         return httpRespMsg;
     }
@@ -5490,33 +5493,37 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                             if (company.getIsInternational() == 1) {
                                 operateDate = operateDate.plusSeconds(offsetSeconds);
                             }
+							
+								
                             String time = dtf.format(operateDate);
                             String msg= "";
-                            if(needCorpWxTranslate){
-                                Optional<User> first = userList.stream().filter(ul -> ul.getId().equals(audit.getOperatorId())).findFirst();
-                                if(first.isPresent()){
-                                    String corpwxUserId = first.get().getCorpwxUserid();
-                                    if (auditMsg.contains(corpwxUserId)) {
-                                        if(auditMsg.contains("提交了")){
-                                            int i = auditMsg.indexOf("提");
-                                            String substring = auditMsg.substring(0, i);
-                                            msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"\\$");
-                                        }else if(auditMsg.contains("审核通过了")){
-                                            int i = auditMsg.indexOf("审");
-                                            String substring = auditMsg.substring(0, i);
-                                            msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"\\$");
-                                        }else if(auditMsg.contains("驳回了")) {
-                                            int i = auditMsg.indexOf("驳");
-                                            String substring = auditMsg.substring(0, i);
-                                            msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"\\$");
-                                        }
-                                    } else {
-                                        msg = time+" " + auditMsg;
-                                    }
-                                }
-                            }else {
-                                msg = time+" " + auditMsg;
-                            }
+							if (auditMsg != null) {
+								if(needCorpWxTranslate){
+									Optional<User> first = userList.stream().filter(ul -> ul.getId().equals(audit.getOperatorId())).findFirst();
+									if(first.isPresent()){
+										String corpwxUserId = first.get().getCorpwxUserid();
+										if (!StringUtils.isEmpty(corpwxUserId) && auditMsg.contains(corpwxUserId)) {
+											if(auditMsg.contains("提交了")){
+												int i = auditMsg.indexOf("提");
+												String substring = auditMsg.substring(0, i);
+												msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"\\$");
+											}else if(auditMsg.contains("审核通过了")){
+												int i = auditMsg.indexOf("审");
+												String substring = auditMsg.substring(0, i);
+												msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"\\$");
+											}else if(auditMsg.contains("驳回了")) {
+												int i = auditMsg.indexOf("驳");
+												String substring = auditMsg.substring(0, i);
+												msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"\\$");
+											}
+										} else {
+											msg = time+" " + auditMsg;
+										}
+									}
+								}else {
+									msg = time+" " + auditMsg;
+								}
+							} 
                             if (!isFirst) {
                                 sb.append("->");
                             } else {
@@ -7146,6 +7153,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         HttpRespMsg msg = new HttpRespMsg();
         String userId = request.getHeader("TOKEN");
         User user = userMapper.selectById(userId);
+        Company company = companyMapper.selectById(user.getCompanyId());
         //根据targetDate获取本周的日期
         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
         LocalDate date = LocalDate.parse(targetDate, dtf);
@@ -7161,10 +7169,12 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("creator_id", userId).between("create_date", startDate, endDate).orderByAsc("create_date"));
 
         List<Integer> collect = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
+        List<User> auditorList = new ArrayList<>();
         //加载这段时间内已填报过的项目
         List<Project> projectList = new ArrayList<>();
         if (collect.size() > 0) {
             projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", collect));
+			auditorList = userMapper.selectList(new QueryWrapper<User>().in("id", reportList.stream().map(Report::getProjectAuditorId).collect(Collectors.toList())));
         } else {
             //没有项目,默认加载最近填报过的项目
             List<Report> oldReport = reportMapper.selectList(new QueryWrapper<Report>().select("distinct project_id").eq("creator_id", userId).orderByDesc("id").last("limit 5"));
@@ -7172,13 +7182,57 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", oldReport.stream().map(Report::getProjectId).collect(Collectors.toList())));
             }
         }
-//
-//        List<TaskGroup> allGroupList = taskGroupMapper.selectList(new QueryWrapper<TaskGroup>().in("project_id", projectList.stream().map(Project::getId).collect(Collectors.toList())));
-//        //获取当前日报项目下的所有任务分组
-//        for (Report report : reportList) {
-//            Integer targetPid = report.getProjectId();
-//            report.setTaskGroups(allGroupList.stream().filter(tg->tg.getProjectId().equals(targetPid)).collect(Collectors.toList()));
-//        }
+        List<SapProjectService> sapProjectServices = new ArrayList<>();
+        if (company.getId() == 3092) {
+            sapProjectServices = sapProjectServiceMapper.selectList(new QueryWrapper<SapProjectService>().eq("company_id",company.getId()));
+        }
+        //专业版要取任务分组
+        List<TaskGroup> allGroupList = new ArrayList<>();
+        List<Task> taskList = new ArrayList<>();
+        if (projectList.size() > 0) {
+            if (company.getPackageProject() == 1) {
+                allGroupList = taskGroupMapper.selectList(new QueryWrapper<TaskGroup>().in("project_id", projectList.stream().map(Project::getId).collect(Collectors.toList())));
+                taskList = taskMapper.selectList(new QueryWrapper<Task>().select("id, name").in("project_id", projectList.stream().map(Project::getId).collect(Collectors.toList())));
+            }
+            //获取当前日报项目下的所有任务分组
+            for (Report report : reportList) {
+                Integer targetPid = report.getProjectId();
+                if (company.getPackageProject() == 1) {
+                    report.setTaskGroups(allGroupList.stream().filter(tg->tg.getProjectId().equals(targetPid)).collect(Collectors.toList()));
+                    if (report.getGroupId() != null) {
+                        //设置已经填报的任务分组名称
+                        Optional<TaskGroup> optional = allGroupList.stream().filter(tg->tg.getId().equals(report.getGroupId())).findFirst();
+                        if (optional.isPresent()) {
+                            report.setGroupName(optional.get().getName());
+                        }
+                    }
+                    //任务名称设置
+                    if (report.getTaskId() != null) {
+                        Optional<Task> optional = taskList.stream().filter(t->t.getId().equals(report.getTaskId())).findFirst();
+                        if (optional.isPresent()) {
+                            report.setTaskName(optional.get().getName());
+                        }
+                    }
+                }
+                //设置项目名称
+                Optional<Project> optional = projectList.stream().filter(p->p.getId().equals(report.getProjectId())).findFirst();
+                if (optional.isPresent()) {
+                    report.setProjectName(optional.get().getProjectName());
+                }
+                //设置ProjectAuditorName
+                Optional<User> optionalUser = auditorList.stream().filter(u->u.getId().equals(report.getProjectAuditorId())).findFirst();
+                if (optionalUser.isPresent()) {
+                    report.setProjectAuditorName(optionalUser.get().getName());
+                }
+                if (company.getId() == 3092) {
+                    //依斯倍有SapServiceName
+                    Optional<SapProjectService> optionalSap = sapProjectServices.stream().filter(s->s.getId().equals(report.getSapServiceId())).findFirst();
+                    if (optionalSap.isPresent()) {
+                        report.setSapServiceName(optionalSap.get().getServiceName());
+                    }
+                }
+            }
+        }
 
         List cardTimeList = new ArrayList();
         if (timeType.getShowDdCardtime() == 1) {
@@ -7349,8 +7403,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         //需要填报的最后一天
         LocalDate lastDayOfWeek = sunday;
         int days = sunday.lengthOfMonth() - sunday.getDayOfMonth();
-        if (days <= 2) {
-            //周日距离月底相差天数在2天以内,比如周日是10.29,则10.30和10.31也算在本周内
+        if (days <= 3) {
+            //周日距离月底相差天数在3天以内,比如周日是10.28,则10.29,10.30和10.31也算在本周内
             lastDayOfWeek = sunday.plusDays(days);
         }
         //如果上周只有2天以内工作日,需要并到这周来
@@ -7358,7 +7412,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         LocalDate lastSaturday = lastSunday.with(DayOfWeek.SATURDAY);
 
         if (WorkDayCalculateUtils.isWorkDay(lastSunday) && WorkDayCalculateUtils.isWorkDay(lastSaturday)) {
-            //上周周末两天是工作日,并且只有2天以内工作日,需要并到这周来
+            //合并上周的工作日的情况:上周周末两天是工作日,并且只有2天以内工作日,需要并到这周来
             LocalDate lastMonday = lastSunday.with(DayOfWeek.MONDAY);
             boolean hasMoreWorkDays = false;
             while (lastMonday.isBefore(lastSaturday)) {
@@ -7371,15 +7425,33 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             if (!hasMoreWorkDays) {
                 firstDayOfWeek = lastSaturday;
             }
-        }
-        //如果本周一周二中有工作日,但是是上个月的月末,会被合并到上周去,本周要去掉
-        if (WorkDayCalculateUtils.isWorkDay(firstDayOfWeek) && firstDayOfWeek.getDayOfMonth() >= 30) {
-            firstDayOfWeek = firstDayOfWeek.plusDays(1);
-            if (WorkDayCalculateUtils.isWorkDay(firstDayOfWeek) && firstDayOfWeek.getDayOfMonth() >= 30) {
-                firstDayOfWeek = firstDayOfWeek.plusDays(1);
+        } else {
+            //剔除被合并到上周的情况,如果本周一周二周三中有工作日,但是是上个月的月末,会被合并到上周去,本周要去掉
+            boolean hasFirstDayOfMonth = false;
+            LocalDate checkDate = firstDayOfWeek;
+            int beforeDays = 0;
+            while (!checkDate.isAfter(lastDayOfWeek)) {
+                if (checkDate.getDayOfMonth() == 1) {
+                    hasFirstDayOfMonth = true;
+                    break;
+                } else {
+                    beforeDays++;
+                }
+                checkDate = checkDate.plusDays(1);
+            }
+            if (hasFirstDayOfMonth && beforeDays <= 3) {
+                firstDayOfWeek = checkDate;
             }
         }
 
+//        if (WorkDayCalculateUtils.isWorkDay(firstDayOfWeek) && firstDayOfWeek.getDayOfMonth() >= 30) {
+//            firstDayOfWeek = firstDayOfWeek.plusDays(1);
+//            if (WorkDayCalculateUtils.isWorkDay(firstDayOfWeek) && firstDayOfWeek.getDayOfMonth() >= 30) {
+//                firstDayOfWeek = firstDayOfWeek.plusDays(1);
+//            }
+//        }
+
+
         //再按照当前用户的入职离职日期进行过滤
         LocalDate entryDate = user.getInductionDate();
         LocalDate leaveDate = user.getInactiveDate();
@@ -7654,73 +7726,73 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     @Override
     public HttpRespMsg cannelAllReport() {
         List<ReportPushLog> list = reportPushLogService.list();
-        List<Integer> collect = list.stream().map(ReportPushLog::getReportId).distinct().collect(Collectors.toList());
-        String s = collect.stream().map(m -> String.valueOf(m)).collect(Collectors.joining(","));
+        List<String> collect = list.stream().map(ReportPushLog::getUuid).distinct().collect(Collectors.toList());
+        String s = collect.stream().map(m -> m).collect(Collectors.joining(","));
         User user = userMapper.selectById(request.getHeader("token"));
         cancelReportPushSap(s,user);
         return null;
     }
 
-    public void  cancelReportPushSap(String reportIds, User user){
-        if(!StringUtils.isEmpty(reportIds)){
+    public void  cancelReportPushSap(String uuids, User user){
+        if(!StringUtils.isEmpty(uuids)){
             LocalDateTime localDateTime=LocalDateTime.now();
             List<SapSyncLog> sapSyncLogs=new ArrayList<>();
-            List<Integer> reportIdList = ListUtil.convertIntegerIdsArrayToList(reportIds);
-            List<ReportPushLog> reportPushLogList = reportPushLogService.list(new LambdaQueryWrapper<ReportPushLog>().in(ReportPushLog::getReportId, reportIdList));
-            for (Integer reportId : reportIdList) {
-                Optional<ReportPushLog> first = reportPushLogList.stream().filter(r -> r.getReportId().equals(reportId)).findFirst();
-                if(first.isPresent()){
-                    XmlRequestData xmlRequestData=new XmlRequestData();
-                    ZDeleteEmployeeTime zDeleteEmployeeTime=new ZDeleteEmployeeTime();
-                    zDeleteEmployeeTime.setEmployeeTimeUUID(first.get().getUuid()==null?"":first.get().getUuid());
-                    xmlRequestData.setZDeleteEmployeeTime(zDeleteEmployeeTime);
-                    String xml = CommonUtils.convertToXml(xmlRequestData);
-                    System.out.println(xml);
-                    xml=xml.substring(xml.indexOf("<XMLDATA>")+9,xml.lastIndexOf("</XMLDATA>"));
-                    StringBuffer sb = new StringBuffer();
-                    sb.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:glob=\"http://sap.com/xi/SAPGlobal20/Global\">\n" +
-                            "   <soapenv:Header/>\n" +
-                            "   <soapenv:Body>\n" +
-                            "      <glob:ZDeleteEmployeeTimeCreateRequest_sync>\n");
-                    sb.append(xml);
-                    sb.append("      </glob:ZDeleteEmployeeTimeCreateRequest_sync>\n" +
-                            "   </soapenv:Body>\n" +
-                            "</soapenv:Envelope>");
-                    System.out.println(sb.toString());
-                    String result = "";
-                    try {
-                        if(isDev){
-                            result = WebServiceUtils.requestByXml("https://my602728.sapbyd.cn/sap/bc/srt/scs/sap/yyatr5vf6y_deleteemployeetime?sap-vhost=my602728.sapbyd.cn", sb.toString(), 0, "_BYDHOST", "Welcome1");
-                        }else{
-                            result = WebServiceUtils.requestByXml("https://my601432.sapbyd.cn/sap/bc/srt/scs/sap/yyatr5vf6y_deleteemployeetime?sap-vhost=my601432.sapbyd.cn", sb.toString(), 0, "_BYDHOST", "Welcome1");
-                        }
+            List<String> uuidList = ListUtil.convertLongIdsArrayToList(uuids);
+            for (String uuid : uuidList) {
+                int count = reportPushLogService.count(new LambdaQueryWrapper<ReportPushLog>().eq(ReportPushLog::getUuid, uuid));
+                if(count>0){
+                    continue;
+                }
+                XmlRequestData xmlRequestData=new XmlRequestData();
+                ZDeleteEmployeeTime zDeleteEmployeeTime=new ZDeleteEmployeeTime();
+                zDeleteEmployeeTime.setEmployeeTimeUUID(uuid);
+                xmlRequestData.setZDeleteEmployeeTime(zDeleteEmployeeTime);
+                String xml = CommonUtils.convertToXml(xmlRequestData);
+                System.out.println(xml);
+                xml=xml.substring(xml.indexOf("<XMLDATA>")+9,xml.lastIndexOf("</XMLDATA>"));
+                StringBuffer sb = new StringBuffer();
+                sb.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:glob=\"http://sap.com/xi/SAPGlobal20/Global\">\n" +
+                        "   <soapenv:Header/>\n" +
+                        "   <soapenv:Body>\n" +
+                        "      <glob:ZDeleteEmployeeTimeCreateRequest_sync>\n");
+                sb.append(xml);
+                sb.append("      </glob:ZDeleteEmployeeTimeCreateRequest_sync>\n" +
+                        "   </soapenv:Body>\n" +
+                        "</soapenv:Envelope>");
+                System.out.println(sb.toString());
+                String result = "";
+                try {
+                    result = WebServiceUtils.requestByXml("https://my601432.sapbyd.cn/sap/bc/srt/scs/sap/yyatr5vf6y_deleteemployeetime?sap-vhost=my601432.sapbyd.cn", sb.toString(), 0, "_BYDHOST", "Welcome1");
+//                    if(isDev){
+//                        result = WebServiceUtils.requestByXml("https://my602728.sapbyd.cn/sap/bc/srt/scs/sap/yyatr5vf6y_deleteemployeetime?sap-vhost=my602728.sapbyd.cn", sb.toString(), 0, "_BYDHOST", "Welcome1");
+//                    }else{
 //                        result = WebServiceUtils.requestByXml("https://my601432.sapbyd.cn/sap/bc/srt/scs/sap/yyatr5vf6y_deleteemployeetime?sap-vhost=my601432.sapbyd.cn", sb.toString(), 0, "_BYDHOST", "Welcome1");
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    if(!StringUtils.isEmpty(result)) {
-                        result = result.substring(result.indexOf("<soap-env:Body>")+15, result.lastIndexOf("</soap-env:Body>"));
-                        result = result.substring(result.indexOf(">")+1, result.lastIndexOf("</n0:ZDeleteEmployeeTimeCreateConfirmation_sync>"));
-                        result="<XMLDATA>"+result+"</XMLDATA>";
-                    }
-                    System.out.println(result);
-                    XmlResponseData xmlResponseData = (XmlResponseData) CommonUtils.convertXmlStrToObject(XmlResponseData.class, result);
-                    SapSyncLog sapSyncLog=new SapSyncLog();
-                    sapSyncLog.setCompanyId(user.getCompanyId());
-                    sapSyncLog.setRemark("日报数据取消推送");
-                    sapSyncLog.setSyncType("手动推送");
-                    sapSyncLog.setOperator(user.getJobNumber());
-                    sapSyncLog.setSyncTime(localDateTime);
-                    if(StringUtils.isEmpty(xmlResponseData.getZDeleteEmployeeTime())){
-                        log.error("推送取消考勤失败===》UUID:"+xmlRequestData.getZDeleteEmployeeTime().getEmployeeTimeUUID());
-                        sapSyncLog.setResult("推送取消考勤失败");
-                    }else {
-                        //删除推送记录
-                        sapSyncLog.setResult("推送取消考勤成功");
-                        reportPushLogService.remove(new LambdaQueryWrapper<ReportPushLog>().eq(ReportPushLog::getReportId,reportId));
-                    }
-                    sapSyncLogs.add(sapSyncLog);
+//                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                if(!StringUtils.isEmpty(result)) {
+                    result = result.substring(result.indexOf("<soap-env:Body>")+15, result.lastIndexOf("</soap-env:Body>"));
+                    result = result.substring(result.indexOf(">")+1, result.lastIndexOf("</n0:ZDeleteEmployeeTimeCreateConfirmation_sync>"));
+                    result="<XMLDATA>"+result+"</XMLDATA>";
+                }
+                System.out.println(result);
+                XmlResponseData xmlResponseData = (XmlResponseData) CommonUtils.convertXmlStrToObject(XmlResponseData.class, result);
+                SapSyncLog sapSyncLog=new SapSyncLog();
+                sapSyncLog.setCompanyId(user.getCompanyId());
+                sapSyncLog.setRemark("日报数据取消推送");
+                sapSyncLog.setSyncType("手动推送");
+                sapSyncLog.setOperator(user.getJobNumber());
+                sapSyncLog.setSyncTime(localDateTime);
+                if(StringUtils.isEmpty(xmlResponseData.getZDeleteEmployeeTime())){
+                    log.error("推送取消考勤失败===》UUID:"+xmlRequestData.getZDeleteEmployeeTime().getEmployeeTimeUUID());
+                    sapSyncLog.setResult("推送取消考勤失败");
+                }else {
+                    //删除推送记录
+                    sapSyncLog.setResult("推送取消考勤成功");
+                    reportPushLogService.remove(new LambdaQueryWrapper<ReportPushLog>().eq(ReportPushLog::getUuid,uuid));
                 }
+                sapSyncLogs.add(sapSyncLog);
             }
             if(sapSyncLogs.size()>0){
                 sapSyncLogService.saveBatch(sapSyncLogs);
@@ -8363,4 +8435,20 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         result.add(start);
         return result;
     }
+
+    @Override
+    public HttpRespMsg getHasPushForSap(String startDate, String endDate, String employeeID) {
+        HttpRespMsg msg=new HttpRespMsg();
+        XmlResponseData hasPushForSap = SyncSapUtils.getHasPushForSap(startDate, endDate, employeeID, isDev);
+        User user = userMapper.selectById(request.getHeader("token"));
+        Integer companyId = user.getCompanyId();
+        //是否要撤销相关数据
+        List<ActualEmployeeTime> actualEmployeeTimes = hasPushForSap.getActualEmployeeTimes();
+        List<String> allUuids = actualEmployeeTimes.stream().map(ActualEmployeeTime::getUUID).distinct().collect(Collectors.toList());
+        List<String> needUuidList=new ArrayList<>();
+        String uuids = allUuids.stream().map(n -> n).collect(Collectors.joining(","));
+        cancelReportPushSap(uuids,user);
+        msg.setData(actualEmployeeTimes);
+        return msg;
+    }
 }

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -1701,7 +1701,7 @@ public class TimingTask {
         for (TimeType timeType : timeTypeList) {
             Integer companyId = timeType.getCompanyId();
             //提前推送项目工时(工时管家相关项目任务分组阶段下任务作为SAP服务 预算工时数据推送到SAP)
-            List<Map<String, Object>> mapList = reportMapper.getPushProjectReportToSap(companyId,df.format(date.minusDays(8)),df.format(date.minusDays(8)), null);
+            List<Map<String, Object>> mapList = reportMapper.getPushProjectReportToSap(companyId,df.format(date.minusDays(1)),df.format(date.minusDays(1)), null);
             //过滤服务code为空的数据
             mapList=mapList.stream().filter(r->r.get("ProjectElementID")!=null && !StringUtils.isEmpty(String.valueOf(r.get("ProjectElementID")))).collect(Collectors.toList());
             List<Integer> projectIds = mapList.stream().map(r -> Integer.valueOf(String.valueOf(r.get("ProjectId")))).distinct().collect(Collectors.toList());

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

@@ -78,10 +78,10 @@ public class BeiSenUtils {
         requestMap.put("startTime",startTime+"T00:00:00");
         requestMap.put("stopTime",stopTime+"T23:59:59");
         System.out.println("--------headers请求头数据-------"+headers);
-        System.out.println("--------requestMap请求参数-------"+requestMap);
         if(!StringUtils.isEmpty(scrollId)){
             requestMap.put("scrollId",scrollId);
         }
+        System.out.println("--------requestMap请求参数-------"+requestMap);
         HttpEntity<JSONObject> entity = new HttpEntity<>(requestMap, headers);
         ResponseEntity<String> ResponseEntity = restTemplate.postForEntity(url, entity, String.class);
         if (ResponseEntity.getStatusCode() == HttpStatus.OK) {

+ 64 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/SyncSapUtils.java

@@ -82,6 +82,7 @@ public class SyncSapUtils {
             sb.append("      </glob:ZManageProjectTaskWorkCreateRequest_sync>\n" +
                     "   </soapenv:Body>\n" +
                     "</soapenv:Envelope>");
+            System.out.println(sb.toString());
             String result = "";
             try {
                 if(isDev){
@@ -173,6 +174,7 @@ public class SyncSapUtils {
                 "   </soapenv:Body>\n" +
                 "</soapenv:Envelope>");
         String result = "";
+        System.out.println(sb.toString());
         XmlResponseData xmlResponseData = new XmlResponseData();
         try {
             if(isDev){
@@ -185,6 +187,7 @@ public class SyncSapUtils {
                 result = result.substring(result.indexOf(">")+1, result.lastIndexOf("</n0:EmployeeTimeAsBundleMaintainConfirmation_sync>"));
                 result="<XMLDATA>"+result+"</XMLDATA>";
             }
+            System.out.println(result);
             return result;
         } catch (Exception e) {
             e.printStackTrace();
@@ -264,6 +267,67 @@ public class SyncSapUtils {
     }
 
 
+    //同步SAP项目数据到工时管家
+    public static XmlResponseData getHasPushForSap(String startDate, String endDate,String employeeID,boolean isDev) {
+        //配置请求xml
+        XmlRequestData xmlRequestData=new XmlRequestData();
+        ProcessingConditions processingConditions=new ProcessingConditions();
+        processingConditions.setQueryHitsUnlimitedIndicator("true");
+        xmlRequestData.setProcessingConditions(processingConditions);
+        ActualEmployeeTimeSelectionByElements actualEmployeeTimeSelectionByElements=new ActualEmployeeTimeSelectionByElements();
+        if(!StringUtils.isEmpty(startDate)&&!StringUtils.isEmpty(endDate)){
+            SelectionByDate selectionByDate=new SelectionByDate();
+            selectionByDate.setInclusionExclusionCode("I");
+            selectionByDate.setIntervalBoundaryTypeCode("3");
+            selectionByDate.setLowerBoundaryDate(startDate);
+            selectionByDate.setUpperBoundaryDate(endDate);
+            actualEmployeeTimeSelectionByElements.setSelectionByDate(selectionByDate);
+        }
+        if (!StringUtils.isEmpty(employeeID)){
+            SelectionByEmployeeID selectionByEmployeeID=new SelectionByEmployeeID();
+            selectionByEmployeeID.setInclusionExclusionCode("I");
+            selectionByEmployeeID.setIntervalBoundaryTypeCode("1");
+            selectionByEmployeeID.setLowerBoundaryEmployeeID(employeeID);
+            actualEmployeeTimeSelectionByElements.setSelectionByEmployeeID(selectionByEmployeeID);
+        }
+        if(StringUtils.isEmpty(startDate)&&StringUtils.isEmpty(endDate)&&StringUtils.isEmpty(employeeID)){
+            return new XmlResponseData();
+        }
+        xmlRequestData.setActualEmployeeTimeSelectionByElements(actualEmployeeTimeSelectionByElements);
+        String xml = CommonUtils.convertToXml(xmlRequestData);
+        xml=xml.substring(xml.indexOf("<XMLDATA>")+9,xml.lastIndexOf("</XMLDATA>"));
+        StringBuffer sb = new StringBuffer();
+        sb.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:glob=\"http://sap.com/xi/SAPGlobal20/Global\">\n" +
+                "   <soapenv:Header/>\n" +
+                "   <soapenv:Body>\n" +
+                "      <glob:ActualEmployeeTimeByElementsQuery_sync>\n");
+        sb.append(xml);
+        sb.append("      </glob:ActualEmployeeTimeByElementsQuery_sync>\n" +
+                "   </soapenv:Body>\n" +
+                "</soapenv:Envelope>");
+        System.out.println(sb.toString());
+        String result = "";
+        try {
+            result = WebServiceUtils.requestByXml("https://my601432.sapbyd.cn/sap/bc/srt/scs/sap/queryemployeetimein?sap-vhost=my601432.sapbyd.cn", sb.toString(), 0, "_BYDHOST", "Welcome1");
+//            if(isDev){
+//                result = WebServiceUtils.requestByXml("https://my602728.sapbyd.cn/sap/bc/srt/scs/sap/queryemployeetimein?sap-vhost=my602728.sapbyd.cn", sb.toString(), 0, "_BYDHOST", "Welcome1");
+//            }else {
+//                result = WebServiceUtils.requestByXml("https://my601432.sapbyd.cn/sap/bc/srt/scs/sap/queryemployeetimein?sap-vhost=my601432.sapbyd.cn", sb.toString(), 0, "_BYDHOST", "Welcome1");
+//            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        if(!StringUtils.isEmpty(result)) {
+            result = result.substring(result.indexOf("<soap-env:Body>")+15, result.lastIndexOf("</soap-env:Body>"));
+            result = result.substring(result.indexOf(">")+1, result.lastIndexOf("</n0:ActualEmployeeTimeByElementsResponse_sync>"));
+            result="<XMLDATA>"+result+"</XMLDATA>";
+        }
+        System.out.println(result);
+        XmlResponseData xmlResponseData = (XmlResponseData) CommonUtils.convertXmlStrToObject(XmlResponseData.class, result);
+        return xmlResponseData;
+    }
+
+
     //同步SAP项目服务数据到工时管家
     public static XmlResponseData syncServiceData(String startDate, String endDate, Integer companyId,boolean isDev) {
         //配置请求xml

+ 70 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/ActualEmployeeTime.java

@@ -0,0 +1,70 @@
+package com.management.platform.webservice.po;
+
+import lombok.Data;
+
+import javax.xml.bind.annotation.XmlElement;
+
+@Data
+public class ActualEmployeeTime {
+
+    private String changeStateID;
+    private String UUID;
+    private String workAgreementID;
+    private String itemTypeCode;
+    private SapPeriod datePeriod;
+    private String duration;
+    private String lifeCycleStatusCode;
+    private String approvalStatusCode;
+    private String projectElementID;
+    private String serviceProductInternalID;
+
+    @XmlElement(name = "ChangeStateID")
+    public String getChangeStateID(){
+        return changeStateID;
+    }
+
+    @XmlElement(name = "UUID")
+    public String getUUID(){
+        return UUID;
+    }
+
+    @XmlElement(name = "WorkAgreementID")
+    public String getWorkAgreementID(){
+        return workAgreementID;
+    }
+
+    @XmlElement(name = "ItemTypeCode")
+    public String getItemTypeCode(){
+        return itemTypeCode;
+    }
+
+    @XmlElement(name = "DatePeriod")
+    public SapPeriod getDatePeriod(){
+        return datePeriod;
+    }
+
+    @XmlElement(name = "Duration")
+    public String getDuration() {
+        return duration;
+    }
+
+    @XmlElement(name = "LifeCycleStatusCode")
+    public String getLifeCycleStatusCode(){
+        return lifeCycleStatusCode;
+    }
+
+    @XmlElement(name = "ApprovalStatusCode")
+    public String getApprovalStatusCode(){
+        return approvalStatusCode;
+    }
+
+    @XmlElement(name = "ProjectElementID")
+    public String getProjectElementID(){
+        return projectElementID;
+    }
+
+    @XmlElement(name = "ServiceProductInternalID")
+    public String getServiceProductInternalID(){
+        return serviceProductInternalID;
+    }
+}

+ 22 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/ActualEmployeeTimeSelectionByElements.java

@@ -0,0 +1,22 @@
+package com.management.platform.webservice.po;
+
+import lombok.Data;
+
+import javax.xml.bind.annotation.XmlElement;
+
+@Data
+public class ActualEmployeeTimeSelectionByElements {
+    private SelectionByEmployeeID selectionByEmployeeID;
+    private SelectionByDate selectionByDate;
+
+    @XmlElement(name = "SelectionByEmployeeID")
+    public SelectionByEmployeeID getSelectionByEmployeeID() {
+        return selectionByEmployeeID;
+    }
+
+
+    @XmlElement(name = "SelectionByDate")
+    public SelectionByDate getSelectionByDate() {
+        return selectionByDate;
+    }
+}

+ 7 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/ProcessingConditions.java

@@ -10,6 +10,7 @@ public class ProcessingConditions {
     private String queryHitsUnlimitedIndicator;
     private String returnedQueryHitsNumberValue;
     private String queryHitsMaximumNumberValue;
+    private String moreHitsAvailableIndicator;
 
     @XmlElement(name = "QueryHitsUnlimitedIndicator")
     public String getQueryHitsUnlimitedIndicator() {
@@ -27,4 +28,10 @@ public class ProcessingConditions {
         return returnedQueryHitsNumberValue;
     }
 
+    //返回的项目条数
+    @XmlElement(name = "MoreHitsAvailableIndicator")
+    public String getMoreHitsAvailableIndicator() {
+        return moreHitsAvailableIndicator;
+    }
+
 }

+ 33 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/SelectionByDate.java

@@ -0,0 +1,33 @@
+package com.management.platform.webservice.po;
+
+import lombok.Data;
+
+import javax.xml.bind.annotation.XmlElement;
+
+@Data
+public class SelectionByDate {
+    private String inclusionExclusionCode;
+    private String intervalBoundaryTypeCode;
+    private String lowerBoundaryDate;
+    private String upperBoundaryDate;
+
+    @XmlElement(name = "InclusionExclusionCode")
+    public String getInclusionExclusionCode() {
+        return inclusionExclusionCode;
+    }
+
+    @XmlElement(name = "IntervalBoundaryTypeCode")
+    public String getIntervalBoundaryTypeCode() {
+        return intervalBoundaryTypeCode;
+    }
+
+    @XmlElement(name = "LowerBoundaryDate")
+    public String getLowerBoundaryDate() {
+        return lowerBoundaryDate;
+    }
+
+    @XmlElement(name = "UpperBoundaryDate")
+    public String getUpperBoundaryDate() {
+        return upperBoundaryDate;
+    }
+}

+ 29 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/SelectionByEmployeeID.java

@@ -0,0 +1,29 @@
+package com.management.platform.webservice.po;
+
+import lombok.Data;
+
+import javax.xml.bind.annotation.XmlElement;
+
+@Data
+public class SelectionByEmployeeID {
+
+    private String inclusionExclusionCode;
+    private String intervalBoundaryTypeCode;
+    private String lowerBoundaryEmployeeID;
+
+    @XmlElement(name = "InclusionExclusionCode")
+    public String getInclusionExclusionCode() {
+        return inclusionExclusionCode;
+    }
+
+    @XmlElement(name = "IntervalBoundaryTypeCode")
+    public String getIntervalBoundaryTypeCode() {
+        return intervalBoundaryTypeCode;
+    }
+
+    @XmlElement(name = "LowerBoundaryEmployeeID")
+    public String getLowerBoundaryEmployeeID() {
+        return lowerBoundaryEmployeeID;
+    }
+
+}

+ 6 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/XmlRequestData.java

@@ -21,6 +21,7 @@ public class XmlRequestData {
 	private EmployeeTime employeeTime;
 	private String basicMessageHeader;
 	private ZDeleteEmployeeTime zDeleteEmployeeTime;
+	private ActualEmployeeTimeSelectionByElements actualEmployeeTimeSelectionByElements;
 
 	@XmlElement(name = "ProcessingConditions")
 	public ProcessingConditions getProcessingConditions() {
@@ -57,4 +58,9 @@ public class XmlRequestData {
 		return zDeleteEmployeeTime;
 	}
 
+	@XmlElement(name = "ActualEmployeeTimeSelectionByElements")
+	public ActualEmployeeTimeSelectionByElements getActualEmployeeTimeSelectionByElements() {
+		return actualEmployeeTimeSelectionByElements;
+	}
+
 }

+ 6 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/webservice/po/XmlResponseData.java

@@ -25,6 +25,7 @@ public class XmlResponseData{
 
 	private EmployeeTime employeeTime;
 	private ZDeleteEmployeeTime zDeleteEmployeeTime;
+	private List<ActualEmployeeTime> actualEmployeeTimes;
 
 	
 	@XmlElement(name = "ServiceProduct")
@@ -62,4 +63,9 @@ public class XmlResponseData{
 		return zDeleteEmployeeTime;
 	}
 
+	@XmlElement(name = "ActualEmployeeTime")
+	public List<ActualEmployeeTime> getActualEmployeeTimes() {
+		return actualEmployeeTimes;
+	}
+
 }

+ 97 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml

@@ -1778,4 +1778,101 @@
         GROUP BY user.id, project.`category`
     </select>
 
+    <select id="userProjectProcessList" resultType="java.util.Map">
+        select d.department_name as departmentName,d.corpwx_deptid as corpwxDeptId,u.corpwx_userid as corpwxUserId,u.name as userName,u.job_number as jobNumber,p.project_name as projectName,p.project_code as projectCode,
+        IFNULL(IFNULL(SUM(te.plan_hours),0)-IFNULL((select SUM(working_time) from report where task_id=te.task_id),0),0)as residueTime
+        from task_executor te
+        left join  user u on u.id=te.executor_id
+        left join department d on d.department_id=u.department_id
+        left join project p on p.id=te.project_id
+        where u.company_id=#{companyId} and te.project_id is not null and d.department_name in ('4','12','14')
+        <if test="deptId!=null">
+            and d.department_id=#{deptId}
+        </if>
+        <if test="userId!=null and userId!=''">
+            and u.id=#{userId}
+        </if>
+        <if test="projectId!=null">
+            and p.id=#{project}
+        </if>
+        <if test="list!=null and list.size()>0">
+            and d.department_id in
+            <foreach collection="list" open="(" close=")" item="item" separator=",">
+                #{item}
+            </foreach>
+        </if>
+        group by te.executor_id,te.project_id
+        order by d.department_id,u.id
+        <if test="start!=null and size!=null">
+            limit #{start},#{size}
+        </if>
+    </select>
+
+
+    <select id="userProjectProcessCount" resultType="java.lang.Long">
+        select count(1) from (
+            select d.department_name as departmentName
+            from task_executor te
+            left join  user u on u.id=te.executor_id
+            left join department d on d.department_id=u.department_id
+            left join project p on p.id=te.project_id
+            where u.company_id=#{companyId} and te.project_id is not null and d.department_name in ('4','12','14')
+            <if test="deptId!=null">
+                and d.department_id=#{deptId}
+            </if>
+            <if test="userId!=null and userId!=''">
+                and u.id=#{userId}
+            </if>
+            <if test="projectId!=null">
+                and p.id=#{project}
+            </if>
+            <if test="list!=null and list.size()>0">
+                and d.department_id in
+                <foreach collection="list" open="(" close=")" item="item" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            group by te.executor_id,te.project_id
+        ) as total
+    </select>
+
+    <select id="groupExpendProcessList" resultType="java.util.Map">
+        select d.department_name,tg.name as groupName,IFNULL(SUM(te.plan_hours),0) as planHour,
+        IFNULL(IFNULL((select SUM(working_time) from report where task_id=te.task_id <if test="startDate!=null and endDate!=null">
+            create_date between #{startDate} and #{endDate}
+        </if> ),0)-IFNULL((select SUM(overtime_hours) from report where task_id=te.task_id <if test="startDate!=null and endDate!=null">
+        create_date between #{startDate} and #{endDate}
+        </if>),0),0) as normalHour,
+        IFNULL((select SUM(overtime_hours) from report where task_id=te.task_id <if test="startDate!=null and endDate!=null">
+        create_date between #{startDate} and #{endDate}
+        </if>),0) as overHour,
+        IFNULL((select SUM(working_time) from report where task_id=te.task_id <if test="startDate!=null and endDate!=null">
+        create_date between #{startDate} and #{endDate}
+        </if>),0) as realHour,
+        IFNULL((select SUM(cost) from report where task_id=te.task_id <if test="startDate!=null and endDate!=null">
+        create_date between #{startDate} and #{endDate}
+        </if>),0) as realCost
+        from task_executor te
+        left join  user u on u.id=te.executor_id
+        left join task t on t.id=te.task_id
+        left join task_group tg on tg.id=t.group_id
+        left join department d on d.department_id=u.department_id
+        where u.company_id=#{companyId} and te.project_id is not null and d.department_name in ('4','12','14')
+        and tg.name in ('生产部电气','生产部车间','工程部现场安装施工','工程部配合调试','研发部工艺设计','研发部结构设计','研发部BIM设计','研发部电气设计','研发部工艺调试验收','研发部电气调试验收')
+        <if test="userId!=null and userId!=''">
+            te.executor_id=#{userId}
+        </if>
+        <if test="list!=null and list.size()>0">
+            and d.department_id in
+            <foreach collection="list" open="(" close=")" item="item" separator=",">
+                #{item}
+            </foreach>
+        </if>
+        group by t.group_id
+        order by d.department_id
+        <if test="start!=null and size!=null">
+            limit #{start},#{size}
+        </if>
+    </select>
+
 </mapper>

+ 4 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

@@ -551,6 +551,10 @@
             AND ((a.is_dept_audit = 0 and a.project_auditor_id = #{auditorId} and a.project_audit_state = 0)
             or (a.is_dept_audit = 1 and a.audit_dept_managerid = #{auditorId}))
         </if>
+        <if test="auditUserId != null and auditUserId !=''">
+            AND ((a.is_dept_audit = 0 and a.project_auditor_id = #{auditUserId} and a.project_audit_state = 0)
+            or (a.is_dept_audit = 1 and a.audit_dept_managerid = #{auditUserId}))
+        </if>
         <if test="isEngeering == 1">
             AND a.department_audit_state = 1
         </if>

文件差异内容过多而无法显示
+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TimeTypeMapper.xml


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

@@ -92,8 +92,8 @@ public class DepartmentController {
      * parentId 父级部门id
      */
     @RequestMapping("/add")
-    public HttpRespMsg insertDepartment(@RequestParam String name, Integer parentId, String managerId, String reportAuditUserid,String otherManagerIds, HttpServletRequest request) {
-        return departmentService.insertDepartment(name, parentId, managerId, reportAuditUserid,otherManagerIds, request);
+    public HttpRespMsg insertDepartment(@RequestParam String name, Integer parentId, String managerId, String reportAuditUserid,String otherManagerIds,String qualityManagerIds, HttpServletRequest request) {
+        return departmentService.insertDepartment(name, parentId, managerId, reportAuditUserid,otherManagerIds,qualityManagerIds, request);
     }
 
     /**
@@ -102,8 +102,8 @@ public class DepartmentController {
      * name 部门名称
      */
     @RequestMapping("/edit")
-    public HttpRespMsg updateDepartment(@RequestParam Integer id, @RequestParam String name, String managerId, String reportAuditUserid,String otherManagerIds, HttpServletRequest request) {
-        return departmentService.updateDepartment(id, name, managerId, reportAuditUserid,otherManagerIds, request);
+    public HttpRespMsg updateDepartment(@RequestParam Integer id, @RequestParam String name, String managerId, String reportAuditUserid,String otherManagerIds,String qualityManagerIds,  HttpServletRequest request) {
+        return departmentService.updateDepartment(id, name, managerId, reportAuditUserid,otherManagerIds,qualityManagerIds, request);
     }
 
     /**

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

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-01-18
+ */
+@RestController
+@RequestMapping("/department-quality-manager")
+public class DepartmentQualityManagerController {
+
+}
+

+ 7 - 2
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/PlanController.java

@@ -71,6 +71,11 @@ public class PlanController {
         return planService.allocationPlan(ids,planType);
     }
 
+    @RequestMapping("/allocationUser")
+    public HttpRespMsg allocationUser(Integer planId){
+        return planService.allocationUser(planId);
+    }
+
     //设置今明日计划部门
     @RequestMapping("/deptSet")
     @Transactional
@@ -94,8 +99,8 @@ public class PlanController {
     }
 
     @RequestMapping("/exportData")
-    public HttpRespMsg exportData(String date,Integer planType,String steelStampNumber){
-        return planService.exportData(date,planType,steelStampNumber);
+    public HttpRespMsg exportData(String startDate,String endDate,Integer planType,Integer productId,Integer deptId){
+        return planService.exportData(startDate,endDate,planType,productId,deptId);
     }
     /*计划下产品工序组员分配*/
     @RequestMapping("/teamAllocation")

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

@@ -1630,6 +1630,11 @@ public class ReportController {
         return reportService.getPlanDataWithUserId(userId,startDate,endDate);
     }
 
+    @RequestMapping("/exportPlanDataWithUserId")
+    public HttpRespMsg exportPlanDataWithUserId(String userId,String startDate,String endDate){
+        return reportService.exportPlanDataWithUserId(userId,startDate,endDate);
+    }
+
     @RequestMapping("/getUserCommentPlanResult")
     public HttpRespMsg getUserCommentPlanResult(String pptIds){
         return reportService.getUserCommentPlanResult(pptIds);

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

@@ -0,0 +1,48 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-01-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class DepartmentQualityManager extends Model<DepartmentQualityManager> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @TableField("department_id")
+    private Integer departmentId;
+
+    /**
+     * 质检人id
+     */
+    @TableField("quality_id")
+    private String qualityId;
+
+    @TableField("company_id")
+    private Integer companyId;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 3 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/Plan.java

@@ -259,6 +259,9 @@ public class Plan extends Model<Plan> {
     @TableField(exist = false)
     private List<PlanSteelStampNumber> steelStampNumberList;
 
+    @TableField(exist = false)
+    private Integer hasAllocation;
+
     @Override
     protected Serializable pkVal() {
         return this.id;

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

@@ -21,5 +21,6 @@ public class DepartmentVO {
     private List<DepartmentVO> children;
     private List<HashMap> userList;
     private List<String> otherManagerIds;
+    private List<String> qualityManagerIds;
     private Integer ddDeptid;
 }

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

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

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

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

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

@@ -18,9 +18,9 @@ import java.util.List;
  * @since 2020-02-11
  */
 public interface DepartmentService extends IService<Department> {
-    HttpRespMsg insertDepartment(String departmentName, Integer superiorId, String managerId, String reportAuditUserid,String otherManagerIds, HttpServletRequest request);
+    HttpRespMsg insertDepartment(String departmentName, Integer superiorId, String managerId, String reportAuditUserid,String otherManagerIds,String qualityManagerIds, HttpServletRequest request);
 
-    HttpRespMsg updateDepartment(Integer departmentId, String departmentName, String managerId, String reportAuditUserid,String otherManagerIds, HttpServletRequest request);
+    HttpRespMsg updateDepartment(Integer departmentId, String departmentName, String managerId, String reportAuditUserid,String otherManagerIds,String qualityManagerIds, HttpServletRequest request);
 
     HttpRespMsg deleteDepartment(Integer departmentId, HttpServletRequest request);
 

+ 3 - 1
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/PlanService.java

@@ -27,7 +27,7 @@ public interface PlanService extends IService<Plan> {
 
     HttpRespMsg importData(MultipartFile multipartFile, Integer planType);
 
-    HttpRespMsg exportData(String date, Integer planType,String steelStampNumber);
+    HttpRespMsg exportData(String startDate,String endDate,Integer planType,Integer productId,Integer deptId);
 
     HttpRespMsg deptSet(String deptIds);
 
@@ -56,4 +56,6 @@ public interface PlanService extends IService<Plan> {
     HttpRespMsg allPlanList(HttpServletRequest request);
 
     HttpRespMsg deletePlan(Integer id);
+
+    HttpRespMsg allocationUser(Integer planId);
 }

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

@@ -156,4 +156,6 @@ public interface ReportService extends IService<Report> {
     HttpRespMsg getPlanDataWithUserId(String userId, String startDate, String endDate);
 
     HttpRespMsg getUserCommentPlanResult(String pptIds);
+
+    HttpRespMsg exportPlanDataWithUserId(String userId, String startDate, String endDate);
 }

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.DepartmentQualityManager;
+import com.management.platform.mapper.DepartmentQualityManagerMapper;
+import com.management.platform.service.DepartmentQualityManagerService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-01-18
+ */
+@Service
+public class DepartmentQualityManagerServiceImpl extends ServiceImpl<DepartmentQualityManagerMapper, DepartmentQualityManager> implements DepartmentQualityManagerService {
+
+}

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

@@ -76,6 +76,8 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
     private UserWorkTypeMapper userWorkTypeMapper;
     @Resource
     private PlanService planService;
+    @Resource
+    private DepartmentQualityManagerMapper departmentQualityManagerMapper;
 
     @Value("${corpId}")
     private String corpId;
@@ -83,7 +85,7 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
     private String providerSecret;
     //新增部门
     @Override
-    public HttpRespMsg insertDepartment(String departmentName, Integer superiorId, String managerId, String reportAuditUserid,String otherManagerIds,  HttpServletRequest request) {
+    public HttpRespMsg insertDepartment(String departmentName, Integer superiorId, String managerId, String reportAuditUserid,String otherManagerIds,String qualityManagerIds,  HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
@@ -135,7 +137,7 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
 
     //更新部门
     @Override
-    public HttpRespMsg updateDepartment(Integer departmentId, String departmentName,String managerId, String reportAuditUserid,String otherManagerIds, HttpServletRequest request) {
+    public HttpRespMsg updateDepartment(Integer departmentId, String departmentName,String managerId, String reportAuditUserid,String otherManagerIds,String qualityManagerIds, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
@@ -246,6 +248,20 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                     }else{
                         departmentOtherManagerMapper.delete(new QueryWrapper<DepartmentOtherManager>().eq("department_id",departmentId));
                     }
+                    if(qualityManagerIds!=null&&!qualityManagerIds.equals("")){
+                        String[] split = qualityManagerIds.split(",");
+                        List<String> list = Arrays.asList(split);
+                        departmentQualityManagerMapper.delete(new QueryWrapper<DepartmentQualityManager>().eq("department_id",departmentId));
+                        for (String s : list) {
+                            DepartmentQualityManager departmentQualityManager=new DepartmentQualityManager();
+                            departmentQualityManager.setDepartmentId(department.getDepartmentId());
+                            departmentQualityManager.setQualityId(s);
+                            departmentQualityManager.setCompanyId(companyId);
+                            departmentQualityManagerMapper.insert(departmentQualityManager);
+                        }
+                    }else{
+                        departmentQualityManagerMapper.delete(new QueryWrapper<DepartmentQualityManager>().eq("department_id",departmentId));
+                    }
                 }
             }
         } catch (NullPointerException e) {
@@ -330,16 +346,16 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
         return departmentMapper.selectCount(new QueryWrapper<Department>().eq("superior_id", id)) > 0;
     }
 
-    private void fillSubDepartmentList(List<Department> allDepts, DepartmentVO parentDept, List<DepartmentOtherManager> otherManagerList) {
+    private void fillSubDepartmentList(List<Department> allDepts, DepartmentVO parentDept, List<DepartmentOtherManager> otherManagerList, List<DepartmentQualityManager> qualityManagerList) {
         Integer id = parentDept.getId();
         List<Department> collect = allDepts.stream().filter(all -> all.getSuperiorId() != null && all.getSuperiorId().intValue() == id).collect(Collectors.toList());
         List<DepartmentVO> subResult = new ArrayList<>();
         if (collect.size() > 0) {
             collect.forEach(c->{
-                DepartmentVO vo = formatDepartmentToVO(c, otherManagerList);
+                DepartmentVO vo = formatDepartmentToVO(c, otherManagerList,qualityManagerList);
                 subResult.add(vo);
                 //继续添加当前部门的子部门
-                fillSubDepartmentList(allDepts, vo, otherManagerList);
+                fillSubDepartmentList(allDepts, vo, otherManagerList,qualityManagerList);
             });
         }
         if (subResult.size() > 0) {
@@ -357,14 +373,15 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
             List<Department> departmentList = departmentMapper.selectList(new QueryWrapper<Department>()
                     .eq("company_id", companyId));
             List<DepartmentOtherManager> departmentOtherManagerList = departmentOtherManagerMapper.selectList(new QueryWrapper<DepartmentOtherManager>().eq("company_id", companyId));
+            List<DepartmentQualityManager> departmentQualityManagerList = departmentQualityManagerMapper.selectList(new QueryWrapper<DepartmentQualityManager>().eq("company_id", companyId));
             //结果列表
             List<DepartmentVO> list = new ArrayList<>();
             //获取全部的顶层部门
             List<Department> rootDepartments = departmentList.stream().filter(dept -> dept.getSuperiorId() == null).collect(Collectors.toList());
             rootDepartments.forEach(root->{
-                DepartmentVO rootDeptVO = formatDepartmentToVO(root, departmentOtherManagerList);
+                DepartmentVO rootDeptVO = formatDepartmentToVO(root, departmentOtherManagerList,departmentQualityManagerList);
                 list.add(rootDeptVO);
-                fillSubDepartmentList(departmentList, rootDeptVO, departmentOtherManagerList);
+                fillSubDepartmentList(departmentList, rootDeptVO, departmentOtherManagerList,departmentQualityManagerList);
             });
             //递归排序
             sortResultDeptList(list);
@@ -406,13 +423,14 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                 }
             }
             List<DepartmentOtherManager> departmentOtherManagerList = departmentOtherManagerMapper.selectList(new QueryWrapper<DepartmentOtherManager>().eq("company_id", user.getCompanyId()));
+            List<DepartmentQualityManager> departmentQualityManagerList = departmentQualityManagerMapper.selectList(new QueryWrapper<DepartmentQualityManager>().eq("company_id", user.getCompanyId()));
             //结果列表
             List<DepartmentVO> list = new ArrayList<>();
             List<Department> rootDepartments = departmentList.stream().filter(dept -> dept.getSuperiorId() == null).collect(Collectors.toList());
             rootDepartments.forEach(root->{
-                DepartmentVO rootDeptVO = formatDepartmentToVO(root, departmentOtherManagerList);
+                DepartmentVO rootDeptVO = formatDepartmentToVO(root, departmentOtherManagerList,departmentQualityManagerList);
                 list.add(rootDeptVO);
-                fillSubDepartmentList(departmentList, rootDeptVO, departmentOtherManagerList);
+                fillSubDepartmentList(departmentList, rootDeptVO, departmentOtherManagerList,departmentQualityManagerList);
             });
             //返回数据
             httpRespMsg.data = list;
@@ -425,9 +443,10 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
     }
 
     //将部门PO转化为部门VO
-    private DepartmentVO formatDepartmentToVO(Department department, List<DepartmentOtherManager> departmentOtherManagerList) {
+    private DepartmentVO formatDepartmentToVO(Department department, List<DepartmentOtherManager> departmentOtherManagerList, List<DepartmentQualityManager> departmentQualityManagerList) {
         //获取该部门的其他管理者
         List<String> collect = departmentOtherManagerList.stream().filter(dm -> dm.getDepartmentId().equals(department.getDepartmentId())).map(vo -> vo.getOtherManagerId()).collect(Collectors.toList());
+        List<String> collect1 = departmentQualityManagerList.stream().filter(dm -> dm.getDepartmentId().equals(department.getDepartmentId())).map(vo -> vo.getQualityId()).collect(Collectors.toList());
         //这俩东西并没有继承关系
         return new DepartmentVO()
                 .setId(department.getDepartmentId())
@@ -435,6 +454,7 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                 .setLabel(department.getDepartmentName())
                 .setParentId(department.getSuperiorId())
                 .setOtherManagerIds(collect)
+                .setQualityManagerIds(collect1)
                 .setReportAuditUserid(department.getReportAuditUserid())
                 .setDdDeptid(department.getDdDeptid())
                 .setSeq(department.getSeq());
@@ -960,13 +980,14 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                 List<Department> allDepartmentList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id",companyId));
                 List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).eq("is_active",1));
                 List<DepartmentOtherManager> departmentOtherManagerList = departmentOtherManagerMapper.selectList(new QueryWrapper<DepartmentOtherManager>().eq("company_id", companyId));
+                List<DepartmentQualityManager> departmentQualityManagerList = departmentQualityManagerMapper.selectList(new QueryWrapper<DepartmentQualityManager>().eq("company_id", companyId));
                 //结果列表
                 List<DepartmentVO> list = new ArrayList<>();
                 List<Department> rootDepartments = departmentList.stream().filter(dept -> dept.getSuperiorId() == null).collect(Collectors.toList());
                 rootDepartments.forEach(root->{
-                    DepartmentVO rootDeptVO = formatDepartmentToVO(root, departmentOtherManagerList);
+                    DepartmentVO rootDeptVO = formatDepartmentToVO(root, departmentOtherManagerList,departmentQualityManagerList);
                     list.add(rootDeptVO);
-                    fillSubDepartmentList(allDepartmentList, rootDeptVO, departmentOtherManagerList);
+                    fillSubDepartmentList(allDepartmentList, rootDeptVO, departmentOtherManagerList,departmentQualityManagerList);
                 });
                 //处理部门下人员列表
                 List<DepartmentVO> userListWithDept = getUserListWithDept(userList, list);

+ 146 - 57
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/PlanServiceImpl.java

@@ -115,7 +115,9 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
         NumberFormat format = NumberFormat.getPercentInstance();
         format.setMinimumFractionDigits(2);
         queryWrapper.eq(Plan::getCompanyId,companyId);
-        queryWrapper.ne(Plan::getStatus,2);
+        if(isMob!=null&&isMob==1){
+            queryWrapper.ne(Plan::getStatus,2);
+        }
         queryWrapper.eq(Plan::getIsDelete,0);
         if(planType!=2){
             queryWrapper.eq(Plan::getPlanType,0);
@@ -165,22 +167,23 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
             List<Integer> otherDeptIds = otherManagers.stream().map(DepartmentOtherManager::getDepartmentId).distinct().collect(Collectors.toList());
             deptIds.addAll(otherDeptIds);
             /*作为部门负责人看到的数据*/
-            if(departmentMapper.selectCount(new LambdaQueryWrapper<Department>().eq(Department::getManagerId,user.getId()))>0
-                    ||departmentOtherManagerService.count(new LambdaQueryWrapper<DepartmentOtherManager>().eq(DepartmentOtherManager::getOtherManagerId,user.getId()))>0){
-                queryWrapper.and(wrapper->wrapper.and(wr->wr.in(Plan::getStationId,deptIds).eq(Plan::getStatus,1)).or().eq(Plan::getCreateId,user.getId()));
-            }else {
-                /*作为组员可以查看的数据*/
-                List<ProdProcedureTeam> prodProcedureTeams = prodProcedureTeamService.list(new QueryWrapper<ProdProcedureTeam>().eq("company_id", companyId).eq("user_id", user.getId()));
-                List<Integer> collect=new ArrayList<>();
-                if(prodProcedureTeams!=null&&prodProcedureTeams.size()>0){
-                    List<Integer> ids = prodProcedureTeams.stream().map(ProdProcedureTeam::getPlanProcedureId).collect(Collectors.toList());
-                    List<PlanProcedureTotal> list = planProcedureTotalService.list(new QueryWrapper<PlanProcedureTotal>().in("id", ids));
-                    collect = list.stream().map(PlanProcedureTotal::getPlanId).distinct().collect(Collectors.toList());
-                }
-                collect.add(-1);
-                List<Integer> finalCollect = collect;
-                queryWrapper.and(wrapper->wrapper.in(Plan::getId, finalCollect).or().eq(Plan::getCreateId,user.getId())).eq(Plan::getStatus,1);
+//            if(departmentMapper.selectCount(new LambdaQueryWrapper<Department>().eq(Department::getManagerId,user.getId()))>0
+//                    ||departmentOtherManagerService.count(new LambdaQueryWrapper<DepartmentOtherManager>().eq(DepartmentOtherManager::getOtherManagerId,user.getId()))>0){
+////                queryWrapper.and(wrapper->wrapper.and(wr->wr.in(Plan::getStationId,deptIds).eq(Plan::getStatus,1)).or().eq(Plan::getCreateId,user.getId()));
+//                queryWrapper.and(wrapper->wrapper.and(wr->wr.in(Plan::getStationId,deptIds)).or().eq(Plan::getCreateId,user.getId()));
+//            }else {
+//
+//            }
+            List<ProdProcedureTeam> prodProcedureTeams = prodProcedureTeamService.list(new QueryWrapper<ProdProcedureTeam>().eq("company_id", companyId).eq("user_id", user.getId()));
+            List<Integer> collect=new ArrayList<>();
+            if(prodProcedureTeams!=null&&prodProcedureTeams.size()>0){
+                List<Integer> ids = prodProcedureTeams.stream().map(ProdProcedureTeam::getPlanProcedureId).collect(Collectors.toList());
+                List<PlanProcedureTotal> list = planProcedureTotalService.list(new QueryWrapper<PlanProcedureTotal>().in("id", ids));
+                collect = list.stream().map(PlanProcedureTotal::getPlanId).distinct().collect(Collectors.toList());
             }
+            collect.add(-1);
+            List<Integer> finalCollect = collect;
+            queryWrapper.and(wrapper->wrapper.in(Plan::getId, finalCollect).or().eq(Plan::getCreateId,user.getId()).or().in(Plan::getStationId,deptIds)).eq(Plan::getStatus,1);
         }
         if(!StringUtils.isEmpty(steelStampNumber)){
             QueryWrapper<PlanSteelStampNumber> queryWrapperSSN=new QueryWrapper<>();
@@ -220,6 +223,9 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
                 if(totals.size()>0){
                     double sum = totals.stream().filter(t->t.getTotalWages()!=null).mapToDouble(PlanProcedureTotal::getTotalWages).sum();
                     rs.setTotalMoney(sum);
+                    List<Integer> totalIds = totals.stream().map(PlanProcedureTotal::getId).collect(Collectors.toList());
+                    boolean b = procedureTeams.stream().anyMatch(p -> totalIds.contains(p.getPlanProcedureId()));
+                    rs.setHasAllocation(b?1:0);
                 }
                 if(planType==2){
                     totals.forEach(ps->{
@@ -275,7 +281,6 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
     @Override
     public HttpRespMsg addOrUpdatePlan(Plan plan) {
         User user = userMapper.selectById(request.getHeader("token"));
-        List<Plan> plans = planMapper.selectList(new LambdaQueryWrapper<Plan>().eq(Plan::getStationId, plan.getStationId()).eq(Plan::getProductId, plan.getProductId()).orderByDesc(Plan::getCreateTime));
         boolean isNew=true;
         Integer companyId = user.getCompanyId();
         HttpRespMsg msg=new HttpRespMsg();
@@ -287,6 +292,15 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
         }
         if(plan.getProductId()!=null){
             Product product = productMapper.selectById(plan.getProductId());
+            List<Plan> plans = planMapper.selectList(new LambdaQueryWrapper<Plan>().select(Plan::getNum).eq(Plan::getProductId,product.getId()));
+            double sum = plans.stream().mapToDouble(Plan::getNum).sum();
+            BigDecimal decimal = new BigDecimal(sum);
+            decimal=decimal.add(new BigDecimal(plan.getNum())).setScale(2,BigDecimal.ROUND_HALF_UP);
+            //需求暂时取消 todo:限制产品下计划中数量之和大于产品设置的订单数量
+//            if(decimal.doubleValue()>product.getOrderNumber()){
+//                msg.setError("创建失败,该产品下的排产计划总数量大于当前产品下的订单数量");
+//                return msg;
+//            }
             plan.setProductName(product.getName());
         }
         if(plan.getTaskTypeId()!=null){
@@ -294,6 +308,10 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
             plan.setTaskTypeName(taskType.getTaskTypeName());
         }
         List<ProdProcedure> procedureList = prodProcedureMapper.selectList(new QueryWrapper<ProdProcedure>().eq("company_id", companyId).eq("product_id",plan.getProductId()).orderByDesc("id"));
+        if(procedureList.size()<=0){
+            msg.setError("当前产品工序配置未完成,请先完成工序配置");
+            return msg;
+        }
         List<PlanProcedureTotal> planProcedureTotals=new ArrayList<>();
         List<PlanProcedureTotal> oldPlanProcedureTotals=new ArrayList<>();
         List<ProdProcedure> list;
@@ -427,31 +445,31 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
         }
         planProcedureTotalService.saveOrUpdateBatch(planProcedureTotals);
         //新增的时候 计划相同的产品 分配到相同的班组的时候 组员自动分配到上次分配到的人员上
-        if(isNew){
-            if(plans.size()>0){
-                Plan oldPlan = plans.get(0);
-                List<PlanProcedureTotal> oldTotalList = planProcedureTotalService.list(new LambdaQueryWrapper<PlanProcedureTotal>().eq(PlanProcedureTotal::getPlanId, oldPlan.getId()));
-                List<Integer> ids = oldTotalList.stream().map(PlanProcedureTotal::getId).distinct().collect(Collectors.toList());
-                ids.add(-1);
-                List<ProdProcedureTeam> procedureTeams = prodProcedureTeamService.list(new LambdaQueryWrapper<ProdProcedureTeam>().in(ProdProcedureTeam::getPlanProcedureId, ids));
-                for (PlanProcedureTotal planProcedureTotal : planProcedureTotals) {
-                    Optional<PlanProcedureTotal> first = oldTotalList.stream().filter(ot -> ot.getProdProcedureId().equals(planProcedureTotal.getProdProcedureId())).findFirst();
-                    if(!first.isPresent()){
-                        continue;
-                    }
-                    List<ProdProcedureTeam> teams = procedureTeams.stream().filter(ps -> ps.getPlanProcedureId().equals(first.get().getId())).collect(Collectors.toList());
-                    if(teams!=null&&teams.size()>0){
-                        String teamIds = teams.stream().map(ProdProcedureTeam::getUserId).distinct().collect(Collectors.joining(","));
-                        try {
-                            teamAllocation(planProcedureTotal,teamIds,plan.getPlanType());
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                        }
-                    }
-                }
-
-            }
-        }
+//        if(isNew){
+//            if(plans.size()>0){
+//                Plan oldPlan = plans.get(0);
+//                List<PlanProcedureTotal> oldTotalList = planProcedureTotalService.list(new LambdaQueryWrapper<PlanProcedureTotal>().eq(PlanProcedureTotal::getPlanId, oldPlan.getId()));
+//                List<Integer> ids = oldTotalList.stream().map(PlanProcedureTotal::getId).distinct().collect(Collectors.toList());
+//                ids.add(-1);
+//                List<ProdProcedureTeam> procedureTeams = prodProcedureTeamService.list(new LambdaQueryWrapper<ProdProcedureTeam>().in(ProdProcedureTeam::getPlanProcedureId, ids));
+//                for (PlanProcedureTotal planProcedureTotal : planProcedureTotals) {
+//                    Optional<PlanProcedureTotal> first = oldTotalList.stream().filter(ot -> ot.getProdProcedureId().equals(planProcedureTotal.getProdProcedureId())).findFirst();
+//                    if(!first.isPresent()){
+//                        continue;
+//                    }
+//                    List<ProdProcedureTeam> teams = procedureTeams.stream().filter(ps -> ps.getPlanProcedureId().equals(first.get().getId())).collect(Collectors.toList());
+//                    if(teams!=null&&teams.size()>0){
+//                        String teamIds = teams.stream().map(ProdProcedureTeam::getUserId).distinct().collect(Collectors.joining(","));
+//                        try {
+//                            teamAllocation(planProcedureTotal,teamIds,plan.getPlanType());
+//                        } catch (Exception e) {
+//                            e.printStackTrace();
+//                        }
+//                    }
+//                }
+//
+//            }
+//        }
         List<PlanProcedureTotal> totals = planProcedureTotals.stream().filter(ps -> ps.getPlanId().equals(plan.getId())).collect(Collectors.toList());
         if(totals.size()>0){
             double sum = totals.stream().filter(t->t.getTotalWages()!=null).mapToDouble(PlanProcedureTotal::getTotalWages).sum();
@@ -790,7 +808,12 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
             }
             planSteelStampNumberService.saveBatch(allPlanSteelStampNumberList);
             if(needInsertList.size()>0){
+                List<Integer> productIds = needInsertList.stream().map(Plan::getProductId).collect(Collectors.toList());
+                List<Product> products = productMapper.selectList(new LambdaQueryWrapper<Product>().in(Product::getId, productIds));
+                List<Plan> planList = planMapper.selectList(new LambdaQueryWrapper<Plan>().in(Plan::getProductId, productIds));
                 List<PlanProcedureTotal> planProcedureTotals=new ArrayList<>();
+                StringBuilder sb=new StringBuilder();
+                List<Plan> lastPlanList=new ArrayList<>();
                 for (Plan plan : needInsertList) {
                     if(plan.getPlanType()==0){
                         //处理工序  获取当前产品最新版本的工序的版本号
@@ -798,6 +821,26 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
                         if(procedureList!=null&&procedureList.size()>0){
                             String versionNumber = procedureList.get(0).getVersionNumber();
                             plan.setVersionNumber(versionNumber);
+                        }else {
+                            if(StringUtils.isEmpty(sb.toString())){
+                                sb.append(plan.getProductName());
+                            }else {
+                                sb.append(","+plan.getProductName());
+                            }
+                            continue;
+                        }
+                        Product product = products.stream().filter(p->p.getId().equals(plan.getProductId())).findFirst().get();
+                        List<Plan> plans = planList.stream().filter(p->p.getProductId().equals(plan.getProductId())).collect(Collectors.toList());
+                        List<Plan> importPlan = needInsertList.stream().filter(n -> n.getProductId().equals(plan.getProductId())).collect(Collectors.toList());
+                        plans.addAll(importPlan);
+                        //要减去当前这个计划的数量
+                        double allSum = plans.stream().mapToDouble(Plan::getNum).sum();
+                        BigDecimal decimal = new BigDecimal(allSum);
+                        decimal=decimal.subtract(new BigDecimal(plan.getNum()));
+                        decimal=decimal.add(new BigDecimal(plan.getNum())).setScale(2,BigDecimal.ROUND_HALF_UP);
+                        if(decimal.doubleValue()>product.getOrderNumber()){
+                            msg.setError("创建失败,该产品下的排产计划总数量大于当前产品下的订单数量");
+                            return msg;
                         }
                         List<ProdProcedure> list = procedureList.stream().filter(pl -> pl.getVersionNumber().equals(procedureList.get(0).getVersionNumber())).collect(Collectors.toList());
                         list=list.stream().sorted(Comparator.comparing(ProdProcedure::getId)).collect(Collectors.toList());
@@ -827,9 +870,13 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
                         p.setTotalWorkingHours(plan.getPlanWorkHour());
                         planProcedureTotals.add(p);
                     }
+                    lastPlanList.add(plan);
                 }
                 planProcedureTotalService.saveBatch(planProcedureTotals);
-                saveOrUpdateBatch(needInsertList);
+                if(lastPlanList.size()>0){
+                    saveOrUpdateBatch(lastPlanList);
+                };
+                msg.setData("导入成功,其中产品["+sb.toString()+"]产品工序未完成,请完成工序配置");
             }
         } catch (IOException e) {
             e.printStackTrace();
@@ -870,7 +917,7 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
     }
 
     @Override
-    public HttpRespMsg exportData(String date, Integer planType,String steelStampNumber) {
+    public HttpRespMsg exportData(String startDate,String endDate,Integer planType,Integer productId,Integer deptId) {
         HttpRespMsg msg=new HttpRespMsg();
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
         QueryWrapper<Plan> queryWrapper=new QueryWrapper();
@@ -881,27 +928,37 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
         }else {
             queryWrapper.eq("plan_type",1);
         }
-        if(!StringUtils.isEmpty(date)){
-            LocalDate parse = LocalDate.parse(date,df);
-            queryWrapper.eq("start_date",parse);
+        if(!StringUtils.isEmpty(startDate)&&!StringUtils.isEmpty(endDate)){
+            LocalDate parse1 = LocalDate.parse(startDate,df);
+            LocalDate parse2 = LocalDate.parse(endDate,df);
+            queryWrapper.between("start_date",parse1,parse2);
         }else {
             if(planType!=2){
                 LocalDate now = LocalDate.now();
                 queryWrapper.eq("start_date",planType==0?now:now.plusDays(1));
             }
         }
+        if(productId!=null){
+            queryWrapper.eq("product_id",productId);
+        }
+        if(deptId!=null){
+            List<Department> departmentList = departmentMapper.selectList(new LambdaQueryWrapper<Department>().eq(Department::getDepartmentId, deptId).or().eq(Department::getSuperiorId, deptId));
+            List<Integer> list = departmentList.stream().map(Department::getDepartmentId).distinct().collect(Collectors.toList());
+            list.add(-1);
+            queryWrapper.in("station_id",list);
+        }
+////        if(!StringUtils.isEmpty(steelStampNumber)){
+////            queryWrapper.gt("steel_stamp_number_start",steelStampNumber);
+////            queryWrapper.lt("steel_stamp_number_end",steelStampNumber);
+////        }
 //        if(!StringUtils.isEmpty(steelStampNumber)){
-//            queryWrapper.gt("steel_stamp_number_start",steelStampNumber);
-//            queryWrapper.lt("steel_stamp_number_end",steelStampNumber);
+//            QueryWrapper<PlanSteelStampNumber> queryWrapperSSN=new QueryWrapper<>();
+//            queryWrapperSSN.apply("'"+steelStampNumber+"'"+" between steel_stamp_number_start AND steel_stamp_number_end");
+//            List<PlanSteelStampNumber> list = planSteelStampNumberService.list(queryWrapperSSN);
+//            List<Integer> ids = list.stream().map(PlanSteelStampNumber::getPlanId).collect(Collectors.toList());
+//            ids.add(-1);
+//            queryWrapper.in("id",ids);
 //        }
-        if(!StringUtils.isEmpty(steelStampNumber)){
-            QueryWrapper<PlanSteelStampNumber> queryWrapperSSN=new QueryWrapper<>();
-            queryWrapperSSN.apply("'"+steelStampNumber+"'"+" between steel_stamp_number_start AND steel_stamp_number_end");
-            List<PlanSteelStampNumber> list = planSteelStampNumberService.list(queryWrapperSSN);
-            List<Integer> ids = list.stream().map(PlanSteelStampNumber::getPlanId).collect(Collectors.toList());
-            ids.add(-1);
-            queryWrapper.in("id",ids);
-        }
         List<Plan> planList = planMapper.selectList(queryWrapper);
         List<String> titleList=new ArrayList<>();
         if(planType!=2){
@@ -1387,4 +1444,36 @@ public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements Pl
         msg.setError("‘已有员工报工,删除失败");
         return msg;
     }
+
+    @Override
+    public HttpRespMsg allocationUser(Integer planId) {
+        HttpRespMsg msg=new HttpRespMsg();
+        Plan plan = planMapper.selectById(planId);
+        List<Plan> plans = planMapper.selectList(new LambdaQueryWrapper<Plan>().eq(Plan::getStationId, plan.getStationId()).ne(Plan::getId,plan.getId()).eq(Plan::getProductId, plan.getProductId()).orderByDesc(Plan::getCreateTime));
+        List<PlanProcedureTotal> planProcedureTotals = planProcedureTotalService.list(new LambdaQueryWrapper<PlanProcedureTotal>().eq(PlanProcedureTotal::getPlanId, plan.getId()));
+        if(plans.size()>0){
+            Plan oldPlan = plans.get(0);
+            List<PlanProcedureTotal> oldTotalList = planProcedureTotalService.list(new LambdaQueryWrapper<PlanProcedureTotal>().eq(PlanProcedureTotal::getPlanId, oldPlan.getId()));
+            List<Integer> ids = oldTotalList.stream().map(PlanProcedureTotal::getId).distinct().collect(Collectors.toList());
+            ids.add(-1);
+            List<ProdProcedureTeam> procedureTeams = prodProcedureTeamService.list(new LambdaQueryWrapper<ProdProcedureTeam>().in(ProdProcedureTeam::getPlanProcedureId, ids));
+            for (PlanProcedureTotal planProcedureTotal : planProcedureTotals) {
+                Optional<PlanProcedureTotal> first = oldTotalList.stream().filter(ot -> ot.getProdProcedureId().equals(planProcedureTotal.getProdProcedureId())).findFirst();
+                if(!first.isPresent()){
+                    continue;
+                }
+                List<ProdProcedureTeam> teams = procedureTeams.stream().filter(ps -> ps.getPlanProcedureId().equals(first.get().getId())).collect(Collectors.toList());
+                if(teams!=null&&teams.size()>0){
+                    String teamIds = teams.stream().map(ProdProcedureTeam::getUserId).distinct().collect(Collectors.joining(","));
+                    try {
+                        teamAllocation(planProcedureTotal,teamIds,plan.getPlanType());
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+
+        }
+        return msg;
+    }
 }

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

@@ -142,18 +142,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         if (report.getFinishNum() == null) {
             report.setFinishNum(0.0);
         }
-//        LocalDate today = LocalDate.now();
         LocalDate targetDate = report.getCreateDate();
-//        if (report.getId() == null) {
-//            report.setCreateDate(today);
-//            targetDate = today;
-//        } else {
-//            Report report1 = reportMapper.selectById(report.getId());
-//            targetDate = report1.getCreateDate();
-//            report.setCreateDate(report1.getCreateDate());
-//        }
         report.setCompanyId(companyId);
-
         Plan plan = planMapper.selectById(report.getPlanId());
         if (plan.getNum() == 0) {
             httpRespMsg.setError("该计划件数为0,无法报工");
@@ -270,6 +260,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         if (isAllFinish) {
             //该计划下的所有工序都已经完成了,那么该计划就是完成状态
             plan.setRealEndDate(LocalDate.now());
+            plan.setHideState(1);//完成的隐藏掉
             planMapper.updateById(plan);
         }
         return httpRespMsg;
@@ -4060,9 +4051,11 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         }
         IPage<User> userIPage = userMapper.selectPage(new Page<>(pageIndex, pageSize), queryWrapper);
         List<User> userList = userIPage.getRecords();
-        User totalUser=new User();
-        totalUser.setId("0");
-        userList.add(totalUser);
+        if(userList.size()>0){
+            User totalUser=new User();
+            totalUser.setId("0");
+            userList.add(totalUser);
+        }
         List<Map<String,Object>> totalList=new ArrayList<>();
         for (String date : dataStringList) {
             Map<String,Object> map=new HashMap<>();
@@ -4130,7 +4123,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     @Override
     public HttpRespMsg getPersonWorkHoursWagesDetail(String date, String userId,String startDate,String endDate,Integer checkStatus,Integer detailStatus) {
         User user = userMapper.selectById(request.getHeader("token"));
-        if(checkStatus!=null&&StringUtils.isEmpty(userId)){
+        if(checkStatus!=null&&checkStatus==0&&StringUtils.isEmpty(userId)){
             userId=user.getId();
         }
         List<Map<String,Object>> mapList=reportMapper.getPersonWorkHoursWagesDetail(date,userId,user.getCompanyId(),startDate,endDate,checkStatus,detailStatus);
@@ -4840,27 +4833,10 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         System.out.println("测试001==="+integrated);
                     }
                     integratedSteelNums.add(steelNum);
-                    List<ReportSteelNum> newReportSteelNums=new ArrayList<>();
-                    //作为完整的钢印号直接去掉
-                    for (int i = 0; i < reportSteelNums.size(); i++) {
-                        if(reportSteelNums.get(i).getSteelNum().equals(steelNum)){
-                            continue;
-                        }
-                        newReportSteelNums.add(reportSteelNums.get(i));
-                    }
-                    reportSteelNums=newReportSteelNums;
-                    List<String> newSteelNums=new ArrayList<>();
-                    for (int i = 0; i < steelNums.size(); i++) {
-                        if(steelNums.get(i).equals(steelNum)){
-                            continue;
-                        }
-                        newSteelNums.add(steelNums.get(i));
-                    }
-                    steelNums=newSteelNums;
                 }
             }
 
-            //以钢印号为基准,进行计算,剔除完整件数的钢印号 //这个在上面已经去过了
+            //以钢印号为基准,进行计算,剔除完整件数的钢印号
             List<String> noCompleteSteelNums = steelNums.stream().filter(s->!integratedSteelNums.contains(s)).collect(Collectors.toList());
 
             //列出每一道工序上的钢印号集合
@@ -5679,4 +5655,175 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         httpRespMsg.setData(sb.toString());
         return httpRespMsg;
     }
+
+    @Override
+    public HttpRespMsg exportPlanDataWithUserId(String userId, String startDate, String endDate) {
+        HttpRespMsg msg=new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        Company company = companyMapper.selectById(companyId);
+        DateTimeFormatter dtf=DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        DateTimeFormatter dtf1=DateTimeFormatter.ofPattern("yyyyMMdd");
+        List<LocalDate> dates = getDays(LocalDate.parse(startDate, dtf), LocalDate.parse(endDate, dtf));
+        List<String> dataStringList=new ArrayList<>();
+        for (LocalDate localDate : dates) {
+            dataStringList.add(localDate.format(dtf1));
+        }
+        HttpRespMsg respMsg = getPlanDataWithUserId(userId, startDate, endDate);
+        List<Map<String, Object>> msgData = (List<Map<String, Object>>) respMsg.getData();
+        //1.创建一个workbook,对应一个excel文件
+        SXSSFWorkbook workBook = new SXSSFWorkbook();
+        //2.在workbook中添加一个sheet,对应Excel中的sheet
+        SXSSFSheet sheet = workBook.createSheet("车间工位计划表");
+        //设置每一列的列宽
+        sheet.setColumnWidth(0,256*15);
+        sheet.setColumnWidth(1,256*15);
+        //3.设置样式以及字体样式
+        //设置首行冻结
+        sheet.createFreezePane(0, 1);
+        sheet.setDefaultColumnWidth(16);
+        //设置字体样式
+        Font headFont = workBook.createFont();
+        headFont.setBold(true);
+        headFont.setFontHeightInPoints((short) 10);
+        headFont.setFontName("黑体");
+
+        Font titleFont = workBook.createFont();
+        titleFont.setBold(true);
+        titleFont.setFontHeightInPoints((short) 10);
+        titleFont.setFontName("黑体");
+
+        Font font = workBook.createFont();
+        font.setFontHeightInPoints((short) 10);
+        font.setFontName("宋体");
+
+        //设置单元格样式
+        XSSFCellStyle  headStyle = (XSSFCellStyle) workBook.createCellStyle();
+        headStyle.setFont(headFont);
+        headStyle.setAlignment(HorizontalAlignment.CENTER);
+        headStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+        headStyle.setWrapText(true);
+        headStyle.setBorderBottom(BorderStyle.THIN); //下边框
+        headStyle.setBorderLeft(BorderStyle.THIN);//左边框
+        headStyle.setBorderTop(BorderStyle.THIN);//上边框
+        headStyle.setBorderRight(BorderStyle.THIN);//右边框
+
+        String color = "c0c0c0";    //此处得到的color为16进制的字符串
+        //转为RGB码
+        int r = Integer.parseInt((color.substring(0,2)),16);   //转为16进制
+        int g = Integer.parseInt((color.substring(2,4)),16);
+        int b = Integer.parseInt((color.substring(4,6)),16);
+
+        //设置自定义颜色
+        XSSFColor xssfColor = new XSSFColor();
+        byte[] colorRgb = { (short)9, (byte) r, (byte) g, (byte) b };
+        xssfColor.setRGB(colorRgb);
+
+        headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index);
+        headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 填充模式(和背景颜色成对使用)
+        /*headStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex());*/ //设置自带的颜色
+
+        CellStyle titleStyle = workBook.createCellStyle();
+        titleStyle.setFont(titleFont);
+        titleStyle.setAlignment(HorizontalAlignment.CENTER);
+        titleStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+        titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);  //填充单元格
+        titleStyle.setFillForegroundColor((short)9);    //填色
+        titleStyle.setWrapText(true);
+        titleStyle.setBorderBottom(BorderStyle.THIN); //下边框
+        titleStyle.setBorderLeft(BorderStyle.THIN);//左边框
+        titleStyle.setBorderTop(BorderStyle.THIN);//上边框
+        titleStyle.setBorderRight(BorderStyle.THIN);//右边框
+
+        CellStyle cellStyle = workBook.createCellStyle();
+        cellStyle.setFont(font);
+        cellStyle.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+        cellStyle.setWrapText(true);
+        cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
+        cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
+        cellStyle.setBorderTop(BorderStyle.THIN);//上边框
+        cellStyle.setBorderRight(BorderStyle.THIN);//右边框
+        //行号
+        int rowNum = 0;
+        //第一行
+        SXSSFRow row0 = sheet.createRow(rowNum++);
+        row0.setHeight((short)500);
+        List<String> row_first =new ArrayList<>();
+        row_first.add("产品名称");
+        for (String date : dataStringList) {
+            row_first.add(date);
+        }
+        for (int i = 0; i < row_first.size(); i++) {
+            SXSSFCell tempCell = row0.createCell(i);
+            tempCell.setCellValue(row_first.get(i));
+            tempCell.setCellStyle(headStyle);
+        }
+        List<String> list=new ArrayList<>();
+        Map<String, List<Map<String, Object>>> listMap = msgData.stream().collect(Collectors.groupingBy(d -> String.valueOf(d.get("productId"))));
+        List<String> productIdList = msgData.stream().map(m -> String.valueOf(m.get("productId"))).distinct().collect(Collectors.toList());
+        int startIndex=1;
+        for (int i = 0; i < productIdList.size(); i++) {
+            List<Map<String, Object>> mapList = listMap.get(productIdList.get(i));
+            //判断是否需要合并
+            if(mapList.size()>1){
+                sheet.addMergedRegion(new CellRangeAddress(startIndex,startIndex+mapList.size()-1,0,0));
+            }
+            startIndex+=mapList.size();
+            for (int j = 0; j < mapList.size(); j++) {
+                if(j==0){
+                    list.add(String.valueOf(mapList.get(j).get("productName")));
+                }else {
+                    list.add("");
+                }
+                List<Map<String, Object>> targetList = (List<Map<String, Object>>) mapList.get(j).get("dataList");
+                for (String date : dataStringList) {
+                    Optional<Map<String, Object>> first = targetList.stream().filter(l -> String.valueOf(l.get("createDate")).equals(date)).findFirst();
+                    if(first.isPresent()){
+                        list.add((first.get().get("procedureName")==null?"":first.get().get("procedureName")+"\n")+
+                                first.get().get("workingTime")+"分钟"+first.get().get("cost")+"元"+"\n"+
+                                first.get().get("finishNum")+"件");
+                    }else {
+                        list.add("");
+                    }
+                }
+            }
+        }
+        int k=0;
+        for(int i = 0;i<msgData.size();i++){
+            SXSSFRow tempRow = sheet.createRow(rowNum++);
+            tempRow.setHeight((short)500);
+            for(int j=0;j<dataStringList.size()+1;j++){
+                SXSSFCell tempCell = tempRow.createCell(j);
+                String cellValue = "";
+                tempCell.setCellStyle(cellStyle);
+                if(k>=list.size()){
+                    continue;
+                }
+                cellValue=list.get(k);
+                tempCell.setCellValue(cellValue);
+                k++;
+            }
+        }
+
+        //导出excel
+        String result="系统提示:Excel文件导出成功!";
+        String title= "车间工位计划表_"+company.getCompanyName()+System.currentTimeMillis();
+        String fileName= title+".xlsx";
+        try {
+            File dir = null;
+            dir = new File(path);
+            if (!dir.exists()) {
+                dir.mkdirs();
+            }
+            FileOutputStream os = new FileOutputStream(path+fileName);//保存到本地
+            workBook.write(os);
+            os.flush();
+            os.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg.data ="/upload/"+fileName;
+        return httpRespMsg;
+    }
 }

+ 18 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/DepartmentQualityManagerMapper.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.DepartmentQualityManagerMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.DepartmentQualityManager">
+        <id column="id" property="id" />
+        <result column="department_id" property="departmentId" />
+        <result column="quality_id" property="qualityId" />
+        <result column="company_id" property="companyId" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, department_id, quality_id, company_id
+    </sql>
+
+</mapper>

+ 16 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5/src/views/planView/component/planComponent.vue

@@ -48,6 +48,7 @@
                     {{ item.progress==null||item.progress==0 ? '中止计划' : ''}}
                   </span>
                   <van-button type="info" size="small" @click="toDistribution(item)">派工单</van-button>
+                  <van-button v-if="item.hasAllocation==0" type="info" size="small" @click="allocationUser(item)">下发</van-button>
                 </div>
               </div>
             </div>
@@ -157,6 +158,21 @@ export default {
             this.$toast.fail(res.msg);
           }
         }).catch(err => { this.$toast.clear(); })
+    },
+    allocationUser(item){
+      this.$axios.post(
+          "/plan/allocationUser",
+            {
+              planId:item.id,
+            },
+        ).then(res => {
+          if (res.code == "ok") {
+             this.$toast.success('下发成功');
+          } else {
+            this.$toast.clear();
+            this.$toast.fail(res.msg);
+          }
+        }).catch(err => { this.$toast.clear(); })
     }
   },
 };

+ 16 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5/src/views/workView/fillReport.vue

@@ -177,6 +177,20 @@ export default {
         }).catch(err => { this.$toast.clear(); });
     },
     onSubmit() {
+      //核验件数
+      if (this.reportForm.finishNum >0 && this.reportForm.finishNum < 1.0) {
+        //完成件数为小数时,如果勾选了钢印号需要二次确认
+        this.$dialog.confirm({
+                    title: '提醒',
+                    message: '检测到件数为小数同时勾选了钢印号,确认该钢印号已完成了吗?'
+                }).then(() => {
+                    this.submitData();
+                }).catch(() => {});
+        return
+      }
+      this.submitData();
+    },
+    submitData() {
       let postData = {
         userProcedureTeamId: this.reportForm.id,
         prodProcedureId: this.reportForm.prod_procedure_id,
@@ -217,6 +231,8 @@ export default {
     onCheckChange(names) {
       this.$forceUpdate();
       console.log(this.reportForm.checkedSteelNum);
+      //自动计算件数
+      this.reportForm.finishNum = this.reportForm.checkedSteelNum.length;
     },
     getMyPlanProcedureList() {
       const { id, reportBoolean, date } = this.$route.query;

+ 4 - 4
fhKeeper/formulahousekeeper/timesheet-workshop/src/views/Home.vue

@@ -990,7 +990,7 @@
                 }
             }
             .logo-width {
-                width: 200px;
+                width: 160px;
             }
             .logo-collapse-width {
                 width: 60px;
@@ -1036,8 +1036,8 @@
                 width: 60px;
             }
             .menu-expanded {
-                flex: 0 0 200px;
-                width: 200px;
+                flex: 0 0 160px;
+                width: 160px;
             }
             .content-container {
                 flex: 1;
@@ -1047,7 +1047,7 @@
                 // position: relative;
                 .breadcrumb-container {
                     .title {
-                        width: 200px;
+                        width: 160px;
                         float: left;
                         color: #475669;
                     }

+ 274 - 116
fhKeeper/formulahousekeeper/timesheet-workshop/src/views/plan/orderInsert.vue

@@ -20,7 +20,7 @@
           <el-link type="primary" :underline="false" @click="addPlan()">{{
             `新增${titleText}`
           }}</el-link>
-          <el-link type="primary" :underline="false" @click="importDataDialog=true">{{ "导入" }}</el-link>
+          <el-link type="primary" :underline="false" @click="importDataDialog = true">{{ "导入" }}</el-link>
           <el-link type="primary" :underline="false" @click="exportData()"
             :download="this.planType == 0 ? '今日计划' : this.planType == 1 ? '明日计划' : this.planType == 2 ? '插单计划' : '' + '.xlsx'">{{
               "导出"
@@ -28,41 +28,71 @@
         </div>
       </div>
     </div>
-    <div class="layout-container-center">
+    <div class="layout-container-center grand">
       <!-- tab 切换 -->
-      <div class="today-tab">
+      <!-- <div class="today-tab">
         <div v-for="(item, index) in hasSetDeptList" :key="index" :class="`${todayTabIndex === index ? 'on' : ''}`"
           @click="tabChange(item, index)">
           {{ item.departmentName }}
         </div>
+      </div> -->
+
+      <div class="left-laowang" style="flex: 0 0 180px; overflow: hidden;">
+        <div class="left-laowangText">
+          {{ currentDepartmentText }}
+        </div>
+        <div class="left-laowangTree">
+          <el-tree :data="departmentList" @node-click="treeChange" :props="defaultProps" :draggable="adjustPosition"
+            :allow-drop="allowDrop" :expand-on-click-node="false">
+            <span class="custom-tree-node" slot-scope="{ node }">
+              <span class="spanWitdh">
+                <span v-if="user.userNameNeedTranslate == '1'">
+                  <ww-open-data type='departmentName' :openid='node.label'></ww-open-data>
+                </span>
+                <span v-else>
+                  {{ node.label }}
+                </span>
+              </span>
+            </span>
+          </el-tree>
+        </div>
       </div>
 
+      <div class="line line-second">
+        <div>
+          -
+          -
+          -
+        </div>
+      </div>
       <!-- 各部分数据列表 -->
-      <el-table :data="tableData" :height="'0'" style="width: 100%; flex: 1" v-loading="tableDataLoading"
-        @selection-change="handleSelectionChange">
-        <el-table-column type="selection" width="55"> </el-table-column>
-        <el-table-column prop="taskChangeNoticeNum" label="通知号" width="180"></el-table-column>
-        <el-table-column prop="taskName" label="任务名称" width="180"></el-table-column>
-        <el-table-column prop="taskTypeName" label="任务类型" width="180"></el-table-column>
-        <el-table-column prop="planManNum" label="计划人数" width="180"> </el-table-column>
-        <el-table-column prop="num" label="数量" width="180"></el-table-column>
-        <el-table-column prop="planWorkHour" label="计划工时" width="180"></el-table-column>
-        <el-table-column prop="totalMoney" label="工钱" width="180"></el-table-column>
-        <el-table-column prop="foremanName" label="工长" width="180">
+      <div class="box-second-father conterTable" style="width: 200px; flex: 1 1 0%">
+        <el-table :data="tableData" :height="'0'" style="width: 100%;" v-loading="tableDataLoading"
+          @selection-change="handleSelectionChange">
+          <el-table-column type="selection" width="55"> </el-table-column>
+          <el-table-column prop="taskChangeNoticeNum" label="通知号" width="180"></el-table-column>
+          <el-table-column prop="taskName" label="任务名称" width="180"></el-table-column>
+          <el-table-column prop="taskTypeName" label="任务类型" width="180"></el-table-column>
+          <el-table-column prop="planManNum" label="计划人数" width="180"> </el-table-column>
+          <el-table-column prop="num" label="数量" width="180"></el-table-column>
+          <el-table-column prop="planWorkHour" label="计划工时" width="180"></el-table-column>
+          <el-table-column prop="totalMoney" label="工钱" width="180"></el-table-column>
+          <el-table-column prop="foremanName" label="工长" width="180">
             <template slot-scope="scope">
-            <div @click="getFormenDetail(scope.row)" class="colorText">
-              {{ scope.row.foremanName}}
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column prop="startDate" label="开工时间" width="180"></el-table-column>
-        <el-table-column prop="endDate" label="完工时间" width="180"></el-table-column>
-        <el-table-column label="操作" :fixed="'right'">
-          <template slot-scope="scope">
-            <div @click="editPlan(scope.row)" class="colorText">编辑</div>
-          </template>
-        </el-table-column>
-      </el-table>
+              <div @click="getFormenDetail(scope.row)" class="colorText">
+                {{ scope.row.foremanName }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="startDate" label="开工时间" width="180"></el-table-column>
+          <el-table-column prop="endDate" label="完工时间" width="180"></el-table-column>
+          <el-table-column label="操作" :fixed="'right'">
+            <template slot-scope="scope">
+              <div @click="editPlan(scope.row)" class="colorText">编辑</div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
     </div>
     <div class="layout-container-floor">
       <el-button type="primary" size="mini" @click="allocationPlan">下发计划</el-button>
@@ -96,13 +126,15 @@
           </el-form-item>
           <el-form-item label="计划工时" prop="planWorkHour">
             <div style="display: flex;">
-              <el-input v-model="todayPlanForm.planWorkHour" type="number" placeholder="请输入" style="flex: 1;" maxlength="5"></el-input>
+              <el-input v-model="todayPlanForm.planWorkHour" type="number" placeholder="请输入" style="flex: 1;"
+                maxlength="5"></el-input>
               <div style="margin-left: 10px;">分钟</div>
             </div>
           </el-form-item>
           <el-form-item label="单价" prop="moneyOfJob">
             <div style="display: flex;">
-              <el-input v-model="todayPlanForm.moneyOfJob" type="number" placeholder="请输入" style="flex: 1;" maxlength="5"></el-input>
+              <el-input v-model="todayPlanForm.moneyOfJob" type="number" placeholder="请输入" style="flex: 1;"
+                maxlength="5"></el-input>
               <div style="margin-left: 10px;">元/小时</div>
             </div>
           </el-form-item>
@@ -154,43 +186,43 @@
         <el-button type="primary" @click="deptSetDialog = false">确 定</el-button>
       </span>
     </el-dialog>
-    
+
     <!-- 任务类型管理 -->
     <el-dialog title="任务类型管理" :visible.sync="taskTypeDialog" width="800" :before-close="handleClose">
       <div>
         <el-table :data="taskTypeList" style="width: 100%; flex: 1" v-loading="tableDataLoading">
-        <el-table-column prop="taskName" label="序号" width="180">
-          <template slot-scope="scope">
-            <div>{{scope.$index+1}}</div>
-          </template>
-        </el-table-column>
-        <el-table-column prop="taskTypeName" label="类型名称" width="180"></el-table-column>
-        <el-table-column label="操作">
-          <template slot-scope="scope">
-            <span @click="taskTypeAddDialog=true ,editTaskType(scope.row)" class="colorText">编辑</span>
-            <span @click="deleteTaskType(scope.row)" class="colorText">删除</span>
-          </template>
-        </el-table-column>
-      </el-table>
+          <el-table-column prop="taskName" label="序号" width="180">
+            <template slot-scope="scope">
+              <div>{{ scope.$index + 1 }}</div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="taskTypeName" label="类型名称" width="180"></el-table-column>
+          <el-table-column label="操作">
+            <template slot-scope="scope">
+              <span @click="taskTypeAddDialog = true, editTaskType(scope.row)" class="colorText">编辑</span>
+              <span @click="deleteTaskType(scope.row)" class="colorText">删除</span>
+            </template>
+          </el-table-column>
+        </el-table>
       </div>
       <span slot="footer" class="dialog-footer">
         <el-button @click="
           (taskTypeDialog = false)
           ">取 消</el-button>
-        <el-button type="primary" @click="taskTypeAddDialog=true,editTaskType()">新增</el-button>
+        <el-button type="primary" @click="taskTypeAddDialog = true, editTaskType()">新增</el-button>
       </span>
     </el-dialog>
 
     <!-- 任务类型新增 -->
     <el-dialog title="新增任务类型" :visible.sync="taskTypeAddDialog" width="800" :before-close="handleClose">
-        <div>
-          <el-form ref="taskTypeForm" :rules="taskTypeFormrules" :model="taskTypeForm" label-width="120px">
+      <div>
+        <el-form ref="taskTypeForm" :rules="taskTypeFormrules" :model="taskTypeForm" label-width="120px">
           <el-form-item label="分类名称" style="width: 100%" prop="taskTypeName">
             <el-input v-model="taskTypeForm.taskTypeName" placeholder="请输入"></el-input>
           </el-form-item>
-          </el-form>
-        </div>
-        <span slot="footer" class="dialog-footer">
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
         <el-button @click="
           (taskTypeAddDialog = false)
           ">取 消</el-button>
@@ -201,13 +233,13 @@
     <!-- 工长弹框 -->
     <el-dialog title="工长信息" :visible.sync="foremanDetailDialog" width="30%" :before-close="handleClose">
       <div>
-        <span>姓名:{{this.foremanDetail.name}}</span>
+        <span>姓名:{{ this.foremanDetail.name }}</span>
       </div>
       <div>
-        <span>工种:{{this.foremanDetail.workType}}</span>
+        <span>工种:{{ this.foremanDetail.workType }}</span>
       </div>
       <div>
-        <span>工号:{{this.foremanDetail.jobNumber}}</span>
+        <span>工号:{{ this.foremanDetail.jobNumber }}</span>
       </div>
       <span slot="footer" class="dialog-footer">
         <el-button @click="foremanDetailDialog = false">关闭</el-button>
@@ -215,24 +247,28 @@
     </el-dialog>
 
     <!--导入计划 -->
-    <el-dialog :title="this.titleText+'导入'" :visible.sync="importDataDialog"  width="500px">
-        <p>1. 下载
-        <el-link type="primary" style="margin-left:5px;" :underline="false" :href="'./upload/'+'插单计划导入模板.xlsx'" :download="'插单计划导入模板.xlsx'">{{'插单计划导入模板.xlsx'}}</el-link>
-        </p>
-        <p style="display: flex;justify-content: center;">
-            <el-upload ref="upload"  action="#" :limit="1" :http-request="importData" :show-file-list="false">
-              <el-button type="primary" :underline="false" :loading="importingData">{{$t("other.startImporting")}}</el-button>
-            </el-upload>
-        </p>
+    <el-dialog :title="this.titleText + '导入'" :visible.sync="importDataDialog" width="500px">
+      <p>1. 下载
+        <el-link type="primary" style="margin-left:5px;" :underline="false" :href="'./upload/' + '插单计划导入模板.xlsx'"
+          :download="'插单计划导入模板.xlsx'">{{ '插单计划导入模板.xlsx' }}</el-link>
+      </p>
+      <p style="display: flex;justify-content: center;">
+        <el-upload ref="upload" action="#" :limit="1" :http-request="importData" :show-file-list="false">
+          <el-button type="primary" :underline="false" :loading="importingData">{{ $t("other.startImporting")
+          }}</el-button>
+        </el-upload>
+      </p>
     </el-dialog>
   </div>
 </template>
   
 <script>
 import delete$ from 'dingtalk-jsapi/api/biz/cspace/delete';
+import dragMixin from "@/common/js/tensile.js";
 export default {
   name: "planComponent",
   components: {},
+  mixins: [dragMixin],
   props: {
     planType: {
       type: String,
@@ -255,9 +291,9 @@ export default {
       props: { multiple: true },
       hasSetDeptList: [],
       titleName: "",
-      taskTypeDialog:false,
-      importDataDialog:false,
-      importingData:false,
+      taskTypeDialog: false,
+      importDataDialog: false,
+      importingData: false,
       todayPlanForm: {
         id: null,
         taskChangeNoticeNum: "",
@@ -274,21 +310,21 @@ export default {
         endDate: "",
         describtion: "",
         versionNumber: "",
-        checkType:0,
+        checkType: 0,
       },
-       taskTypeForm: {
+      taskTypeForm: {
         id: null,
         companyId: "",
         taskTypeName: "",
       },
       user: JSON.parse(sessionStorage.getItem("user")),
-      foremanDetailDialog:false,
-      foremanDetail:{},
-      taskTypeList:[],
-      checkTypeList:[
-        {id:0,name:"自检"},{id:1,name:"互检"},{id:2,name:"专检"}
+      foremanDetailDialog: false,
+      foremanDetail: {},
+      taskTypeList: [],
+      checkTypeList: [
+        { id: 0, name: "自检" }, { id: 1, name: "互检" }, { id: 2, name: "专检" }
       ],
-      taskTypeAddDialog:false,
+      taskTypeAddDialog: false,
       todayTabIndex: 0,
       tableDataLoading: false,
       tableData: [],
@@ -323,15 +359,15 @@ export default {
           { required: true, message: "分类名称", trigger: "blur" },
         ],
       },
+      currentDepartmentText: ''
     };
   },
   computed: {},
   watch: {},
-  created() { },
   mounted() {
     this.getDepartmentList(),
       this.getPlanDeptSet(),
-      this.getHasSetPlanDeptList(),
+      // this.getHasSetPlanDeptList(),
       this.getProductList(),
       this.getTaskTypeList();
   },
@@ -354,17 +390,17 @@ export default {
         endDate: "",
         describtion: "",
         versionNumber: "",
-        checkType:0,
+        checkType: 0,
       }
     },
-    getFormenDetail(item){
-      this.foremanDetailDialog=true;
+    getFormenDetail(item) {
+      this.foremanDetailDialog = true;
       this.http.post(
         "/user/getUserInfo",
-        {userId:item.foremanId},
+        { userId: item.foremanId },
         (res) => {
           if (res.code == "ok") {
-            this.foremanDetail=res.data
+            this.foremanDetail = res.data
           } else {
             this.$message({
               message: res.msg,
@@ -395,6 +431,11 @@ export default {
           if (res.code == "ok") {
             let dptlist = JSON.parse(JSON.stringify(res.data));
             this.departmentList = this.changeArr(dptlist);
+            if(this.departmentList[0]) {
+              const { value, label } = this.departmentList[0]
+              this.currentDepartmentText = label
+              this.getTableData(value)
+            }
           } else {
             this.$message({
               message: res.msg,
@@ -410,6 +451,11 @@ export default {
         }
       );
     },
+    treeChange(item) {
+      const { value, label } = item
+      this.currentDepartmentText = label
+      this.getTableData(value)
+    },
     changeArr(arr) {
       for (var i = 0; i < arr.length; i++) {
         if (arr[i].id != -1 && arr[i].id != 0) {
@@ -589,7 +635,7 @@ export default {
           let stationId =
             this.todayPlanForm.stationId[
             this.todayPlanForm.stationId.length - 1
-            ];  
+            ];
           this.$delete(this.todayPlanForm, 'product')
           this.$delete(this.todayPlanForm, 'planProcedureTotals')
           this.http.post(
@@ -752,7 +798,7 @@ export default {
           if (res.code == "ok") {
             var filePath = res.data;
             const a = document.createElement('a'); // 创建a标签
-            a.setAttribute('download',(this.planType == 0 ? '今日计划' : this.planType == 1 ? '明日计划' : this.planType == 2 ? '插单计划' : '' )+ '.xlsx');// download属性
+            a.setAttribute('download', (this.planType == 0 ? '今日计划' : this.planType == 1 ? '明日计划' : this.planType == 2 ? '插单计划' : '') + '.xlsx');// download属性
             a.setAttribute('href', filePath);// href链接
             a.click(); //自执行点击事件
             a.remove();
@@ -801,13 +847,13 @@ export default {
         }
       );
     },
-    getTaskTypeList(){
-        this.http.post(
+    getTaskTypeList() {
+      this.http.post(
         "/task-type/list",
         {},
         (res) => {
           if (res.code == "ok") {
-            this.taskTypeList=res.data
+            this.taskTypeList = res.data
           } else {
             this.$message({
               message: res.msg,
@@ -823,7 +869,7 @@ export default {
         }
       );
     },
-    addTaskType(formName){
+    addTaskType(formName) {
       console.log(this.taskTypeForm);
       this.$refs[formName].validate((valid) => {
         if (valid) {
@@ -841,7 +887,7 @@ export default {
                     this.taskTypeForm.id == null ? "新增成功" : "修改成功",
                   type: "success",
                 });
-                this.taskTypeForm=[];
+                this.taskTypeForm = [];
                 this.taskTypeAddDialog = false;
               } else {
                 this.$message({
@@ -863,47 +909,85 @@ export default {
         }
       });
     },
-    deleteTaskType(item){
-      let param = {id: item.id};
-      this.$confirm('是否确认删除该分类',this.$t('other.prompts'), {
-          confirmButtonText: this.$t('btn.determine'),
-          cancelButtonText: this.$t('btn.cancel'),
-          type: "warning"
+    deleteTaskType(item) {
+      let param = { id: item.id };
+      this.$confirm('是否确认删除该分类', this.$t('other.prompts'), {
+        confirmButtonText: this.$t('btn.determine'),
+        cancelButtonText: this.$t('btn.cancel'),
+        type: "warning"
       })
-      .then(() => {
-          this.http.post('/task-type/delete',param,
-          res => {
+        .then(() => {
+          this.http.post('/task-type/delete', param,
+            res => {
               if (res.code == "ok") {
                 this.getTaskTypeList();
-                  this.$message({
-                      message: this.$t('message.successfullyDeleted'),
-                      type: "success"
-                  });
+                this.$message({
+                  message: this.$t('message.successfullyDeleted'),
+                  type: "success"
+                });
               } else {
-                  this.$message({
-                      message: res.msg,
-                      type: "error"
-                  });
+                this.$message({
+                  message: res.msg,
+                  type: "error"
+                });
               }
-          },
-          error => {
+            },
+            error => {
               this.$message({
-                  message: error,
-                  type: "error"
+                message: error,
+                type: "error"
               });
-              }
+            }
           );
-      })
-      .catch(() => {});
+        })
+        .catch(() => { });
     },
-    editTaskType(row){
+    editTaskType(row) {
       if (row == null) {
-          this.taskTypeForm = {}
+        this.taskTypeForm = {}
       } else {
-          this.taskTypeForm = row;
+        this.taskTypeForm = row;
       }
     },
   },
+  created() {
+    this.initDrag([
+      {
+        type: "LR",
+        domClass: {
+          // 中间分割线的名字
+          resize: "line-line",
+          // 左侧盒子的名字
+          left: "box-left",
+          // 右侧盒子的名字
+          right: "box-right",
+          // 父级的名字
+          box: "box-father",
+        },
+        otherInfo: {
+          // 限制左边栏最低宽度
+          leftWidth: 120,
+        },
+      },
+      {
+        type: "LR",
+        domClass: {
+          // 中间分割线的名字
+          resize: "line-second",
+          // 左侧盒子的名字
+          left: "left-laowang",
+          // 右侧盒子的名字
+          right: "box-second-father",
+          // 父级的名字
+          box: "grand",
+        },
+        otherInfo: {
+          // 限制左边栏最低宽度
+          leftWidth: 120,
+        },
+      },
+    ]);
+  },
 };
 </script>
 <style scoped lang='scss'>
@@ -919,19 +1003,46 @@ export default {
   // flex-wrap: wrap;
   flex-direction: column;
   box-sizing: border-box;
-  padding: 10px;
+  // padding: 10px;
 
   .layout-container-header,
   .layout-container-center,
   .layout-container-floor {
     width: 100%;
+    box-sizing: border-box;
+  }
+
+  .layout-container-header {
+    padding: 10px 10px 0 10px;
+    background: #F2F2F2;
   }
 
   .layout-container-center {
+    width: 100%;
     flex: 1;
     display: flex;
-    flex-direction: column;
-    overflow: auto;
+    flex-direction: row;
+
+    .conterTable {
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+    }
+
+    .line {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      background: #f2f2f2;
+      cursor: w-resize;
+      width: 10px;
+
+      div {
+        line-height: 5px;
+        text-align: center;
+        color: rgb(151, 151, 151);
+      }
+    }
   }
 
   .layout-container-floor {
@@ -1045,6 +1156,53 @@ export default {
       }
     }
   }
+
+  .left-laowang {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+    border-bottom: 1px solid #EBEEF5;
+
+    .left-laowangTree {
+      flex: 1;
+      overflow-y: auto;
+    }
+
+    .left-laowangText {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      height: 48px;
+      border-bottom: 1px solid #EBEEF5;
+      color: #02A7F0;
+      box-sizing: border-box;
+      width: 100%;
+      padding: 0 10px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+  }
+
+  .custom-tree-node {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-size: 14px;
+    padding-right: 8px;
+    position: relative;
+    box-sizing: border-box;
+    width: 10%;
+
+    .spanWitdh {
+      box-sizing: border-box;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      line-height: 36px;
+      display: inline-block;
+    }
+  }
 }
 </style>
   

+ 272 - 59
fhKeeper/formulahousekeeper/timesheet-workshop/src/views/plan/planComponent.vue

@@ -26,16 +26,13 @@
             `新增${titleText}`
           }}</el-link>
           <el-link type="primary" :underline="false" @click="importDataDialog = true">{{ "导入" }}</el-link>
-          <el-link type="primary" :underline="false" @click="exportData()"
-            :download="this.planType == 0 ? '今日计划' : this.planType == 1 ? '明日计划' : this.planType == 2 ? '插单计划' : '' + '.xlsx'">{{
-              "导出"
-            }}</el-link>
+          <el-link type="primary" :underline="false" @click="exportDialog = true">{{ "导出" }}</el-link>
         </div>
       </div>
     </div>
-    <div class="layout-container-center">
+    <div class="layout-container-center grand">
       <!-- tab 切换 -->
-      <div class="today-tab-btn">
+      <!-- <div class="today-tab-btn">
         <div class="today-tab">
           <div v-for="(item, index) in hasSetDeptList" :key="index" :class="`${todayTabIndex === index ? 'on' : ''}`"
             @click="tabChange(item, index)">
@@ -45,49 +42,81 @@
         <div style="margin-left: 15px;" v-if="planType == 0">
           <el-button type="primary" size="mini" @click="(deptSetDialog = true), getPlanDeptSet()">部门设置</el-button>
         </div>
+      </div> -->
+      <div class="left-laowang" style="flex: 0 0 180px; overflow: hidden;">
+        <div class="left-laowangText">
+          {{ currentDepartmentText }}
+        </div>
+        <div class="left-laowangTree">
+          <el-tree :data="departmentList" @node-click="treeChange" :props="defaultProps" :draggable="adjustPosition" :allow-drop="allowDrop"
+            :expand-on-click-node="false">
+            <span class="custom-tree-node" slot-scope="{ node }">
+              <span class="spanWitdh">
+                <span v-if="user.userNameNeedTranslate == '1'">
+                  <ww-open-data type='departmentName' :openid='node.label'></ww-open-data>
+                </span>
+                <span v-else>
+                  {{ node.label }}
+                </span>
+              </span>
+            </span>
+          </el-tree>
+        </div>
       </div>
 
+      <div class="line line-second">
+        <div>
+          -
+          -
+          -
+        </div>
+      </div>
 
       <!-- 各部分数据列表 -->
-      <el-table :data="tableData" style="width: 100%;" height="0" v-loading="tableDataLoading"
-        @selection-change="handleSelectionChange">
-        <el-table-column type="selection" width="55"> </el-table-column>
-        <el-table-column prop="productSchedulingNum" label="排产工单号" width="180">
-          <template slot-scope="scope">
-            <div @click="toPlanDetil(scope.row)" class="colorText">
-              {{ scope.row.productSchedulingNum }}
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column prop="productName" label="产品名称" width="180">
-        </el-table-column>
-        <el-table-column prop="projectCode" label="项目代码" width="180">
-        </el-table-column>
-        <el-table-column prop="num" label="数量" width="180"> </el-table-column>
-        <el-table-column prop="mainProcess" label="主工序" width="180">
-        </el-table-column>
-        <el-table-column prop="stationName" label="工位名称" width="180">
-        </el-table-column>
-        <el-table-column prop="foremanName" label="工长" width="180">
-          <template slot-scope="scope">
-            <div @click="getFormenDetail(scope.row)" class="colorText">
-              {{ scope.row.foremanName }}
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column prop="startDate" label="开工时间" width="180">
-        </el-table-column>
-        <el-table-column prop="endDate" label="完工时间" width="180">
-        </el-table-column>
-        <el-table-column label="操作" :fixed="'right'">
-          <template slot-scope="scope">
-            <div @click="editPlan(scope.row)" class="colorText">编辑</div>
-            <div @click="deletePlan(scope.row.id)" class="colorText">删除</div>
-            <div v-if="jisuanDate(scope.row.startDate) > 30" @click="hidePlan(scope.row.id, scope.row.hideState)"
-              class="colorText">{{ scope.row.hideState == 0 ? '隐藏' : '取消隐藏' }}</div>
-          </template>
-        </el-table-column>
-      </el-table>
+      <div class="box-second-father conterTable" style="width: 200px; flex: 1 1 0%">
+        <el-table :data="tableData" border height="0" v-loading="tableDataLoading"
+          @selection-change="handleSelectionChange">
+          <el-table-column type="selection" width="55"> </el-table-column>
+          <el-table-column prop="productSchedulingNum" label="排产工单号" width="180">
+            <template slot-scope="scope">
+              <div @click="toPlanDetil(scope.row)" class="colorText">
+                {{ scope.row.productSchedulingNum }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="productName" label="产品名称" width="180">
+          </el-table-column>
+          <el-table-column prop="projectCode" label="项目代码" width="180">
+          </el-table-column>
+          <el-table-column prop="num" label="数量" width="100"> </el-table-column>
+          <el-table-column prop="mainProcess" label="主工序" width="180">
+          </el-table-column>
+          <el-table-column prop="stationName" label="工位名称" width="180">
+          </el-table-column>
+          <el-table-column prop="foremanName" label="工长" width="140">
+            <template slot-scope="scope">
+              <div @click="getFormenDetail(scope.row)" class="colorText">
+                {{ scope.row.foremanName }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="startDate" label="开工时间" width="140">
+          </el-table-column>
+          <el-table-column prop="endDate" label="完工时间" width="140">
+          </el-table-column>
+          <el-table-column label="操作" :fixed="'right'" width="140">
+            <template slot-scope="scope">
+              <div class="controls_btn">
+                <div @click="editPlan(scope.row)" class="colorText">编辑</div>
+                <div @click="deletePlan(scope.row.id)" class="colorText">删除</div>
+                <div v-if="jisuanDate(scope.row.startDate) > 30" @click="hidePlan(scope.row.id, scope.row.hideState)"
+                  class="colorText">{{ scope.row.hideState == 0 ? '隐藏' : '取消隐藏' }}</div>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
     </div>
     <div class="layout-container-floor">
       <el-button type="primary" size="mini" @click="allocationPlan">下发计划</el-button>
@@ -104,14 +133,14 @@
           <el-form-item label="排产工单号" style="width: 100%" prop="productSchedulingNum">
             <el-input v-model="todayPlanForm.productSchedulingNum" maxlength="50"></el-input>
           </el-form-item>
-          <el-form-item label="产品名称" style="width: 100%" prop="productId">
+          <el-form-item label="项目代码" style="width: 100%" prop="productId">
             <el-select v-model="todayPlanForm.productId" placeholder="请选择" class="w100" @change="setProductCode">
-              <el-option v-for="item in productList" :key="item.id" :label="item.name" :value="item.id">
+              <el-option v-for="item in productList" :key="item.id" :label="item.code" :value="item.id">
               </el-option>
             </el-select>
           </el-form-item>
-          <el-form-item label="项目代码" style="width: 100%" prop="projectCode">
-            <el-input v-model="todayPlanForm.projectCode" maxlength="50" readonly></el-input>
+          <el-form-item label="产品名称" style="width: 100%" prop="productName">
+            <el-input v-model="todayPlanForm.productName" maxlength="50" readonly></el-input>
           </el-form-item>
 
           <div v-for="(item, index) in todayPlanForm.steelStampNumberList" style="width: 100%;margin-bottom: 10px;">
@@ -243,13 +272,44 @@
         </el-upload>
       </p>
     </el-dialog>
+
+    <!--导出计划 -->
+    <el-dialog :title="this.titleText + '导出'" :visible.sync="exportDialog" width="500px">
+      <el-form ref="form3" :model="exportParam">
+        <el-form-item prop="rangeDatas" :label="$t('time.dateRange')">
+          <el-date-picker v-model="exportParam.rangeDatas" :editable="false" format="yyyy-MM-dd" value-format="yyyy-MM-dd"
+            :clearable="true" :range-separator="$t('other.to')" type="daterange" :start-placeholder="$t('time.startDate')"
+            :end-placeholder="$t('time.endDate')"></el-date-picker>
+        </el-form-item>
+        <el-form-item prop="departmentId" :label="'选择部门'">
+          <el-cascader v-model="departmentIdArray" :options="departmentList" :placeholder="'全部部门'"
+            :props="{ checkStrictly: true, expandTrigger: 'hover' }" collapse-tags :show-all-levels="false" clearable
+            size="small" style="margin-bottom: 10px;width:180px"></el-cascader>
+        </el-form-item>
+        <el-form-item prop="departmentId" :label="'选择产品'">
+          <!-- 产品筛选 -->
+          <el-select v-model="exportParam.productId" :placeholder="'全部产品'" clearable filterable size="small"
+            style="width:180px">
+            <el-option v-for="(item, index) in productList" :key="index" :label="item.name" :value="item.id"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="exportData" style="width:100%;" :loading="listLoading">{{ $t('export.export')
+        }}</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
   
 <script>
+import dragMixin from "@/common/js/tensile.js";
+import util from "@/common/js/util";
+
 export default {
   name: "planComponent",
   components: {},
+  mixins: [dragMixin],
   props: {
     planType: {
       type: String,
@@ -350,16 +410,17 @@ export default {
         startDate: [{ required: true, message: "开工时间", trigger: "blur" }],
         // endDate: [{ required: true, message: "完工时间", trigger: "blur" }],
       },
+      exportDialog: false,
+      exportParam: { productId: null, rangeDatas: this.getCurrentRangeTime() },
     };
   },
   computed: {},
   watch: {},
-  created() { },
   mounted() {
     console.log(this.planType, '费雷')
     this.getDepartmentList(),
       this.getPlanDeptSet(),
-      this.getHasSetPlanDeptList(),
+      // this.getHasSetPlanDeptList(),
       this.getProductList();
   },
   methods: {
@@ -411,6 +472,7 @@ export default {
       let arrList = this.productList.filter(item => item.id == this.todayPlanForm.productId)
       console.log('====>', arrList)
       this.todayPlanForm.projectCode = arrList[0].code
+      this.todayPlanForm.productName = arrList[0].name
     },
     today() {
       let date = new Date();
@@ -427,6 +489,11 @@ export default {
           if (res.code == "ok") {
             let dptlist = JSON.parse(JSON.stringify(res.data));
             this.departmentList = this.changeArr(dptlist);
+            if(this.departmentList[0]) {
+              const { value, label } = this.departmentList[0]
+              this.currentDepartmentText = label
+              this.getTableData(value)
+            }
           } else {
             this.$message({
               message: res.msg,
@@ -442,6 +509,11 @@ export default {
         }
       );
     },
+    treeChange(item) {
+      const { value, label } = item
+      this.currentDepartmentText = label
+      this.getTableData(value)
+    },
     changeArr(arr) {
       for (var i = 0; i < arr.length; i++) {
         if (arr[i].id != -1 && arr[i].id != 0) {
@@ -459,6 +531,17 @@ export default {
       }
       return arr;
     },
+    // 日期
+    getCurrentRangeTime() {
+      var _this = this;
+      let yy = new Date().getFullYear();
+      let mm = new Date().getMonth() + 1;
+      let dd = new Date().getDate();
+      let time1 = yy + '-' + (mm < 10 ? '0' + mm : mm) + '-' + '01'
+      let time2 = yy + '-' + (mm < 10 ? '0' + mm : mm) + '-' + (dd < 10 ? '0' + dd : dd)
+      _this.gettime = [time1, time2];
+      return _this.gettime
+    },
     deptSet() {
       console.log(
         this.departmentIdArray,
@@ -673,6 +756,7 @@ export default {
             steelStampNumberEnd: ''
           }
         ],
+        currentDepartmentText: ''
       }
     },
     addPlanData(formName) {
@@ -759,6 +843,10 @@ export default {
               steelStampNumber: JSON.stringify(steelStampNumberListArr)
             },
             (res) => {
+              this.todayPlanForm = {
+                ...this.todayPlanForm,
+                steelStampNumberList: steelStampNumberListArr
+              }
               if (res.code == "ok") {
                 this.$message({
                   message:
@@ -915,8 +1003,10 @@ export default {
     exportData() {
       let param = {
         planType: this.planType,
-        date: this.planDate,
-        steelStampNumber: this.steelStampNumber,
+        startDate: this.exportParam.rangeDatas[0],
+        endDate: this.exportParam.rangeDatas[1],
+        productId: this.exportParam.productId,
+        deptId: this.departmentIdArray[this.departmentIdArray.length - 1]
       }
       this.http.post('/plan/exportData', param,
         res => {
@@ -1018,7 +1108,7 @@ export default {
     },
     //删除计划
     deletePlan(id) {
-      this.$alert('该计划将被删除','是否删除该计划', {
+      this.$alert('该计划将被删除', '是否删除该计划', {
         confirmButtonText: '确定',
         callback: action => {
           this.http.post(
@@ -1051,6 +1141,44 @@ export default {
       });
     },
   },
+  created() {
+    this.initDrag([
+      {
+        type: "LR",
+        domClass: {
+          // 中间分割线的名字
+          resize: "line-line",
+          // 左侧盒子的名字
+          left: "box-left",
+          // 右侧盒子的名字
+          right: "box-right",
+          // 父级的名字
+          box: "box-father",
+        },
+        otherInfo: {
+          // 限制左边栏最低宽度
+          leftWidth: 120,
+        },
+      },
+      {
+        type: "LR",
+        domClass: {
+          // 中间分割线的名字
+          resize: "line-second",
+          // 左侧盒子的名字
+          left: "left-laowang",
+          // 右侧盒子的名字
+          right: "box-second-father",
+          // 父级的名字
+          box: "grand",
+        },
+        otherInfo: {
+          // 限制左边栏最低宽度
+          leftWidth: 120,
+        },
+      },
+    ]);
+  },
 };
 </script>
 <style scoped lang='scss'>
@@ -1073,19 +1201,58 @@ export default {
   // flex-wrap: wrap;
   flex-direction: column;
   box-sizing: border-box;
-  padding: 10px;
 
   .layout-container-header,
   .layout-container-center,
   .layout-container-floor {
     width: 100%;
+    box-sizing: border-box;
+  }
+
+  .controls_btn {
+    display: flex;
+
+    div {
+      margin-right: 10px;
+
+      &:last-child {
+        margin-right: 0;
+      }
+    }
+  }
+
+  .layout-container-header {
+    padding: 10px 10px 0 10px;
+    background: #F2F2F2;
   }
 
   .layout-container-center {
+    width: 100%;
     flex: 1;
     display: flex;
-    flex-direction: column;
-    overflow: auto;
+    flex-direction: row;
+    height: 0;
+
+    .conterTable {
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+    }
+
+    .line {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      background: #f2f2f2;
+      cursor: w-resize;
+      width: 10px;
+
+      div {
+        line-height: 5px;
+        text-align: center;
+        color: rgb(151, 151, 151);
+      }
+    }
   }
 
   .layout-container-floor {
@@ -1203,6 +1370,52 @@ export default {
       }
     }
   }
-}
-</style>
+
+  .left-laowang {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+    border-bottom: 1px solid #EBEEF5;
+
+    .left-laowangTree {
+      flex: 1;
+      overflow-y: auto;
+    }
+
+    .left-laowangText {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      height: 48px;
+      border-bottom: 1px solid #EBEEF5;
+      color: #02A7F0;
+      box-sizing: border-box;
+      width: 100%;
+      padding: 0 10px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+  }
+
+  .custom-tree-node {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-size: 14px;
+    padding-right: 8px;
+    position: relative;
+    box-sizing: border-box;
+    width: 10%;
+
+    .spanWitdh {
+      box-sizing: border-box;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      line-height: 36px;
+      display: inline-block;
+    }
+  }
+}</style>
   

+ 40 - 6
fhKeeper/formulahousekeeper/timesheet-workshop/src/views/product/list.vue

@@ -232,12 +232,12 @@
                     </el-table-column>
                     <el-table-column prop="workingTime" label="单件工时(分)"  width="140">
                         <template slot-scope="scope">
-                            <el-input v-model="scope.row.workingTime"   clearable maxlength="11" placeholder="请输入"></el-input>
+                            <el-input v-model.number="scope.row.workingTime"   clearable maxlength="11" placeholder="请输入"></el-input>
                         </template>
                     </el-table-column>
                     <el-table-column prop="unitPrice" label="单件工价(元)" width="140">
                         <template slot-scope="scope">
-                            <el-input v-model="scope.row.unitPrice"   clearable maxlength="9"  placeholder="请输入"></el-input>
+                            <el-input v-model.number="scope.row.unitPrice"   clearable maxlength="9"  placeholder="请输入"></el-input>
                         </template>
                     </el-table-column>
                     <el-table-column label="质检类型" width="150">
@@ -247,7 +247,6 @@
                                     :value="item.value">
                                 </el-option>
                             </el-select>
-
                         </template>
                     </el-table-column>
                     <el-table-column label="操作" width="100" fixed="right">
@@ -256,7 +255,15 @@
                         </template>
                     </el-table-column>
                 </el-table>
-                <i class="el-icon-plus" @click="addProcedure()"></i>
+
+                <div class="workshopTotal">
+                    <div class="workshopTotalHeji">
+                        <i class="el-icon-plus" @click="addProcedure()"></i>
+                        <span>合计</span>
+                    </div>
+                    <div class="workshopTotalText">{{ pieceHourTotal }}</div>
+                    <div>{{ priceSingleTotal }}</div>
+                </div>
 
             </div>
             <!--此处是录入物料的模块-->
@@ -925,7 +932,18 @@ export default {
             this.$refs.productTbl.doLayout();
         })
     },
-
+    computed: {
+        pieceHourTotal: function () {
+            return this.procedureLit.reduce((total, item) => {
+                return +total + +item.workingTime
+            }, 0)
+        },
+        priceSingleTotal: function () {
+            return this.procedureLit.reduce((total, item) => {
+                return +total + +item.unitPrice
+            }, 0)
+        },
+    },
     methods: {
         uploadFile(params) {
             let str = params.file.name.split(".");
@@ -3653,7 +3671,23 @@ export default {
     text-overflow: ellipsis;
 }
 
-.dialogSwitch {}
+.workshopTotal {
+    display: flex;
+    align-items: center;
+    height: 40px;
+    font-size: 18px;
+    .workshopTotalHeji {
+        width: 340px;
+        margin-right: 20px;
+        display: flex;
+        justify-content: space-between;
+    }
+    .workshopTotalText {
+        width: 120px;
+        margin-right: 30px;
+        padding-left: 10px;
+    }
+}
 
 // 111
 </style>

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

@@ -1,8 +1,8 @@
 <template>
   <section>
     <div style=" display: flex;">
-    <div ref="sidebars" style="width: 200px;display: block;background: #fff;border-right: 1px solid #E6E6E6;">
-      <div ref="abbisd" style="width: 200px;overflow: hidden;">
+    <div ref="sidebars" style="width: 180px;display: block;background: #fff;border-right: 1px solid #E6E6E6;">
+      <div ref="abbisd" style="width: 180px;overflow: hidden;">
           <el-col :span="12">
             <el-menu
               :default-active="defaultActive"
@@ -11,7 +11,7 @@
               background-color="#ffffff" 
               text-color="#666666"
               active-text-color="#20A0FF"
-              style="width:200px">
+              style="width:180px">
               <el-submenu index="1">
                 <template slot="title">
                   <i class="iconfont firerock-iconbaobiao"></i>
@@ -28,7 +28,7 @@
               </el-menu>
           </el-col>
       </div>
-      <div class="side" @click="side" ref="sid" style="left: 400px">
+      <div class="side" @click="side" ref="sid" style="left: 340px">
         <div class="spans" ref="side" style="left: -19px;"><i  ref="sideI" class="el-icon-arrow-left"></i></div>
       </div>
     </div>
@@ -71,7 +71,8 @@
           <el-input v-if="ins == 2" v-model="steelNum" placeholder="请输入钢印号" @change="selcts()" size="small" style="width:140px"></el-input>
           
       </div>
-      <p  v-if="!personnelFlag" :style="`${ins == 9 ? 'width:20%' : ins == 14 ? 'width: 20%' : 'width: 10%'}`" class="tableRightBtn">
+      <!-- <p  v-if="!personnelFlag" :style="`${ins == 9 ? 'width:20%' : ins == 14 ? 'width: 20%' : 'width: 10%'}`" class="tableRightBtn"> -->
+      <p  :style="`${ins == 9 ? 'width:20%' : ins == 14 ? 'width: 20%' : 'width: 10%'}`" class="tableRightBtn">
         <el-button type="primary" @click="exportExcel" size="mini">{{ $t('reporderived') }}</el-button>
       </p>
     </div>
@@ -87,7 +88,7 @@
                 <el-table-column align="center" prop="name" label="人员" min-width="100" fixed="left"></el-table-column>
                 <el-table-column v-for="(item, index) in personWorkHoursWagesHead" :key="index" :label="item" align="center" min-width="150">
                     <template slot-scope="scope">
-                        <div v-for="(items, indexs) in scope.row.personWorkHoursWages" :key="indexs" @click="showReportDetail(scope.row,item)" :class="`${scope.row.departmentCascade== '小计' ? '' : 'colorText'}`">
+                        <div v-for="(items, indexs) in scope.row.personWorkHoursWages" :key="indexs" @click="showReportDetail(scope.row,item,0)" :class="`${scope.row.departmentCascade== '小计' ? '' : 'colorText'}`">
                             <div v-if="items.crateDate == item">
                                <div> {{items.workTime}}分钟 </div> 
                                <div>{{items.cost}}元</div>
@@ -96,8 +97,8 @@
                     </template>
                 </el-table-column>
                 <el-table-column align="center" prop="totalResult" label="合计" min-width="150">
-                   <template slot-scope="scope">
-                    {{scope.row.totalResult}}
+                   <template slot-scope="scope" >
+                    <span :class="`${'colorText'}`" @click="showReportDetail(scope.row,item,1)">{{scope.row.totalResult}}</span>
                   </template>
                 </el-table-column>
             </el-table>
@@ -111,13 +112,13 @@
                 </el-table-column>
                 <el-table-column align="center" prop="procedureName" label="工序" min-width="250"></el-table-column>
                 <!-- <el-table-column align="center" prop="userName" label="人员" min-width="150"></el-table-column> -->
-                <el-table-column align="center" prop="planWorkTime" label="计划工时" min-width="250">
+                <el-table-column align="center" prop="planWorkTime" label="计划工时" width="150">
                   <template slot-scope="scope" v-if="scope.row.planWorkTime">{{scope.row.planWorkTime}}分钟</template>
                 </el-table-column>
-                <el-table-column align="center" prop="nowWorkTime" label="当前工时" min-width="250">
+                <el-table-column align="center" prop="nowWorkTime" label="当前工时" width="150">
                   <template slot-scope="scope" v-if="scope.row.nowWorkTime">{{scope.row.nowWorkTime}}分钟</template>
                 </el-table-column>
-                <el-table-column align="center" prop="progress" label="进度" min-width="250">
+                <el-table-column align="center" prop="progress" label="进度" width="150">
                   <template slot-scope="scope" v-if="scope.row.progress">
                     {{scope.row.progress}}%
                   </template>
@@ -131,45 +132,45 @@
                 </el-table-column>
                 <el-table-column align="center" prop="productName" label="产品名称" min-width="250"></el-table-column>
                 <el-table-column align="center" prop="foremanName" label="工长" min-width="150"></el-table-column>
-                <el-table-column align="center" prop="startDate" label="开工时间" min-width="250"></el-table-column>
-                <el-table-column align="center" prop="endDate" label="完工时间" min-width="250"></el-table-column>
+                <el-table-column align="center" prop="startDate" label="开工时间" width="150"></el-table-column>
+                <el-table-column align="center" prop="endDate" label="完工时间" width="150"></el-table-column>
                 <el-table-column align="center" prop="procedureName" label="工序" min-width="250"></el-table-column>
-                <el-table-column align="center" prop="creatorName" label="组员" min-width="250"></el-table-column>
-                <el-table-column align="center" prop="createDate" label="报工时间" min-width="250"></el-table-column>
-                <el-table-column align="center" prop="checkName" label="质检人" min-width="250">
+                <el-table-column align="center" prop="creatorName" label="组员" width="150"></el-table-column>
+                <el-table-column align="center" prop="createDate" label="报工时间" width="150"></el-table-column>
+                <el-table-column align="center" prop="checkName" label="质检人" width="150">
                   <template slot-scope="scope">{{scope.row.checkName}}</template>
                 </el-table-column>
             </el-table>
 
             <!-- 计划实时进度表 -->
             <el-table v-if="ins == 3"  key="4" border :data="planRealTimeProgressList" highlight-current-row v-loading="listLoading" :height="+tableHeight - 1" style="width: 100%;">
-                <el-table-column align="center" prop="taskName" label="排产工单号" min-width="150">
+                <el-table-column align="center" prop="taskName" label="排产工单号" min-width="250">
                   <template slot-scope="scope">{{scope.row.taskName}}</template>
                 </el-table-column>
-                <el-table-column align="center" prop="userName" label="工长" min-width="250"></el-table-column>
-                <el-table-column align="center" prop="planNum" label="计划件数" min-width="150">
+                <el-table-column align="center" prop="userName" label="工长" width="150"></el-table-column>
+                <el-table-column align="center" prop="planNum" label="计划件数" width="100">
                   <template slot-scope="scope">{{scope.row.planNum}}</template>
                 </el-table-column>
                 <el-table-column align="center" prop="productName" label="产品名称" min-width="150">
                   <template slot-scope="scope">{{scope.row.productName}}</template>
                 </el-table-column>
-                <el-table-column align="center" prop="startDate" label="开始日期" min-width="150">
+                <el-table-column align="center" prop="startDate" label="开始日期" width="150">
                   <template slot-scope="scope">{{scope.row.startDate}}</template>
                 </el-table-column>
-                <el-table-column align="center" prop="endDate" label="完工日期" min-width="150">
+                <el-table-column align="center" prop="endDate" label="完工日期" width="150">
                   <template slot-scope="scope">{{scope.row.endDate}}</template>
                 </el-table-column>
-                <el-table-column align="center" prop="statinoName" label="工位" min-width="250"></el-table-column>
-                <el-table-column align="center"  label="计划工时" min-width="150">
+                <el-table-column align="center" prop="statinoName" label="工位" width="150"></el-table-column>
+                <el-table-column align="center"  label="计划工时" min-width="190">
                   <template slot-scope="scope" v-if="scope.row.planWorkTime">{{scope.row.planWorkTime}}分钟 {{scope.row.planCost}}元</template>
                 </el-table-column>
-                <el-table-column align="center"  label="当前工时" min-width="250">
+                <el-table-column align="center"  label="当前工时" min-width="190">
                   <template slot-scope="scope" v-if="scope.row.nowWorkTime">{{scope.row.nowWorkTime}}分钟 {{scope.row.nowCost}}元</template>
                 </el-table-column>
                 <el-table-column align="center"  label="实际完工日期" min-width="150">
                   <template slot-scope="scope" v-if="scope.row.realEndDate">{{scope.row.realEndDate}}</template>
                 </el-table-column>
-                <el-table-column align="center"  label="进度" min-width="250">
+                <el-table-column align="center"  label="进度" min-width="150">
                   <template slot-scope="scope" v-if="scope.row.progress">{{scope.row.progress}}</template>
                 </el-table-column>
             </el-table>
@@ -261,7 +262,7 @@
                               <div v-if="items.createDate == item">
                                   <div>{{items.procedureName}}</div>
                                   <div>{{items.workingTime}}分钟 {{items.cost}}元</div>
-                                  <div>{{items.finishNum}}件</div>
+                                  <div>{{items.finishNum}}件</div>
                               </div>
                           </div>
                       </template>
@@ -307,7 +308,7 @@
   </div>
 
   <el-dialog :title="'详情'" :visible.sync="reportDetailDialog" width="1480px">
-          <div>
+          <div> 
             日期:<el-select v-model="simpleDateChoose" placeholder="请选择" @change="getPersonWorkHoursWagesDetail(simpleDateChoose)">
                 <el-option
                   v-for="(item,index) in personWorkHoursWagesHead"
@@ -672,7 +673,8 @@ export default {
 
       sumObject: { english_achievements: 1000, math_achievements: 888 }, // 合计数据
 
-      hasMoreUserResult:""
+      hasMoreUserResult:"",
+      exportTargetUserId:null,
     };
   },
   computed: {},
@@ -745,14 +747,14 @@ export default {
       this.taskName=item.taskName
       this.getPlanDetail(item);
     },
-    showReportDetail(row,item){
+    showReportDetail(row,item,viewAll){
       if(row.departmentCascade=='小计'){
           return
       }
       console.log(item)
       this.reportDetailDialog=true
       this.detailUserId=row.id
-      this.getPersonWorkHoursWagesDetail(item)
+      this.getPersonWorkHoursWagesDetail(item,viewAll)
     },
     authorityToJudge() {
     //   if(this.permissions.reportProject || this.permissions.reportAllProject) {this.ssl(0);this.defaultActive = '1-1';return} else
@@ -900,7 +902,7 @@ export default {
           if (res.code == "ok") {
             this.personWorkHoursWagesList=res.data.records
             this.personWorkHoursWagesHead=res.data.header
-            this.simpleDateChoose=this.personWorkHoursWagesHead[0]
+            // this.simpleDateChoose=this.personWorkHoursWagesHead[0]
             this.total=res.data.total
             this.plondelas++
           } else {
@@ -918,13 +920,26 @@ export default {
         });
     },
     //点击详情(人员工时工价表)
-    getPersonWorkHoursWagesDetail(item){
-      this.simpleDateChoose=item
+    getPersonWorkHoursWagesDetail(item,viewAll){
       this.listLoading=true
-      this.http.post( "/report/getPersonWorkHoursWagesDetail", {
+      let param={
+        userId:this.detailUserId
+      }
+      if(viewAll==1){
+        this.simpleDateChoose=''
+        param={
+          ...param,
+          startDate:this.rangeDatas[0],
+          endDate:this.rangeDatas[1]
+        }
+      }else{
+        this.simpleDateChoose=item
+        param={
+          ...param,
           date: this.simpleDateChoose.substring(0,4)+"-"+this.simpleDateChoose.substring(4,6)+"-"+this.simpleDateChoose.substring(6,this.simpleDateChoose.length),
-          userId:this.detailUserId
-      },
+        }
+      }
+      this.http.post( "/report/getPersonWorkHoursWagesDetail", param,
       res => {
         if (res.code == "ok") {
           this.personWorkHoursWagesDetail=res.data.record
@@ -1129,6 +1144,7 @@ export default {
     },
     //获取人员填报数据
     getPlanDataWithUserId(userId){
+      this.exportTargetUserId=userId;
       this.listLoading=true
         this.http.post( "/report/getPlanDataWithUserId", {
             startDate:this.rangeDatas[0],
@@ -1358,13 +1374,18 @@ export default {
     }
     else if (this.ins == 6) {
         fName = '车间工位计划表_' + '.xlsx';
-        url += "/exportPlanDataWithStation";
         sl.startDate=this.rangeDatas[0];
         sl.endDate=this.rangeDatas[1];
-        sl.deptId=this.departmentIdArray[this.departmentIdArray.length-1];
-        if(this.exportDeptId){
+        if(!this.personnelFlag){
+          url += "/exportPlanDataWithStation";
+          sl.deptId=this.departmentIdArray[this.departmentIdArray.length-1];
+          if(this.exportDeptId){
           sl.filterDeptId=this.exportDeptId;
           sl.isFilterDept=1
+          }
+        }else{
+          url += "/exportPlanDataWithUserId";
+          sl.userId=this.exportTargetUserId
         }
     }
         this.http.post(url, sl,
@@ -1407,24 +1428,20 @@ export default {
     side() {
       if(this.$refs.side.style.left < '1px') {
         this.$refs.sidebars.style.width = '1px'
-        this.$refs.sid.style.left = '201px'
+        this.$refs.sid.style.left = '161px'
         this.$refs.side.style.left = '1px'
         this.$refs.sideI.className = 'el-icon-arrow-right'
-        // this.$refs.staff.style.margin = '5px 0px 0px 5px'
-        // this.$refs.staff.style.width = '100%'
         this.$refs.headHe.style.paddingLeft = '10px'
-        this.$refs.headine.style.width = (this.windowWidth - 200)+'px'
-        this.$refs.tabless.style.width = (this.windowWidth - 200)+'px'
+        this.$refs.headine.style.width = (this.windowWidth - 180)+'px'
+        this.$refs.tabless.style.width = (this.windowWidth - 180)+'px'
       } else {
-        this.$refs.sidebars.style.width = '200px'
-        this.$refs.sid.style.left = '400px'
+        this.$refs.sidebars.style.width = '180px'
+        this.$refs.sid.style.left = '340px'
         this.$refs.side.style.left = '-19px'
         this.$refs.sideI.className = 'el-icon-arrow-left'
-        // this.$refs.staff.style.margin = '5px 0px 0px 10px'
-        // this.$refs.staff.style.width = '98%'
         this.$refs.headHe.style.paddingLeft = '10px'
-        this.$refs.headine.style.width = (this.windowWidth - 400)+'px'
-        this.$refs.tabless.style.width = (this.windowWidth - 400)+'px'
+        this.$refs.headine.style.width = (this.windowWidth - 340)+'px'
+        this.$refs.tabless.style.width = (this.windowWidth - 340)+'px'
       }
     },
     picks() {
@@ -1648,7 +1665,7 @@ export default {
 /* 侧边栏收索 */
 .side {
   position: absolute;
-  z-index: 2;
+  z-index: 5;
   border-right: 2px solid #DDDDDD;
   height: 100%;
   top: 0;

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

@@ -352,7 +352,7 @@
                 </el-form-item>
 
                 <!-- 其他负责人 --> 
-                <el-form-item :label="$t('responsiblepersons')" prop="managerId">
+                <el-form-item :label="$t('responsiblepersons')" prop="otherManagerIds">
                     <el-select v-model="depForm.otherManagerIds" filterable v-if="user.userNameNeedTranslate != '1'" clearable multiple style="width: 100%" :placeholder="$t('defaultText.pleaseChoose')" >
                         <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id">
                           <span style="float: left">{{ item.name }}</span>
@@ -361,6 +361,17 @@
                     </el-select>
                     <selectCat :size="'medium'" :widthStr="'360'" v-if="user.userNameNeedTranslate == '1'" :subject="users" :subjectId="depForm.otherManagerIds" :distinction="'4'" @selectCal="selectCal"></selectCat>
                 </el-form-item>
+
+                <!-- 质检人 --> 
+                <el-form-item :label="'质检人'" prop="qualityManagerIds">
+                    <el-select v-model="depForm.qualityManagerIds" filterable v-if="user.userNameNeedTranslate != '1'" clearable multiple style="width: 100%" :placeholder="$t('defaultText.pleaseChoose')" >
+                        <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id">
+                          <span style="float: left">{{ item.name }}</span>
+                          <span style="float: right; color: #8492a6; font-size: 13px">{{ item.jobNumber }}</span>
+                        </el-option>
+                    </el-select>
+                    <selectCat :size="'medium'" :widthStr="'360'" v-if="user.userNameNeedTranslate == '1'" :subject="users" :subjectId="depForm.qualityManagerIds" :distinction="'4'" @selectCal="selectCal"></selectCat>
+                </el-form-item>
             </el-form>
             <span slot="footer" class="dialog-footer">
                 <el-button @click="departmentVisible = false">{{ $t('btn.cancel') }}</el-button>
@@ -2934,6 +2945,16 @@ export default {
           } else {
             this.$set(that.depForm, 'otherManagerIds', [])
 
+          }
+          if(that.depData.qualityManagerIds) {
+            if(Array.isArray(that.depData.qualityManagerIds)) {
+              this.$set(that.depForm, 'qualityManagerIds', that.depData.qualityManagerIds)
+            } else {
+              this.$set(that.depForm, 'qualityManagerIds', that.depData.qualityManagerIds.split(','))
+            }
+          } else {
+            this.$set(that.depForm, 'qualityManagerIds', [])
+
           }
           // console.log('点击编辑的时候', that.depData)
           // if(that.depData.reportAuditUserid != null && that.depData.reportAuditUserid != "null" && that.depData.reportAuditUserid.length > 0) {
@@ -3007,6 +3028,10 @@ export default {
           if(this.depForm.otherManagerIds) {
             form.otherManagerIds = this.depForm.otherManagerIds.toString();
           }
+          // 质检人
+          if(this.depForm.qualityManagerIds) {
+            form.qualityManagerIds = this.depForm.qualityManagerIds.toString();
+          }
           this.http.post(
             this.depForm.id == null
               ? this.port.manage.add
@@ -3023,6 +3048,7 @@ export default {
                   this.depData.label = form.name;
                   this.depData.managerId = form.managerId;
                   this.depData.otherManagerIds = form.otherManagerIds;
+                  this.depData.qualityManagerIds = form.qualityManagerIds;
                 }
 
                 this.getDepartment();

+ 5 - 3
fhKeeper/formulahousekeeper/timesheet/src/i18n/en.json

@@ -908,9 +908,10 @@
   "dailyworkinghours": "Normal working hours per day",
   "workingdayspermonth": "Average working days per month",
   "hoursreporteperday": "Lock the upper limit of daily reporting hours",
-  "imitillingtime": "Fill in the time limit",
+  "imitillingtime": "Max report time",
+  "minReportTime": "Min report time",
   "lockingworkinghours": "Lock working hours",
-  "chargedtocost": "Overtime hours charged to cost",
+  "chargedtocost": "Overtime hours produce extra cost",
   "hourscanbereported": "Reportable overtime hours",
   "workSettings": "Overtime settings",
   "bei-gong-zi": "double salary",
@@ -1505,5 +1506,6 @@
   "que-ding-yao-shan-chu-ci-tiao-he-tong-lei-xing-ma": "Are you sure you want to delete this contract type ?",
   "que-ding-yao-shan-chu-gai-he-tong-ma": "Are you sure you want to delete this contract ?",
   "que-ding-yao-shan-chu-gai-wen-jian-ma": "Are you sure you want to delete this file ?",
-  "he-tong-guan-li-dao-ru-mo-ban": "Contract Management Template"
+  "he-tong-guan-li-dao-ru-mo-ban": "Contract Management Template",
+  "minMaxCheck": "report time min value should not be greater than the max value"
 }

+ 7 - 5
fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json

@@ -909,14 +909,15 @@
   "employeehourlywage": "员工时薪录入方式设置",
   "methodsa": "方式一: 录入月成本,自动计算时薪",
   "suitableforfulltimeemployees": "(适合企业全职员工)",
-  "workingdayspermonth": "平均每月工作天数",
-  "dailyworkinghours": "每日正常工作时长",
+  "workingdayspermonth": "平均每月工作",
+  "dailyworkinghours": "每日正常工作",
   "lockingworkinghours": "锁定工作时长",
   "hoursreporteperday": "锁定每日填报工时的上限",
-  "imitillingtime": "填报时长上限",
+  "imitillingtime": "工时上限",
+  "minReportTime": "工时下限",
   "workSettings": "加班设置",
   "hourscanbereported": "可填报加班时长",
-  "chargedtocost": "加班工时记入成本",
+  "chargedtocost": "加班产生额外成本",
   "bei-gong-zi": "倍工资",
   "visittwo": "方式二:直接录入时薪",
   "timeemployees": "(适合计时发放酬劳的小时工,兼职员工)",
@@ -1509,5 +1510,6 @@
   "que-ding-yao-shan-chu-ci-tiao-he-tong-lei-xing-ma": "确定要删除此条合同类型吗?",
   "que-ding-yao-shan-chu-gai-he-tong-ma": "确定要删除该合同吗?",
   "que-ding-yao-shan-chu-gai-wen-jian-ma": "确定要删除该文件吗?",
-  "he-tong-guan-li-dao-ru-mo-ban": "合同管理导入模板"
+  "he-tong-guan-li-dao-ru-mo-ban": "合同管理导入模板",
+  "minMaxCheck": "工时下限不得大于上限"
 }

+ 69 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/Home.vue

@@ -248,6 +248,18 @@
                 </el-dialog>
             </section>
         </el-col>
+
+        <!-- 完善工号弹窗 -->
+        <el-dialog title="完善工号" :visible.sync="perfectJobNumber" width="500px" :show-close="false">
+            <el-form :model="perfectForm" :rules="rules" ref="perfectForm" label-width="80px" class="demo-ruleForm">
+                <el-form-item label="工号" prop="jobNumber">
+                    <el-input v-model.trim="perfectForm.jobNumber"></el-input>
+                </el-form-item>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="editPerfectJobNumber('perfectForm')">确 定</el-button>
+            </span>
+        </el-dialog>
     </el-row>
 </template>
 
@@ -261,10 +273,16 @@
                 companyForm:{
                     name: '',
                 },
+                perfectForm:{
+                    jobNumber: '',
+                },
                 rules: {
                     name: [
                         { required: true, message: '请输入公司名称', trigger: 'blur' },
                         { min: 1, max: 20, message: '长度为1-20个字符', trigger: 'blur' }
+                    ],
+                    jobNumber: [
+                        { required: true, message: '请输入工号', trigger: 'blur' }
                     ]
                 },
                 tourFlg: false,
@@ -377,7 +395,11 @@
                 setTimeLoad: null,
 
                 // 遮罩
-                vTourFlg: false
+                vTourFlg: false,
+
+                
+                perfectJobNumber: false, // 完善工号弹窗
+                jobNumberCheckCompanyId: [936], // 定制需求,需要完善工号的公司id
             };
         },
         created() {
@@ -785,6 +807,46 @@
                     console.log(error, '哦耶')
                 })
             },
+
+            // 完善工号
+            editPerfectJobNumber(perfectForm) {
+                this.$refs[perfectForm].validate((valid) => {
+                    if (valid) {
+                        const { id } = this.user
+                        this.http.post("/user/updateUserJobNumber", {
+                            jobNumber: this.perfectForm.jobNumber,
+                            userId: id
+                        },
+                        res => {
+                            if (res.code == "ok") {
+                                this.perfectJobNumber = false
+                                let nerUser = {
+                                    ...this.user,
+                                    jobNumber: this.perfectForm.jobNumber
+                                }
+                                sessionStorage.setItem('user', JSON.stringify(nerUser));
+                                this.$message({
+                                    message: '操作成功',
+                                    type: "success"
+                                });
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        },
+                        error => {
+                            this.$message({
+                                message: error,
+                                type: "error"
+                            });
+                        });
+                    } else {
+                        return false;
+                    }
+                });
+            }
         },
         mounted() {
             var ua = navigator.userAgent.toLowerCase();
@@ -839,6 +901,12 @@
                     }, 1000)
                 }, 200)
             }
+
+            // 检查是否有工号
+            const { jobNumber, companyId } = this.user
+            if(this.jobNumberCheckCompanyId.includes(companyId) && !jobNumber) {
+                this.perfectJobNumber = true
+            }
         },
     };
 </script>

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

@@ -296,7 +296,7 @@
 
                 <selectCat v-if="user.userNameNeedTranslate == '1'" :size="'small'" :widthStr="'120'" :distinction="'2'"
                   :clearable="true" :subject="users" :disabled="!permissions.costAudit" :subjectId="ownerId"
-                  ref="selectCat" @selectCal="selectCal"></selectCat>
+                  ref="selectCat" @selectCal="selectCal" :filterable="true"></selectCat>
               </el-form-item>
               <!-- 单据编号 -->
               <el-form-item :label="$t('receiptnumber')">
@@ -323,7 +323,7 @@
               <!-- 填报日期 -->
               <div style="display: inline-block;">
                 <el-form-item :label="'项目'">
-                  <el-select v-model="selectProject" size="small" style="width: 162px" clearable>
+                  <el-select v-model="selectProject" size="small" style="width: 162px" clearable filterable>
                     <el-option v-for="item in projectList" :label="item.projectName" :value="item.id">
                       <span style="float: left">{{ item.projectName }}</span>
                       <span style="float: right; color: #8492a6;">{{ item.projectCode }}</span>

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

@@ -1178,7 +1178,9 @@
                         _this.myChart = myChart;
                         if(totalMoneyCost) {
                             this.zhishin = totalMoneyCost.toFixed(2)
-                        } 
+                        } else {
+                            this.zhishin = 0
+                        }
                         if(this.radio == this.$t('other.project') || this.radio == this.$t('zhu-xiang-mu') || this.radio == this.$t('ren-yuan') || this.radio == this.$t('projectclassification') || this.radio==this.$t('lable.department')) {
                             var option = {
                                 title: {

+ 17 - 3
fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue

@@ -18,7 +18,7 @@
                     <el-radio v-model="timeType.hourCostInputType" :label="0" style="width:100%;margin-left:10px;">{{ $t('methodsa') }}<span class="tip">{{ $t('suitableforfulltimeemployees') }}</span></el-radio>
                 </div>
                 <div style="width:100%;float:left"> 
-                    <el-form ref="form0" :inline="true" :model="timeType" label-width="150px" style="margin-top:10px">
+                    <el-form ref="form0" :inline="true" :model="timeType" label-width="120px" style="margin-top:10px">
                         <el-form-item :label="$t('workingdayspermonth')" prop="monthDays">
                         <el-input v-model="timeType.monthDays"  type="number" style="width:120px;"></el-input>
                         {{ $t('time.day') }} 
@@ -40,7 +40,13 @@
                             <el-select :disabled="timeType.lockWorktime" v-model="timeType.maxReportTime" type="number" style="width:120px;">
                                 <el-option v-for="item in maxReportTimeRange" :key="item" :label="item.toFixed(1)" :value="item"></el-option>
                             </el-select><span style="margin-left:5px;color:#409eff">{{ $t('time.hour') }}</span>
-                        </el-form-item><br>
+                        </el-form-item>
+                        <el-form-item :label="$t('minReportTime')">
+                            <el-select :disabled="timeType.lockWorktime" v-model="timeType.minReportTime" type="number" style="width:120px;">
+                                <el-option v-for="item in minReportTimeRange" :key="item" :label="item.toFixed(1)" :value="item"></el-option>
+                            </el-select><span style="margin-left:5px;color:#409eff">{{ $t('time.hour') }}</span>
+                        </el-form-item>
+                        <br>
                         <el-form-item :label="$t('workSettings')" prop="allday" v-if="!timeType.lockWorktime">
                             <el-checkbox v-model="timeType.fillOvertime" :label="$t('hourscanbereported')" />
                             <el-form-item v-if="timeType.fillOvertime">
@@ -713,7 +719,7 @@
                     label: 'label'
                 },
                 maxReportTimeRange: [],
-
+                minReportTimeRange:[0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.5,13.0,13.5,14.0,14.5,15.0],
                 wxFilterText: '', // 企业微信搜索
 
                 searchPersonnelFlg: false,
@@ -1308,6 +1314,14 @@
                                 return
                             }
                         }
+                        //工时上下限的校验
+                        if (param.minReportTime > param.maxReportTime) {
+                            this.$message({
+                                message:this.$t('minMaxCheck'),
+                                type:"error"
+                            })
+                            return
+                        }
                         delete param.userList
                         param.customTextStatus = param.customTextStatus && param.customTextActive ? 1 : 0
                         param.customDegreeStatus = param.customDegreeStatus && param.customDegreeActive ? 1 : 0

+ 112 - 43
fhKeeper/formulahousekeeper/timesheet/src/views/task/list.vue

@@ -3,10 +3,6 @@
         <!--工具条-->
         <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
             <el-form :inline="true">
-                <!-- <div style="margin-left: 20px;display: inline-block">
-                <el-form-item label="任务列表">
-                </el-form-item>
-                </div> -->
                 <el-form-item :label="$t('tasklist')">
                     <div style="margin-left: 8px">
                     <!-- <el-input style="float:left;" v-model="keyword" class="input-with-select" placeholder="请输入项目名称关键字" clearable="true"> -->
@@ -18,65 +14,70 @@
                     <!-- </el-input> -->
                     </div>
                 </el-form-item>
-                <!-- <el-form-item label="项目分组" v-if="user.companyId == '428'">
-                    <div style="margin-left: 8px">
-                        <el-select v-model="groupName" style="width:200px;" placeholder="请选择" clearable @change="hiddens()">
-                            <el-option v-for="(item, index) in groupNameList" :key="index" :label="item" :value="item"></el-option>
-                        </el-select>
-                    </div>
-                </el-form-item> -->
 
                 <el-form-item :label="$t('subordinatedepartments')" v-if="user.timeType.projectWithDept">
-                    <!-- <span style="margin-left:5px;margin-right:5px;color:#606266;">部门</span> -->
                     <el-cascader v-model="deptId" :options="departmentList" size="small" :placeholder="$t('qing-xuan-ze-bu-men')"
                         :props="{ checkStrictly: true, expandTrigger: 'hover' }" :show-all-levels="false" clearable filterable @change="hiddens"
                     ></el-cascader>
                 </el-form-item>
 
-                <!-- <el-form-item style="float:right;">
-                    <el-link type="primary" :underline="false" @click="handleAdd(-1,null)">新增任务</el-link>
-                </el-form-item> -->
-
-                <!-- <div style="margin-left: 40px;display: inline-block">
-                <el-form-item label="类型">
-                </el-form-item>
-                </div> -->
                 <el-form-item :label="$t('types')">
                     <div style="margin-left: 8px">
-                    <!-- <el-input style="float:left;" v-model="keyword" class="input-with-select" placeholder="请输入项目名称关键字" clearable="true"> -->
                         <el-select v-model="typeField" style="width:120px;" size="small" slot="prepend" :placeholder="$t('defaultText.pleaseChoose')" clearable @change="hiddens()">
-                            <!-- <el-option label="任务" value="0" @click.native="hiddens()"></el-option>
-                            <el-option label="里程碑" value="1" @click.native="hiddens()"></el-option>
-                            <el-option label="风险" value="2" @click.native="hiddens()"></el-option> -->
                             <el-option :label="$t('other.task')" value="0"></el-option>
                             <el-option :label="$t('other.milestone')" value="1"></el-option>
                             <el-option :label="$t('risk')" value="2"></el-option>
                         </el-select>
-                        <!-- <el-button slot="append" @click="searchList" icon="el-icon-search"></el-button> -->
-                    <!-- </el-input> -->
                     </div>
                 </el-form-item>
-                <el-form-item >
-                    <div style="margin-left: 20px">
-                        <el-select v-model="dateType" style="width:120px;" size="small" slot="prepend" :placeholder="$t('defaultText.pleaseChoose')">
-                            <el-option :label="$t('starttimes')" :value="0" @click.native="hiddens(1)"></el-option>
-                            <el-option :label="$t('deadline')" :value="1" @click.native="hiddens(1)"></el-option>
+
+                <el-form-item :label="'项目'">
+                    <div style="margin-left: 8px">
+                        <el-select v-model="screenProjectId" style="width:150px;" size="small" slot="prepend" :placeholder="$t('defaultText.pleaseChoose')" clearable @change="screenProjectChange">
+                            <el-option v-for="item in allProjectList" :key="item.id"  :label="item.projectName" :value="item.id"></el-option>
                         </el-select>
                     </div>
                 </el-form-item>
-                <el-form-item >
+
+                <el-form-item :label="'任务分组'">
                     <div style="margin-left: 8px">
-                        <el-date-picker
-                        v-model="dateSelect"
-                        type="daterange"
-                        size="small"
-                        range-separator="-"
-                        :start-placeholder="$t('interval')"
-                        :end-placeholder="$t('interval')"
-                        value-format="yyyy-MM-dd"
-                        clearable
-                        @change="hiddens()">
-                        </el-date-picker>
+                        <el-select v-model="screenTaskGroupingId" style="width:150px;" size="small" :disabled="!screenProjectId" slot="prepend" :placeholder="$t('defaultText.pleaseChoose')" clearable @change="hiddens()">
+                            <el-option v-for="item in taskGroupList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                        </el-select>
+                    </div>
+                </el-form-item>
+
+                <el-form-item :label="'人员'">
+                    <div style="margin-left: 8px">
+                        <el-select v-model="screenPersonnelId" filterable style="width:120px;" size="small" slot="prepend" :placeholder="$t('defaultText.pleaseChoose')" clearable @change="hiddens()" v-if="user.userNameNeedTranslate != '1'">
+                            <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                        </el-select>
+
+                        <selectCat :subject="users" :subjectId="screenPersonnelId" :filterable="true" :clearable="true"  @selectCal="selectCal" :size="'small'" :distinction="'10'" v-if="user.userNameNeedTranslate == '1'"></selectCat>
+                    </div>
+                </el-form-item>
+
+                <el-form-item>
+                    <div style="display: flex;">
+                        <div style="margin-left: 20px">
+                            <el-select v-model="dateType" style="width:120px;" size="small" slot="prepend" :placeholder="$t('defaultText.pleaseChoose')">
+                                <el-option :label="$t('starttimes')" :value="0" @click.native="hiddens(1)"></el-option>
+                                <el-option :label="$t('deadline')" :value="1" @click.native="hiddens(1)"></el-option>
+                            </el-select>
+                        </div>
+                        <div style="margin-left: 8px">
+                            <el-date-picker
+                            v-model="dateSelect"
+                            type="daterange"
+                            size="small"
+                            range-separator="-"
+                            :start-placeholder="$t('interval')"
+                            :end-placeholder="$t('interval')"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                            @change="hiddens()">
+                            </el-date-picker>
+                        </div>
                     </div>
                 </el-form-item>
                 <el-form-item style="float: right;" v-if="user.companyId != '3092'">
@@ -503,6 +504,7 @@ import { error } from 'dingtalk-jsapi';
                 isDeleting: true,
                 showOrNot: false,
                 typeField: null,
+
                 searchField: '0',
                 keyword:null,
                 user: JSON.parse(sessionStorage.getItem("user")),
@@ -632,6 +634,12 @@ import { error } from 'dingtalk-jsapi';
                 meetingStartValue: '',
                 meetingEndValue: '',
                 toMeetTaskId:'',
+
+                // 筛选条件
+                screenProjectId: '',
+                screenTaskGroupingId: '',
+                screenPersonnelId: '',
+                allProjectList: []
             };
         },
         methods: {
@@ -894,6 +902,7 @@ import { error } from 'dingtalk-jsapi';
 
             //获取项目列表
             getList() {
+                console.log('执行函数')
                 this.listLoading = true;
                 let parameter = {
                     status: this.searchField,
@@ -901,6 +910,9 @@ import { error } from 'dingtalk-jsapi';
                     pageIndex: this.page,
                     pageSize: this.size,
                     // type: this.typeField
+                    projectId: this.screenProjectId,
+                    groupId: this.screenTaskGroupingId,
+                    targetUserId: this.screenPersonnelId
                 }
                 if(this.typeField != 'null' && this.typeField != null && this.typeField != '') {
                     parameter.type = this.typeField
@@ -1800,7 +1812,63 @@ import { error } from 'dingtalk-jsapi';
                         arr.push(obj.arrUserList[i].id) 
                     }
                     this.causeRejectionForm.responsible = arr
+                } else if(obj.distinction == '10') {
+                    this.screenPersonnelId = obj.id
+                    this.hiddens()
                 }
+            },
+
+            screenProjectChange() {
+                if(!this.screenProjectId) {
+                    this.screenTaskGroupingId = ''
+                } else {
+                    this.getTaskGroupList()
+                }   
+                this.hiddens()
+
+            },
+
+            // 获取项目列表
+            getAllProjectlist() {
+                this.http.post('/project/getProjectList',{},
+                res => {
+                    if (res.code == "ok") {
+                        this.allProjectList = res.data;
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            // 获取任务分组列表
+            getTaskGroupList() {
+                this.http.post('/task-group/list',{
+                    projectId: this.screenProjectId
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.taskGroupList = res.data;
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
             }
         },
         created() {
@@ -1818,6 +1886,7 @@ import { error } from 'dingtalk-jsapi';
             if(this.user.timeType.projectWithDept) {
                 this.getDepartmentList()
             }
+            this.getAllProjectlist()
             // if(this.user.companyId == '428') {
             //     this.getSthForSb()
             // }

+ 52 - 7
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -345,6 +345,9 @@
 
         <!-- 工时推送日志弹窗 -->
         <el-dialog title="工时推送日志" :visible.sync="pushWorkTimeLogDig"  width="70%" :before-close="handleClose">
+              <template>
+                <el-button type="primary" size="small" style="float: right" @click="exportPushLog">导出</el-button>
+              </template>  
               <template>
                 <el-table :data="pushWorkTimeLogData" style="width: 100%" height="500" >
                     <el-table-column prop="syncTime" label="推送时间" width="150"></el-table-column>
@@ -674,7 +677,7 @@
                             :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)" @change="onTaskSelected(domain)">
                                 <el-option v-for="item in domain.taskList" :key="item.taskId" :label="item.taskName" :value="item.taskId"></el-option>
                             </el-select>
-                            <el-checkbox v-model="domain.taskFinish" v-if="domain.taskId != undefined">{{$t('state.completed')}}</el-checkbox>
+                            <el-checkbox v-model="domain.taskFinish" v-if="domain.taskId != undefined && user.companyId != '5608'">{{$t('state.completed')}}</el-checkbox>
                         </el-form-item>
                         <!--针对依斯贝的SAP服务-->
                         <el-form-item v-if="user.companyId==3092" label="服务" :prop="'domains.' + index + '.sapServiceId'" 
@@ -1158,9 +1161,18 @@
                         <el-option :label="$t('state.alreadyPassedAndWaitingAudit')" value="1"></el-option>
                     </el-select>
                 </el-form-item>
+                <el-form-item prop="exportType" :label="'导出方式'" v-if="user.companyId == '936'">
+                    <div class="exportReportRadio">
+                        <el-radio v-model="exportType" :label="0">完整导出</el-radio>
+                        <el-radio v-model="exportType" :label="1">精简导出</el-radio>
+                        <el-tooltip effect="dark" :content="'精简日报不含工作事项和审批信息,数据量更小导出更快。'" placement="top-start">
+                            <i class="el-icon-question"></i>
+                        </el-tooltip>
+                    </div>
+                </el-form-item>
             </el-form>
             <div slot="footer" class="dialog-footer">
-                <el-button type="primary" @click="exportReport" style="width:100%;" :loading="listLoading">{{$t('export.export')}}</el-button>
+                <el-button type="primary" @click="exportReport" style="width:100%;" :loading="exportingData">{{$t('export.export')}}</el-button>
             </div>
         </el-dialog>
         <!--导出报表条件选择 -->
@@ -1949,6 +1961,8 @@
         },
         data() {
             return {
+                exportType: 0,
+                exportingData: false,
                 roleList:[{value: 1,label: 'CRC&LM'},{value: 2,label: 'PM'}],
                 jobResponseList:[],
                 yisibeiCompId: 3092,
@@ -2045,7 +2059,7 @@
                 subProjectList:[],
                 canEdit: true,
                 originCanEdit: true,
-                timeRange:[0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.0,12.5,13.0,13.5,14.0,14.5,15.0,15.5,16.0,16.5,17.0,17.5,18.0,18.5,19.0,19.5,20.0],
+                timeRange:[0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.0,12.5,13.0,13.5,14.0,14.5,15.0,15.5,16.0,16.5,17.0,17.5,18.0,18.5,19.0,19.5,20.0],
                 selectTime:null,
                 reportTimeType:{},
                 curDate:'',
@@ -2308,6 +2322,10 @@
             if(this.user.timeType.lockWorktime){
                 this.timeRange = this.timeRange.filter(item => {return item <= this.user.timeType.allday})
             }
+            //设置了下限
+            if (this.user.timeType.minReportTime) {
+                this.timeRange = this.timeRange.filter(item => {return item >= this.user.timeType.minReportTime})
+            }
 
             const that = this
             if(this.user.userNameNeedTranslate == 1) {
@@ -4174,6 +4192,7 @@
             // },
 
             showExportDialog() {
+                this.exportType = 0
                 this.exportDialog = true;
             },
             showExportTimeDialog() {
@@ -4746,6 +4765,31 @@
                     this.fillList = this.getUserMembListFromDeptList(list, 1)
                 } 
             },
+                  exportPushLog(){
+        this.http.post('/sap-sync-log/export',{},
+            res => {
+                if (res.code == "ok") {
+                    var filePath = res.data;
+                    var fName = '推送日志.xlsx'
+                    const a = document.createElement('a'); // 创建a标签
+                    a.setAttribute('download', fName);// download属性
+                    a.setAttribute('href', filePath);// href链接
+                    a.click(); //自执行点击事件
+                    a.remove();
+                } else {
+                    this.$message({
+                    message: res.msg,
+                    type: "error"
+                    });
+                }
+            },
+            error => {
+                this.$message({
+                    message: error,
+                    type: "error"
+                });
+            });
+      },
             theValues(id, item) {
                 for(var i in item) {
                     if(item[i].id == id) {
@@ -5302,10 +5346,10 @@
             },
             //导出日报
             exportReport() {
-                this.listLoading = true;
+                this.exportingData = true;
                 var param = {};
                 if (this.exportParam.dateRange != null) {
-                    param = {startDate:this.exportParam.dateRange[0], endDate: this.exportParam.dateRange[1]};
+                    param = {startDate:this.exportParam.dateRange[0], endDate: this.exportParam.dateRange[1], exportType: this.exportType};
                 }
                 if (this.exportParam.projectId != null) {
                     param.projectId = this.exportParam.projectId;
@@ -5315,9 +5359,10 @@
                 }
                 param.stateKey = this.stateKey
                 // param.departmentId = this.user.departmentId
+                console.log(param, '《=== 导出传的参数')
                 this.http.post( this.port.report.export, param,
                 res => {
-                    this.listLoading = false;
+                    this.exportingData = false;
                     if (res.code == "ok") {
                         location.href = res.data;
                         this.exportDialog = false;
@@ -5329,7 +5374,7 @@
                     }
                 },
                 error => {
-                    this.listLoading = false;
+                    this.exportingData = false;
                     this.$message({
                         message: error,
                         type: "error"

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

@@ -11,7 +11,7 @@
                     <vueCascader :size="'mini'" :widthStr="'125'" :clearable="true" :subject="option" :radios="false" :distinction="'1'" @vueCasader="vueCasader" v-if="user.userNameNeedTranslate == 1"></vueCascader>
                 </el-form-item>
 
-                <el-form-item :label="$t('ren-yuan')" style="width: 210px">
+                <el-form-item :label="'填报人'" style="width: 210px">
                     <el-select v-if="user.userNameNeedTranslate != '1'" v-model="search.userIdArray" :placeholder="$t('defaultText.pleaseChoose')" clearable @visible-change="usersSearch" @remove-tag="usersSearch(false)" @clear="usersSearch(false)" filterable="true" size="mini" style="width: 150px" multiple collapse-tags>
                         <el-option v-for="item in searchUsersList" :key="item.id" :label="item.name" :value="item.id">
                             <span style="float: left" v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName' :openid='item.name'></ww-open-data></span>
@@ -19,10 +19,21 @@
                         </el-option>
                     </el-select>
 
-                    <selectCat v-if="user.userNameNeedTranslate == '1'" :filterable="true" :size="'size'" :subject="searchUsersList" :clearable="true" :multiSelect="true" @selectCal="selectCal"></selectCat>
+                    <selectCat v-if="user.userNameNeedTranslate == '1'" :filterable="true" :size="'size'" :subject="searchUsersList" :clearable="true" :multiSelect="true" :distinction="'1'" @selectCal="selectCal"></selectCat>
                     <!-- <selectCat :size="'size'" :subject="searchUsersList" :clearable="true" :filterable="true" @selectCal="selectCal"></selectCat> -->
                 </el-form-item>
 
+                <el-form-item :label="'审核人'" style="width: 210px">
+                    <el-select v-if="user.userNameNeedTranslate != '1'" v-model="search.auditUserId" :placeholder="$t('defaultText.pleaseChoose')" clearable @change="usersSearch(false)" size="mini" style="width: 150px" collapse-tags>
+                        <el-option v-for="item in searchUsersList" :key="item.id" :label="item.name" :value="item.id">
+                            <span style="float: left" v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName' :openid='item.name'></ww-open-data></span>
+                            <span style="float: left" v-if="user.userNameNeedTranslate != '1'">{{item.name}}</span>
+                        </el-option>
+                    </el-select>
+
+                    <selectCat v-if="user.userNameNeedTranslate == '1'" :filterable="true" :size="'size'" :subject="searchUsersList" :clearable="true" :distinction="'2'" @selectCal="selectCal"></selectCat>
+                </el-form-item>
+
                 <el-form-item :label="$t('other.project')" style="width: 215px">
                     <el-select v-model="search.projectId" :placeholder="$t('defaultText.pleaseChoose')" clearable @change="getList()" filterable="true" size="mini" style="width: 175px" popper-class="projectSelectPopperClass">
                         <el-option v-for="item in projectList" :key="item.id" :label="item.projectName + item.projectCode" :value="item.id">
@@ -462,7 +473,8 @@
                     endDate: null,
                     state:0,
                     userId: null,
-                    userIdArray: []
+                    userIdArray: [],
+                    auditUserId: null
                 },
 
                 users: [],
@@ -498,7 +510,8 @@
                 approveinDialog: false,
                 isbatch: false,
                 defaultExpandAllFlg: false,
-                showTable: true
+                showTable: true,
+                projectList: []
             };
         },
         filters: {
@@ -899,7 +912,8 @@
                 this.http.post( this.port.project.list, {},
                 res => {
                     if (res.code == "ok") {
-                        this.projectList = res.data;
+                        console.log(res, '数据')
+                        this.$set(this, 'projectList', res.data);
                     } else {
                         this.$message({
                             message: res.msg,
@@ -1012,15 +1026,20 @@
             },
             selectCal(obj) {
                 console.log(obj, '过来的数据')
-                // search.userIdArray
-                let userListId = obj.arrUserList
-                let arr = []
-                for(var i in userListId) {
-                    arr.push(userListId[i].id)
+                if(obj.distinction == 1) {
+                    let userListId = obj.arrUserList
+                    let arr = []
+                    for(var i in userListId) {
+                        arr.push(userListId[i].id)
+                    }
+                    this.search.userIdArray = arr
+                    console.log(this.search.userIdArray, '数据看看')
+                    this.usersSearch(false)
+                } else if(obj.distinction == 2) {
+                    this.search.auditUserId = obj.id
+                    this.usersSearch(false)
                 }
-                this.search.userIdArray = arr
-                console.log(this.search.userIdArray, '数据看看')
-                this.usersSearch(false)
+                
             },
             defaultExpandAllFlgCli() {
                 this.defaultExpandAllFlg = !this.defaultExpandAllFlg

+ 1 - 0
fhKeeper/formulahousekeeper/timesheet_h5/package.json

@@ -17,6 +17,7 @@
     "css-loader": "^3.6.0",
     "dingtalk-jsapi": "^2.13.42",
     "echarts": "^4.9.0",
+    "element-ui": "^2.15.14",
     "font-awesome": "^4.7.0",
     "jquery": "^3.6.1",
     "pdfh5": "^1.4.2",

+ 6 - 0
fhKeeper/formulahousekeeper/timesheet_h5/src/components/Element.js

@@ -0,0 +1,6 @@
+import Vue from 'vue'
+import { Tree, Radio, Checkbox } from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css';
+Vue.use(Tree)
+Vue.use(Radio)
+Vue.use(Checkbox)

+ 1 - 0
fhKeeper/formulahousekeeper/timesheet_h5/src/main.js

@@ -13,6 +13,7 @@ import axios from 'axios'; /* 引入axios进行地址访问*/
 Vue.prototype.$http = axios;
 
 import "@/components/Vant";
+import './components/Element.js'
 
 import { Form , Toast , Grid, GridItem , DatetimePicker , Popover,
 Picker , Dialog , NumberKeyboard , Sticky , Skeleton ,

+ 7 - 0
fhKeeper/formulahousekeeper/timesheet_h5/src/router/index.js

@@ -210,6 +210,13 @@ const router = new Router({
         },
         component: () => import("@/views/exaLeave/awayOffice")
     },
+    {
+        path: "/editPerfect",
+        meta: {
+            title: "完善工号"
+        },
+        component: () => import("@/views/editPerfect/editPerfect")
+    },
     {
         path: "/clearStorage",
         meta: {

+ 12 - 3
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -546,7 +546,7 @@ export default {
             endTime: '18:00',
             nowTime: new Date(),
             showPickerHours: false,
-            timeRange: [0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0, 10.5, 11.0, 11.5, 12.5, 13.0, 13.5, 14.0, 14.5, 15.0],
+            timeRange: [],
             selectTime: null,
             reportTimeType: {},
             user: JSON.parse(localStorage.userInfo),
@@ -2522,8 +2522,17 @@ export default {
 
         this.today = this.format(new Date(), 'yyyy-MM-dd')
         this.timeRange = []
-        for (let i = 0.5; i <= 20; i += 0.5) {
-            this.timeRange.push(i)
+        let i = 0.0; 
+        while(true) {
+            if (i < 24) {
+                //校验上下限
+                if (i >= this.user.timeType.minReportTime && i <= this.user.timeType.maxReportTime) {
+                    this.timeRange.push(i);
+                }
+                i += 0.5;
+            } else {
+                break;
+            }
         }
         // console.log('user',this.user)
         var ua = navigator.userAgent.toLowerCase();

文件差异内容过多而无法显示
+ 2651 - 0
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit-02.vue


+ 202 - 43
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue

@@ -48,24 +48,29 @@
                 </template>
             </van-cell>
 
-            
             <!-- 每一周的数据循环 -->
             <div v-if="inbtn != 999">
                 <div class="form_domains" v-for="(item,index) in currentForm.domains" :key="item.id">
                     <div style="float:right;margin-top:10px;margin-right:10px;">
                     
-                    <van-tag v-if="index>0" color="#fff" 
+                    <van-tag v-if="index > 0 && item.state > 1" color="#fff" 
                     @click="delPro(index)" style="border: 1px solid #ff0000;padding:5px;margin-left:10px;"
                     icon="plus" type="default" ><span style="color:#666;padding: 0 5px;">删除</span></van-tag>
                     </div>
 
+                    <!-- 当前的状态 -->
+                    <div class="currentState" :style="`color: ${['#E6A23C', '#5CB87A'][item.state] || '#000'}`">
+                        {{ ['待审核', '已通过'][item.state] || '' }}
+                    </div>
+
                     <van-cell-group :title="(user.companyId==781?'任务':'项目') + (index+1)">
+
                         <!-- <div>请选择投入项目</div> -->
                         <!--按周填报的项目改成非必填-->
-                        <van-field  readonly  name="projectId" clickable :value="item.projectName" :label="user.companyId==781?'工作任务':'投入项目'" :placeholder="user.companyId==781?'请选择工作任务':'请选择项目'" @click="clickPicker(index, item)"
-                        />
+                        <van-field  readonly  name="projectId" clickable :value="item.projectName" :label="user.companyId==781?'工作任务':'投入项目'" :placeholder="user.companyId==781?'请选择工作任务':'请选择项目'" 
+                            @click="clickPicker(index, item)" :disabled="item.state<=1" />
                         <van-field  readonly  name="subProjectId" v-if="item.subProjectList != null && item.subProjectList.length > 0 && user.timeType.mainProjectState != 1" clickable 
-                            :value="item.subProjectName" label="子项目" placeholder="请选择子项目" 
+                            :value="item.subProjectName" label="子项目" placeholder="请选择子项目"  :disabled="item.state<=1"
                         @click="clickPickSubProject(index, item)" />
 
                         <van-popup v-model="item.showPickerSubProject" position="bottom">
@@ -75,14 +80,14 @@
                         <!--任务分组 -->
                         <van-field  readonly  name="groupId" v-if="user.company.packageProject==1&&item.taskGroups != null && item.taskGroups.length > 0" clickable 
                             :value="item.groupName" :label="user.timeType.enableNewWeeklyfill == 1 ? '分组' : '任务分组'" :placeholder="user.timeType.enableNewWeeklyfill == 1 ? '请选择分组' : '请选择任务分组'" 
-                        @click="clickPickTaskGroup(index, item)" />
+                        @click="clickPickTaskGroup(index, item)" :disabled="item.state<=1" />
                         <van-popup v-model="item.showPickerTaskGroup" position="bottom">
                             <van-picker show-toolbar :columns="item.taskGroups" value-key="name" @confirm="choseTaskGroup" 
                                 @cancel="item.showPickerTaskGroup = false;$forceUpdate();" />
                         </van-popup>
                         <!--任务阶段 -->
                         <van-field  readonly  name="stage" v-if="user.company.packageProject==1&&item.stages != null && item.stages.length > 0 && user.timeType.enableNewWeeklyfill != 1" clickable 
-                            :value="item.stage" label="投入阶段" placeholder="请选择投入阶段" 
+                            :value="item.stage" label="投入阶段" placeholder="请选择投入阶段"  :disabled="item.state<=1"
                         @click="clickPickStage(index, item)" />
                         <van-popup v-model="item.showPickerStage" position="bottom">
                             <van-picker show-toolbar :columns="item.stages" value-key="stagesName" @confirm="choseStage" 
@@ -90,7 +95,7 @@
                         </van-popup>
                         <!-- 预算来源 -->
                         <van-field  readonly  name="basecostId" v-if="user.company.packageProject==1&&reportBasecostList &&reportBasecostList.length>0" 
-                            :value="item.basecostName" label="预算来源" placeholder="请选择预算来源" 
+                            :value="item.basecostName" label="预算来源" placeholder="请选择预算来源" :disabled="item.state<=1"
                         @click="clickPickCostId(index, item)" />
                         <van-popup v-model="item.showPickerCostId" position="bottom">
                             <van-picker show-toolbar :columns="reportBasecostList" value-key="name" @confirm="choseCostId" 
@@ -99,7 +104,7 @@
                         <!-- 审核人 -->
                     <template v-if="user.timeType.reportAuditType != 3">
                         <van-field  readonly  name="projectAuditorId" v-if="item.auditUserList != null && item.auditUserList.length > 0" clickable
-                            :value="item.projectAuditorName" :label="user.companyId==781?'审核人':'项目审核人'" placeholder="请选择审核人" 
+                            :value="item.projectAuditorName" :label="user.companyId==781?'审核人':'项目审核人'" placeholder="请选择审核人"  :disabled="item.state<=1"
                         @click="clickPickAuditor(index, item)">
                             <template #input>
                                 <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName' :openid='item.projectAuditorName'></ww-open-data></span>
@@ -191,7 +196,7 @@
                         <!-- 全天上下午模式 -->
                         <div v-if="reportTimeType.multiWorktime==0">
                         <van-field v-if="reportTimeType.type < 2" readonly clickable  :value="reportTimeType.type==0?item.label:(parseFloat(item.workingTime).toFixed(1)+'h')" label="工作时长" placeholder="请选择工作时长(小时)" 
-                        @click="clickTimePicker(index, item)"
+                        @click="clickTimePicker(index, item)" :disabled="item.state<=1"
                         :rules="[{ required: true, message: '请选择工作时长' }]"/>
                         <van-popup v-model="showPickerTime" position="bottom">
                             <van-picker show-toolbar :columns="timeType"  value-key="label" @confirm="choseTimePick" @cancel="showPickerTime = false" />
@@ -206,7 +211,7 @@
 
                         <!-- 时间段选择模式 -->
                         <van-field readonly v-if="reportTimeType.type == 2" clickable name="datetimePicker" :value="item.startTime" label="开始时间" placeholder="点击选择时间" 
-                            @click="showStartTime = true"
+                            @click="timePickChange(item, 'showStartTime')" :disabled="item.state<=1"
                             :rules="[{ required: true, message: '请选择开始时间' }]"
                             />
                         <van-popup v-model="showStartTime" position="bottom">
@@ -221,7 +226,7 @@
                             <!-- :filter="filter" 原本这个属性在里面 -->
                         </van-popup>
                         <van-field v-if="reportTimeType.type == 2" readonly clickable name="datetimePicker" :value="item.endTime" label="结束时间" placeholder="点击选择时间" 
-                            @click="showEndTime = true"
+                            @click="timePickChange(item, 'showEndTime')" :disabled="item.state<=1"
                             :rules="[{ required: true, message: '请选择结束时间' }]" />
                         <van-popup v-model="showEndTime" position="bottom" >
                             <van-datetime-picker
@@ -238,7 +243,7 @@
                             <template >
                                 <div>
                             <span>用时占比</span>
-                            <van-slider :min="5" :step="5" style="width:120px;display:inline-block;margin-left:50px;" v-model="item.progress" :value="100" @change="item.workingTime = (reportTimeType.allday*item.progress/100).toFixed(1)" >
+                            <van-slider :min="5" :step="5" style="width:120px;display:inline-block;margin-left:50px;" :disabled="item.state<=1" v-model="item.progress" :value="100" @change="item.workingTime = (reportTimeType.allday*item.progress/100).toFixed(1)" >
                             <template #button>
                                 <div class="custom-button">{{ item.progress }}%</div>
                             </template>
@@ -261,16 +266,16 @@
                                 <!-- 时间段选择模式 -->
                                 <van-field readonly v-if="reportTimeType.type == 2" :clickable="true" name="datetimePicker" 
                                 :value="timeItem.startTime" label="开始时间" placeholder="点击选择时间" 
-                                :rules="[{ required: true, message: '必填项' }]"
+                                :rules="[{ required: true, message: '必填项' }]" :disabled="item.state<=1"
                                     @click="showStartDialog(timeItem)"  />
                                 
                                 <van-field v-if="reportTimeType.type == 2" readonly :clickable="true" name="datetimePicker" 
                                 :value="timeItem.endTime" label="结束时间" placeholder="点击选择时间" 
-                                :rules="[{ required: true, message: '必填项' }]"
+                                :rules="[{ required: true, message: '必填项' }]" :disabled="item.state<=1"
                                     @click="showEndDialog(timeItem)"  />
                                 
                                 <van-field class="form_input" style="color:#333;-webkit-text-fill-color:#646566;"
-                                
+                                    :disabled="item.state<=1"
                                     v-model="timeItem.content" name="content" type="textarea" label="工作事项" placeholder="请输入工作事项" 
                                     :rules="user.timeType.workContentState == 1 ? [{ required: true, message: '请填写工作事项' }] : null"
                                     rows="1" autosize  />
@@ -308,8 +313,8 @@
                         
                         <div class="overtime" v-if="((user.timeType.fillOvertime || (isWeekend && user.timeType.lockWorktime != 1)) || (isCorpWX&&canEdit)) && user.timeType.enableNewWeeklyfill != 1">
                             <div class="overTimeClas">
-                                <van-checkbox  v-model="item.isOvertime" style="width: 4.3rem;">加班</van-checkbox>
-                                <van-field v-model="item.overtimeHours" type="number" :disabled="item.isOvertime==null||item.isOvertime==0"
+                                <van-checkbox  v-model="item.isOvertime" :disabled="item.state<=1" style="width: 4.3rem;">加班</van-checkbox>
+                                <van-field v-model="item.overtimeHours" type="number" :disabled="item.isOvertime==null || item.isOvertime==0 || item.state<=1"
                                 placeholder="请输入加班时长" style="width: 5rem"></van-field>
                                 <span :class="'overListTime'">小时</span>    
                             </div>
@@ -366,8 +371,16 @@
             </div>
              
             <div class="form_btn" style="position:fixed; bottom:0px;width:100%;">
-                <div style="padding-bottom:10px;">
-                    <van-button square block type="info" @click="submitReport" native-type="submit" style="width:100%;float:left;">
+                <div style="padding-bottom:10px;" v-if="temporaryStorage">
+                    <van-button square block type="default" @click="submitReport(1)" native-type="submit" style="width:50%;float:left;">
+                        <div>暂存</div>
+                    </van-button>
+                    <van-button square block type="info" @click="submitReport(0)" native-type="submit" style="width:50%;float:right;">
+                        <div>提交</div>
+                    </van-button>
+                </div>
+                <div style="padding-bottom:10px;" v-if="!temporaryStorage">
+                    <van-button square block type="info" @click="submitReport(0)" native-type="submit" style="width:100%;float:right;">
                         <div>提交</div>
                     </van-button>
                 </div>
@@ -444,7 +457,7 @@
                 endTime: '18:00',
                 nowTime:new Date(),
                 showPickerHours: false,
-                timeRange:[0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.5,13.0,13.5,14.0,14.5,15.0],
+                timeRange:[],
                 selectTime:null,
                 reportTimeType:{},
                 user: JSON.parse(localStorage.userInfo),
@@ -516,9 +529,18 @@
                 },
                 integrationProjectList: [],
                 summary: '', // 周总结
+
+                temporaryStorage: false, // 是否开启暂存
             };
         },
         methods: {
+            // 时间选择
+            timePickChange(item, filed) {
+                if(item.state <= 1) {
+                    return
+                }
+                this[filed] = true
+            },
             // 获取地址上的参数
             getUrlKey(name) {
                 return (
@@ -612,7 +634,7 @@
             },
             // 切换星期
             switchWeek(item,index){
-                console.log(this.inbtn)
+                console.log(this.inbtn, this.form)
                 if(this.inbtn == 999) {
                     this.inbtn = index
                     return
@@ -626,6 +648,8 @@
                 }
                 this.getKaoqin()
                 this.getWorkTime()
+
+                this.getEachArray(this.currentForm)
             },
             // 切换按周
             switchWeekly(index) {
@@ -948,20 +972,27 @@
                     this.projectss = this.proads
                 }
             },
-            fZr(item,index) {
+            fZr(item, index, flag = false, newProIdx) {
+                console.log(flag, '《=== 回显')
+                if(flag) { // flag 为 true 时,表示回显数据
+                    this.proIdx = newProIdx
+                }
+
                 var domainItem = this.currentForm.domains[this.proIdx];
-                domainItem.projectId = item.id;
-                domainItem.projectName = item.projectName;
-                
-                //清空子项目
-                domainItem.subProjectId = null;
-                domainItem.subProjectName = null;
-                //清空任务
-                domainItem.taskId = null;
-                domainItem.taskName = null;
-                //清空分组和阶段
-                domainItem.stage = null;
-                domainItem.groupId = null;
+
+                if(!flag) { // 选择项目时清空,回显数据不做操作
+                    domainItem.projectId = item.id;
+                    domainItem.projectName = item.projectName;
+                    //清空子项目
+                    domainItem.subProjectId = null;
+                    domainItem.subProjectName = null;
+                    //清空任务
+                    domainItem.taskId = null;
+                    domainItem.taskName = null;
+                    //清空分组和阶段
+                    domainItem.stage = null;
+                    domainItem.groupId = null;
+                }
 
                 this.showPickerUserddp = false;
                 //获取子项目
@@ -1007,6 +1038,10 @@
                     .then(res => {
                         if(res.code == "ok") {
                             domainItem.subProjectList = res.data;
+                            const { subProjectId, subProjectName } = domainItem
+                            if(subProjectId && !subProjectName) {
+                                domainItem.subProjectName = res.data.filter(item => item.id == subProjectId)[0].name
+                            }
                         } 
                         this.$forceUpdate();
                     }).catch(err=> {this.$toast.clear();});
@@ -1503,6 +1538,9 @@
                 this.$forceUpdate();
             },
             clickPickTaskGroup(i, item) {
+                if(item.state <= 1) {
+                    return
+                }
                 this.clickIndex = i;
                 item.showPickerTaskGroup = true;
                 this.$forceUpdate();
@@ -1578,16 +1616,22 @@
                 this.$forceUpdate();
             },
 
-            choseTaskGroup(value, index) {
+            choseTaskGroup(value, index, flag = false, newClickIndex) {
                 if(!value){
                     return
                 }
+
+                if(flag) {
+                    this.clickIndex = newClickIndex
+                }
+
                 this.currentForm.domains[this.clickIndex].groupId = value.id;
                 this.currentForm.domains[this.clickIndex].groupName = value.name;
                 this.currentForm.domains[this.clickIndex].showPickerTaskGroup = false;
+                
                 var domainItem = this.currentForm.domains[this.clickIndex];
 
-                this.getGroupStages(this.currentForm.domains[this.clickIndex], index);
+                this.getGroupStages(this.currentForm.domains[this.clickIndex], index, flag);
                 
                 //检查当前的项目是否需要获取分组的负责人
                 var curProject = this.project.filter(p=>p.id == this.currentForm.domains[this.clickIndex].projectId)[0];
@@ -1616,11 +1660,13 @@
 
             },
 
-            getGroupStages(domain, index) {
+            getGroupStages(domain, index, flag = false) {
                 this.$axios.post("/stages/getProjectStagesByGroup", {groupId: domain.groupId})
                         .then(res => {
                             if(res.code == "ok") {
-                                domain.stage = '';
+                                if(!flag) {
+                                    domain.stage = '';
+                                }
                                 domain.stages = res.data;
                                 this.$forceUpdate();
                             } else {
@@ -1760,10 +1806,13 @@
             },
 
             // 提交日报
-            submitReport() {
+            submitReport(isDraft) {
                 if(this.inbtn != 999) {
                     this.form[this.inbtn] = this.currentForm
                 }
+                console.log(this.form)
+                console.log(this.currentForm)
+                // return
                 const { allday, workContentState, enableNewWeeklyfill, reportAuditType } = this.user.timeType // 系统设置的每日工作时间
                 // 针对物奇做的判断
                 if(this.user.timeType.enableNewWeeklyfill == 1){
@@ -1944,7 +1993,8 @@
                         }
                     }
 
-                    formData.append("draft", this.isDraft);
+                    // formData.append("draft", this.isDraft);
+                    formData.append("draft", isDraft);
                     //填字段
                     for(var i in this.form[formIndex].domains) {
                         //没有选择项目的,跳过
@@ -2432,9 +2482,101 @@
                 const day = newDate.getDate();
                 return `${year}/${month < 10 ? '0' + month : month}/${day < 10 ? '0' + day : day}`;
             },
+
+            // 获取按周填报的数据
+            async getWeeklyReportData() {
+                if(!this.temporaryStorage) {
+                    return
+                }
+                const { data } = await this.$axios.post("/report/getWeeklyReportData", { targetDate: this.dateText[0] })
+                const { dateList } = data
+                this.form =  this.handleWeeklyReportData(dateList)
+                this.currentForm = this.form[this.inbtn]
+                this.getEachArray(this.currentForm)
+            },
+            // 处理按周填报回显数据
+            handleWeeklyReportData(array) {
+                console.log(array, 'array')
+
+                let objectItem = {
+                    auditorFirst: {id: '', name: ''},
+                    auditorSec: {id: '', name: ''},
+                    auditorThird: {id: '', name: ''},
+                    ccUserid: {id: '', name: ''},
+                    content: '',
+                    degreeId: '',
+                    id: null,
+                    multiWorktime: 0,
+                    progress: 100,
+                    projectId: '',
+                    projectName: '',
+                    state: 2,
+                    workingTime: 8,
+                    worktimeList: []
+                }
+
+                let dataList = []
+                for(var i in array) {
+                    const arrayItem = array[i]
+                    let assignoBject = {
+                        createDate: arrayItem.date
+                    }
+                    if(arrayItem.reportList.length > 0) {
+                        let list = []
+                        for(var j in arrayItem.reportList) {
+                            const { 
+                                id,
+                                endTime, startTime, content, groupId, groupName,
+                                projectAuditorId, projectAuditorName, projectId,
+                                projectName, state, taskId, taskName, overtimeHours,
+                                stage, taskGroups, isOvertime, workingTime, subProjectId, progress
+                            } = arrayItem.reportList[j]
+
+                            let newObj = {
+                                ...objectItem, id,
+                                endTime, startTime, content, groupId, groupName,
+                                projectAuditorId, projectAuditorName, projectId,
+                                projectName, state, taskId, taskName, overtimeHours,
+                                stage, taskGroups, workingTime, subProjectId, progress,
+                                isOvertime: isOvertime == 1 ? true : false
+                            }
+                            list.push(newObj)
+                        }
+                        assignoBject.domains = JSON.parse(JSON.stringify(list))
+                    } else {
+                        assignoBject.domains = [JSON.parse(JSON.stringify(objectItem))]
+                    }
+                    dataList.push(assignoBject)
+                }
+
+                return dataList
+            },
+            // 获取回显数据的的各个数组(任务分组,阶段等)
+            getEachArray(arrItem) {
+                if(!this.temporaryStorage) {
+                    return
+                }
+                console.log(arrItem, '<=== 处理的数据')
+                let newArrItem = JSON.parse(JSON.stringify(arrItem))
+                const { domains } = newArrItem
+                for(let i in domains) {
+                    const { projectId, projectName, stage, groupId, groupName } = domains[i]
+                    if(projectId) {
+                        this.fZr({ projectId, projectName }, 0, true, i)
+                    }
+
+                    if(groupId) {
+                        this.choseTaskGroup({ id: groupId, name: groupName }, 0, true, i)
+                    }
+                }
+            }
         },
         
         mounted() {
+            const { companyId } = this.user
+            this.temporaryStorage = [4374, 10].includes(companyId)
+            console.log(this.temporaryStorage, '暂存权限', companyId)
+
             this.getUrlKey('date')
             const { enableNewWeeklyfill } = this.user.timeType // 针对物奇
             // if(enableNewWeeklyfill == 1) {
@@ -2445,8 +2587,17 @@
             //     }
             // }
             this.timeRange = []
-            for(let i=0.5; i<=20; i+=0.5){
-                this.timeRange.push(i)
+            let i = 0.0; 
+            while(true) {
+                if (i < 24) {
+                    //校验上下限
+                    if (i >= this.user.timeType.minReportTime && i <= this.user.timeType.maxReportTime) {
+                        this.timeRange.push(i);
+                    }
+                    i += 0.5;
+                } else {
+                    break;
+                }
             }
             this.getDateRange()
             var ua = navigator.userAgent.toLowerCase();
@@ -2478,6 +2629,9 @@
             //     this.form = JSON.parse(obj)
             //     localStorage.removeItem('formVal')
             // }
+
+            // 获取按周填报的数据
+            this.getWeeklyReportData()
         },
         beforeDestroy() {
             // localStorage.removeItem('formVal')
@@ -2486,6 +2640,11 @@
 </script>
 
 <style lang="less" scope>
+.currentState {
+    position: absolute;
+    top: 15px;
+    left: 112px;
+}
 .my-swipe .van-swipe-item {
   color: #fff;
   font-size: 20px;

+ 99 - 0
fhKeeper/formulahousekeeper/timesheet_h5/src/views/editPerfect/editPerfect.vue

@@ -0,0 +1,99 @@
+<template>
+    <div class='perfect'>
+        <div class="perfectTitle">完善工号</div>
+        <div class="perfectNumber">
+            <input type="text" v-model.trim="jobNumber" placeholder="请输入工号">
+        </div>
+        <div class="perfectBtn">
+            <van-button type="info" round :disabled="!jobNumber" @click="editPerfectJobNumber">确定</van-button>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: '',
+    components: {},
+    props: {},
+    data() {
+        return {
+            jobNumber: '',
+            user: JSON.parse(localStorage.userInfo)
+        }
+    },
+    computed: {},
+    watch: {},
+    created() { },
+    mounted() { },
+    methods: {
+        editPerfectJobNumber() {
+            const { id } = this.user
+            this.$axios.post("/user/updateUserJobNumber", {
+                id,
+                jobNumber: this.jobNumber
+            })
+            .then(res => {
+                if (res.code == "ok") {
+                    this.$toast.success('操作成功');
+                    let newUserInfo = {
+                        ...this.user,
+                        jobNumber: this.jobNumber
+                    }
+                    localStorage.setItem('userInfo', JSON.stringify(newUserInfo))
+                    this.$router.go(-1);
+                } else {
+                    this.$toast.fail(res.msg);
+                }
+            }).catch(err => {
+                this.$toast.fail(err);
+            });
+        }
+    },
+}
+</script>
+<style scoped lang='less'>
+.perfect {
+    width: 100%;
+    height: 100vh;
+    background: #fff;
+
+    .perfectTitle {
+        font-size: 30px;
+        padding-top: 20vh;
+        text-align: center;
+        color: #00a0e9;
+    }
+
+    .perfectNumber {
+        width: 100%;
+        display: flex;
+        justify-content: center;
+
+        input {
+            width: 80%;
+            height: 50px;
+            border: 1px solid #ccc;
+            border-radius: 5px;
+            margin-top: 8vh;
+            padding-left: 10px;
+            font-size: 16px;
+            border-radius: 50px;
+            text-align: center;
+        }
+    }
+
+    .perfectBtn {
+        width: 80%;
+        margin: 0 auto;
+
+        .van-button {
+            margin-top: 10vh;
+            width: 100%;
+            height: 50px;
+            border-radius: 50px;
+            background: #00a0e9;
+            color: #fff;
+        }
+    }
+}
+</style>

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

@@ -43,7 +43,8 @@
                 ],
                 routers: [],
                 key: 0,
-                isSyncData: false
+                isSyncData: false,
+                jobNumberCheckCompanyId: [936], // 定制需求,需要完善工号的公司id
             };
         },
         created() {
@@ -100,6 +101,12 @@
                     this.previewPicture()
                 }
             }
+
+            // 检查是否有工号
+            const { companyId, jobNumber } = this.user
+            if(this.jobNumberCheckCompanyId.includes(companyId) && !jobNumber) {
+                this.$router.push("/editPerfect");
+            }
         },
         components: {
             Footer
@@ -189,7 +196,7 @@
                         if(this.user.timeType.enableNewWeeklyfill != 1 && this.user.companyId != 4374) { // 针对新版按周填报去掉填写日报
                             this.routers.push({name: '填写日报',url: '/edit',icon: 'edit'})
                         }
-                        if (this.user.companyId != 3092) {
+                        if (this.user.companyId != 3092 && this.user.timeType.type != 0) {
                             this.routers.push({name: '按周填报',url: '/weekEdit',icon: 'records'})
                         }
                         if(jurisdictionNameList.some(item => item == '代填日报')) {
@@ -354,7 +361,6 @@
                             //去掉按周填报
                             this.routers = this.routers.filter(r=>r.name != '按周填报');
                         } 
-
                         // this.bindIfNessary();
                     } 
                 }).catch(err=> {

+ 266 - 13
fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue

@@ -4,9 +4,45 @@
 
         <div class="login_form">
             <van-sticky :offset-top="46">
-                <van-field readonly clickable name="datetimePicker" :value="nowTime" label="时间选择" placeholder="点击选择时间"
-                    @click="showPicker = true" />
+                <van-cell title="时间选择" clickable :value="nowTime" @click="showPicker = true" />
             </van-sticky>
+            <div v-if="user.manageDeptId != 0 || reportsCompany || reportsDept">
+                <van-sticky :offset-top="90">
+                    <van-cell title="选择部门" clickable :value="departmentText" @click="selectDepartmentShow = true">
+                        <template #extra>
+                            <van-icon v-if="departmentText" name="close" class="clearSeach"
+                                @click.stop="selectUserClear('dept')" />
+                        </template>
+                        <template #default>
+                            <span v-if="user.userNameNeedTranslate == '1'">
+                                <span v-if="departmentText">
+                                    <ww-open-data type='departmentName' :openid='departmentText'></ww-open-data>
+                                </span>
+                            </span>
+                            <span v-else>{{ departmentText }}</span>
+                        </template>
+                    </van-cell>
+                </van-sticky>
+                <van-sticky :offset-top="134" class="one_report_select">
+                    <van-cell title="选择人员" clickable :value="userNameValue" @click="selectUserShow = true"
+                        value-class="userNameValue">
+                        <template #extra>
+                            <van-icon v-if="selectPeopleVal.name" name="close" class="clearSeach"
+                                @click.stop="selectUserClear('user')" />
+                        </template>
+                        <template #default>
+                            <span v-if="user.userNameNeedTranslate == '1'">
+                                <span v-if="selectPeopleVal.name">
+                                    <ww-open-data type='userName' :openid='selectPeopleVal.name'></ww-open-data>
+                                </span>
+                            </span>
+                            <span v-else>{{ userNameValue }}</span>
+                        </template>
+                    </van-cell>
+                </van-sticky>
+            </div>
+
+
             <van-popup v-model="showPicker" position="bottom">
                 <van-datetime-picker v-model="currentDate" type="date" :min-date="minDate" :max-date="maxDate"
                     @confirm="changeTime" @cancel="showPicker = false" />
@@ -33,8 +69,8 @@
                         </span>
                     </div>
                     <div v-if="user.timeType.enableNewWeeklyfill == 1 && item.summary != null" style="margin-left:20px;"
-                         v-html="'<b>'+item.summaryTitle+'</b><br>'+item.summary.replace(/\r\n/g, '<br>')">
-                        
+                        v-html="'<b>' + item.summaryTitle + '</b><br>' + item.summary.replace(/\r\n/g, '<br>')">
+
                     </div>
                     <div v-for="(item1, index1) in item.data" class="one_report_data" :key="index1">
                         <div class="project_title" style="font-weight:bold;">项目:{{ item1.project }} <span
@@ -73,12 +109,16 @@
                         <div style="color:red;" v-if="item1.state == 2 && item1.rejectReason != null">原因:{{
                             item1.rejectReason }}
                         </div>
-                        <div class="project_title" v-if="item1.subProjectName != null && user.companyId != yuzhongCompId">子项目:{{ item1.subProjectName }}</div>
-                        <div class="project_title" v-if="user.companyId == yuzhongCompId" >角色:{{item1.extraField1?roleList.find(r=>r.value==item1.extraField1).label:''}}</div>
+                        <div class="project_title" v-if="item1.subProjectName != null && user.companyId != yuzhongCompId">
+                            子项目:{{ item1.subProjectName }}</div>
+                        <div class="project_title" v-if="user.companyId == yuzhongCompId">
+                            角色:{{ item1.extraField1 ? roleList.find(r => r.value == item1.extraField1).label : '' }}</div>
                         <div class="project_title" v-if="user.company.packageProject == 1 && item1.groupName != null">
                             任务分组:{{ item1.groupName }}</div>
-                        <div class="project_title" v-if="user.companyId == yuzhongCompId" >工作职责:{{item1.extraField2?item1.extraField2Name:''}}</div>
-                        <div class="project_title" v-if="user.companyId == yuzhongCompId" >工作内容:{{item1.extraField3?item1.extraField3Name:''}}</div>
+                        <div class="project_title" v-if="user.companyId == yuzhongCompId">
+                            工作职责:{{ item1.extraField2 ? item1.extraField2Name : '' }}</div>
+                        <div class="project_title" v-if="user.companyId == yuzhongCompId">
+                            工作内容:{{ item1.extraField3 ? item1.extraField3Name : '' }}</div>
                         <div class="project_title" v-if="user.company.packageProject == 1 && item1.stage != '-'">
                             投入阶段:{{ item1.stage }}</div>
                         <!--自定义维度 -->
@@ -149,16 +189,81 @@
             <van-empty v-if="report.length == 0" description="暂无日报">
                 <van-button round type="primary" class="bottom-button" @click="toWriteReport()">去填写</van-button>
             </van-empty>
+
+            <!-- 人员选择 -->
+            <van-popup v-model="selectUserShow" position="bottom" style="height: 90%">
+                <div class="popupDiv">
+                    <div class="popupSearch">
+                        <van-search v-model.trim="searchInputValue" placeholder="输入员工姓名搜索" @clear="userListSearch" @search="userListSearch"
+                            shape="round" background="#F4F4F4"></van-search>
+                    </div>
+
+                    <div class="popupCon conBorder" style="flex: 1;background-color: #fff;">
+                        <div class="popupConBox">
+                            <van-radio-group v-model="selectPeopleVal">
+                                <van-radio v-for="uitem in showUserList" :key="uitem.id" :name="uitem" style="padding:10px"
+                                    class="popupItem marginNone borderNone">
+                                    <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName'
+                                            :openid='uitem.name'></ww-open-data></span>
+                                    <span v-else>{{ uitem.name ? uitem.name : '' }}</span>
+                                </van-radio>
+                            </van-radio-group>
+                        </div>
+                    </div>
+
+                    <div class="popupBtn">
+                        <van-button style="width:100%;background: #1989fa;color: #ffffff;" round
+                            @click="selectUserConfirm()">确定</van-button>
+                    </div>
+                </div>
+            </van-popup>
+
+            <!-- 部门选择 -->
+            <van-popup v-model="selectDepartmentShow" position="bottom" style="height: 90%">
+                <div class="popupDiv">
+                    <div class="comPaceholder">
+                        已选择部门:
+                        <span v-if="user.userNameNeedTranslate != '1'">
+                            {{ selectDepartmentText.length > 0 ? selectDepartmentText[0].label : '请选择部门' }}
+                        </span>
+                        <span v-else>
+                            <span v-if="selectDepartmentText.length > 0">
+                                <ww-open-data type='departmentName' :openid='selectDepartmentText[0].label'></ww-open-data>
+                            </span>
+                            <span v-else>请选择部门</span>
+                        </span>
+                    </div>
+                    <div class="popupCon conBorder comTree" style="flex: 1;">
+                        <el-tree :data="departmentList" :props="defaultProps" @node-click="treeNodeClick">
+                            <span class="custom-tree-node" slot-scope="{ node }">
+                                <span v-if="user.userNameNeedTranslate == '1'">
+                                    <span>
+                                        <ww-open-data type='departmentName' :openid='node.label'></ww-open-data>
+                                    </span>
+                                </span>
+                                <span v-if="user.userNameNeedTranslate != '1'">
+                                    {{ node.label }}
+                                </span>
+                            </span>
+                        </el-tree>
+                    </div>
+                    <div class="popupBtn">
+                        <van-button style="width:100%;background: #1989fa;color: #ffffff;" round
+                            @click="treeBtn">确定</van-button>
+                    </div>
+                </div>
+            </van-popup>
         </div>
     </div>
 </template>
 
 <script>
 export default {
+    components: {},
     data() {
         return {
             yuzhongCompId: 3385,
-            roleList:[{value: 1,label: 'CRC&LM'},{value: 2,label: 'PM'}],
+            roleList: [{ value: 1, label: 'CRC&LM' }, { value: 2, label: 'PM' }],
             tmpPics: [],
             imgShow: false,
             hasWaiting: false,
@@ -173,6 +278,24 @@ export default {
             report: [],
             fullDayTxt: ['全天', '上午', '下午'],
             statusTxt: ["待审核", "已通过", "已驳回", "待提交"],
+            selectUserShow: false,
+            searchInputValue: '',
+            userList: '',
+            showUserList: '',
+            userIdList: '',
+            userNameValue: '',
+            selectPeopleVal: {},
+
+            selectDepartmentShow: false,
+            selectDepartmentText: [],
+            departmentText: '',
+            departmentList: [],
+            defaultProps: {
+                children: 'children',
+                label: 'label'
+            },
+            reportsCompany: false,
+            reportsDept: false
         };
     },
     created() {
@@ -182,12 +305,94 @@ export default {
             this.imgShow = true;
             this.tmpPics = item;
         },
-
         // 返回
         back() {
             history.back();
         },
+        getUsers() {
+            this.$axios.post("/user/getEmployeeList", {
+                departmentId: -1,
+                pageIndex: 1,
+                pageSize: -1
+            })
+                .then(res => {
+                    if (res.code == "ok") {
+                        this.userList = res.data.records;
+                        this.showUserList = res.data.records
+                    } else {
+                        this.$toast.fail('获取失败');
+                    }
+                }).catch(err => { this.$toast.clear(); });
+        },
+        getDepartmentList() {
+            this.$axios.post("/department/list", {})
+                .then(res => {
+                    if (res.code == "ok") {
+                        this.departmentList = res.data;
+                    } else {
+                        this.$toast.fail('获取失败');
+                    }
+                }).catch(err => { this.$toast.clear(); });
+        },
+        userListSearch(val) {
+            const { userNameNeedTranslate } = this.user
+            if(!this.searchInputValue) {
+                this.showUserList = JSON.parse(JSON.stringify(this.userList))
+                return
+            }
+
+            if (userNameNeedTranslate != 1) {
+                const newUserList = JSON.parse(JSON.stringify(this.userList))
+                this.showUserList = newUserList.filter(item => item.name.indexOf(this.searchInputValue) != -1)
+            }
+
+            if (userNameNeedTranslate == 1) {
+                this.$axios.post("/user/getEmployeeList", {
+                    departmentId: -1, pageIndex: 1, pageSize: 200,
+                    keyword: this.searchInputValue, status: '',
+                    roleId: '', cursor: '', onlyDirect: 0, matchingType: 0
+                })
+                    .then(res => {
+                        if (res.code == "ok") {
+                            const dataList = res.data.records
+                            const userNameList = dataList.map(item => item.name)
+                            const newUserList = JSON.parse(JSON.stringify(this.userList))
+                            this.showUserList = newUserList.filter(item => userNameList.some(uItem => uItem.includes(item.name)))
+                            console.log(userNameList)
+                        } else {
+                            this.$toast.fail('搜索失败');
+                        }
+                    }).catch(err => { this.$toast.clear(); });
+            }
+        },
+        selectUserConfirm() {
+            console.log(this.selectPeopleVal)
 
+            this.selectUserShow = false
+            this.getReport()
+        },
+        selectUserClear(str) {
+            if (str == 'user') {
+                this.selectPeopleVal = {}
+            }
+            if (str == 'dept') {
+                this.departmentText = '',
+                    this.selectDepartmentText = []
+            }
+            this.getReport()
+        },
+        treeNodeClick(item) {
+            this.selectDepartmentText = [item]
+        },
+        treeBtn() {
+            if (this.selectDepartmentText.length <= 0) {
+                this.$toast('请选择部门');
+                return
+            }
+            this.departmentText = this.selectDepartmentText[0].label
+            this.selectDepartmentShow = false
+            this.getReport()
+        },
         // 时间转换
         format(date, pattern) {
             pattern = pattern || "yyyy-MM-dd";
@@ -226,7 +431,16 @@ export default {
                 forbidClick: true,
                 duration: 0
             });
-            this.$axios.post("/report/getReportList", { date: this.nowTime })
+            let pames = {
+                date: this.nowTime,
+            }
+            if (this.selectPeopleVal.id) {
+                pames.userId = this.selectPeopleVal.id
+            }
+            if (this.departmentText && this.selectDepartmentText.length > 0) {
+                pames.deptId = this.selectDepartmentText[0].id
+            }
+            this.$axios.post("/report/getReportList", pames)
                 .then(res => {
                     if (res.code == "ok") {
                         this.$toast.clear();
@@ -247,7 +461,7 @@ export default {
         // 点击编辑
         editor(item) {
             var path = '/edit';
-            if(this.user.timeType.enableNewWeeklyfill == 1) {
+            if (this.user.timeType.enableNewWeeklyfill == 1) {
                 //物奇要填到按周填报
                 path = '/weekEdit';
             }
@@ -261,7 +475,7 @@ export default {
         // 去填写日报
         toWriteReport() {
             var path = '/edit';
-            if(this.user.timeType.enableNewWeeklyfill == 1) {
+            if (this.user.timeType.enableNewWeeklyfill == 1) {
                 //物奇要填到按周填报
                 path = '/weekEdit';
             }
@@ -278,7 +492,18 @@ export default {
             this.nowTime = sessionStorage.targetDate;
             sessionStorage.removeItem('targetDate');
         }
+        const { functionList } = this.user
+        for (var i in functionList) {
+            if (functionList[i].name == '查看全公司工时') {
+                this.reportsCompany = true
+            }
+            if (functionList[i].name == '查看本部门工时') {
+                this.查看本部门工时 = true
+            }
+        }
         this.getReport();
+        this.getUsers()
+        this.getDepartmentList()
     }
 };
 </script>
@@ -293,6 +518,10 @@ export default {
     font-size: 14px;
 }
 
+.one_report_select {
+    margin-bottom: 15px;
+}
+
 .form_text {
     margin: 15px 0 15px;
     padding: 0 12px;
@@ -314,6 +543,19 @@ export default {
         line-height: 30px;
     }
 }
+
+.comPaceholder {
+    margin: 10px 15px;
+    background: #fff;
+    padding: 10px 10px;
+    border-radius: 6px;
+    font-size: 14px;
+    color: #606266;
+}
+
+.comTree {
+    background: #ffffff;
+}
 </style>
 <style lang="less">
 .van-nav-bar .van-icon,
@@ -349,4 +591,15 @@ export default {
     background-color: rgb(53, 130, 245);
     border-color: rgb(53, 130, 245);
 }
+
+.clearSeach {
+    line-height: 0.64rem;
+    position: relative;
+    left: 5px;
+}
+
+.userNameValue {
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
 </style>

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

@@ -5,19 +5,19 @@ const themePath = path.resolve(__dirname,'src/assets/style/theme.less');
 const Timestamp = new Date().getTime();
 
 // var ip = '47.101.180.183'
-// var ip = '47.100.37.243'
+var ip = '47.100.37.243'
 // var ip = '192.168.2.7'
 // var ip = '127.0.0.1'
 
-var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
-for (var i in ifaces) {
-    for (var j in ifaces[i]) {
-        var val = ifaces[i][j]
-        if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
-            ip = val.address
-        }
-    }
-}
+// var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
+// for (var i in ifaces) {
+//     for (var j in ifaces[i]) {
+//         var val = ifaces[i][j]
+//         if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
+//             ip = val.address
+//         }
+//     }
+// }
 
 module.exports = {
     runtimeCompiler: true,