Преглед на файлове

车间加班申请功能
工时系统去掉美莱德代码

QuYueTing преди 4 дни
родител
ревизия
203719456b
променени са 42 файла, в които са добавени 26840 реда и са изтрити 2094 реда
  1. 1 1
      fhKeeper/formulahousekeeper/management-crm-qrcodeNew/src/main/java/com/management/collectdata/controller/WechatCallbackController.java
  2. 24704 1518
      fhKeeper/formulahousekeeper/management-crm/crm.log
  3. 0 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/constant/Constant.java
  4. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/GroupTemplateController.java
  5. 23 88
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java
  6. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/GroupTemplateService.java
  7. 26 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/GroupTemplateServiceImpl.java
  8. 0 24
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/InformationServiceImpl.java
  9. 1 166
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  10. 44 29
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TaskGroupServiceImpl.java
  11. 4 45
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  12. BIN
      fhKeeper/formulahousekeeper/management-platform/workTime.2025-11-08.log.gz
  13. 8 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/DepartmentController.java
  14. 49 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/OvertimeSettingController.java
  15. 375 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/WorkOvertimeController.java
  16. 54 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/OvertimeSetting.java
  17. 108 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/WorkOvertime.java
  18. 16 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/mapper/OvertimeSettingMapper.java
  19. 16 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/mapper/WorkOvertimeMapper.java
  20. 2 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/DepartmentService.java
  21. 16 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/OvertimeSettingService.java
  22. 16 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/WorkOvertimeService.java
  23. 90 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java
  24. 20 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/OvertimeSettingServiceImpl.java
  25. 11 24
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  26. 20 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/WorkOvertimeServiceImpl.java
  27. 292 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/util/ExcelUtil.java
  28. 18 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/OvertimeSettingMapper.xml
  29. 24 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/WorkOvertimeMapper.xml
  30. BIN
      fhKeeper/formulahousekeeper/management-workshop/workshop_print.2025-11-11.log.gz
  31. BIN
      fhKeeper/formulahousekeeper/management-workshop/workshop_print.2025-11-12.log.gz
  32. 4 0
      fhKeeper/formulahousekeeper/timesheet-workshop/src/permissions.js
  33. 37 66
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/team/index.vue
  34. 325 79
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/workOvertime/apply.vue
  35. 482 4
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/workOvertime/applyList.vue
  36. 25 4
      fhKeeper/formulahousekeeper/timesheet/src/components/taskComponent.vue
  37. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/centerManage/centerManage.vue
  38. 15 28
      fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue
  39. 4 3
      fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue
  40. 4 4
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  41. 1 1
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue
  42. 1 1
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue

+ 1 - 1
fhKeeper/formulahousekeeper/management-crm-qrcodeNew/src/main/java/com/management/collectdata/controller/WechatCallbackController.java

@@ -217,7 +217,7 @@ public class WechatCallbackController {
                         "<FromUserName><![CDATA[%s]]></FromUserName>" +
                         "<CreateTime>%d</CreateTime>" +
                         "<MsgType><![CDATA[text]]></MsgType>" +
-                        "<Content><![CDATA[感谢您的关注!]]></Content>" +
+                        "<Content><![CDATA[小慕得到您的关注深感荣幸,慕临研专注于上市后临床试验研究(含上市后SMO服务(CRC服务)、真实世界研究SMO服务、研究者发起临床研究SMO服务)与GCP培训业务,拥有800人左右临床团队,业务覆盖全国100余城市,商务对接人 邓总:18171268927,陈总:18101929003,刘总:13045093797]]></Content>" +
                         "</xml>",
                 root.elementText("FromUserName"),
                 root.elementText("ToUserName"),

Файловите разлики са ограничени, защото са твърде много
+ 24704 - 1518
fhKeeper/formulahousekeeper/management-crm/crm.log


+ 0 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/constant/Constant.java

@@ -60,7 +60,6 @@ public class Constant {
     public static final String[] LEAVE_CHECK= {"审核结果","审核人","请假时间","备注"};
     
     public static final int ZHE_ZHONG_COMPANY_ID=4811;
-    public static final int MLD_COMPANY_ID=876;
     //泓浒
     public static final int HONG_HU_COMPANY_ID=7536;
 }

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

@@ -102,9 +102,9 @@ public class GroupTemplateController {
     }
 
     @RequestMapping("/addTemplate")
-    public HttpRespMsg addTemplate(Integer groupId, String name, Boolean saveTask, Boolean saveMileStone, Boolean saveRisk,Boolean automatically) {
+    public HttpRespMsg addTemplate(Integer groupId, String name, Boolean saveTask, Boolean saveTaskFiles,  Boolean saveMileStone, Boolean saveRisk,Boolean automatically) {
         String uid = request.getHeader("Token");
-        return groupTemplateService.addTemplate(uid, groupId, name, saveTask, saveMileStone, saveRisk,automatically);
+        return groupTemplateService.addTemplate(uid, groupId, name, saveTask, saveTaskFiles, saveMileStone, saveRisk,automatically);
     }
 
     @RequestMapping("/deleteTemplate")

+ 23 - 88
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java

@@ -201,34 +201,13 @@ public class TaskController {
         HttpRespMsg msg = new HttpRespMsg();
         Company company = companyMapper.selectById(user.getCompanyId());
         WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
-        int isInsert=0;
-        int isUpdate=0;
         //新建的任务,需要设置创建人,创建时间
         if (task.getId() == null) {
-            isInsert=1;
             task.setCreateDate(LocalDate.now());
             task.setCreaterId(userId);
             task.setCreaterName(user.getName());
             task.setCreatorColor(user.getColor());
             task.setCompanyId(user.getCompanyId());
-
-            if (user.getCompanyId()==Constant.MLD_COMPANY_ID&&task.getIsTaskPlan()==0&&task.getCheckFirstId()==null){
-                if (task.getProjectId()!=null){
-                    Project project = projectMapper.selectById(task.getProjectId());
-                    task.setCheckFirstId(project.getInchargerId());
-                }
-            }
-
-            if (user.getCompanyId()==Constant.MLD_COMPANY_ID&&task.getIsTaskPlan()==1){
-                task.setTaskPlan(1);
-                task.setTaskStatus(3);
-                //状态是请假 直接变成任务
-                if (task.getTaskPlanType()==3){
-                    task.setIsTaskPlan(0);
-                    task.setTaskStatus(0);
-                    task.setTaskPlan(1);
-                }
-            }
         }
         if (!StringUtils.isEmpty(executorListStr)) {
             List<User> allUsers = userMapper.selectList(new QueryWrapper<User>().eq("company_id", user.getCompanyId()));
@@ -497,32 +476,30 @@ public class TaskController {
                 informationService.save(new Information().setType(1).setContent(String.valueOf(task.getProjectId())).setUserId(msgRecepient));
             });
             List<User> recpUserList = userMapper.selectList(new QueryWrapper<User>().in("id", msgRecepientList));
-            if(user.getCompanyId()!=Constant.MLD_COMPANY_ID||task.getIsTaskPlan()!=1) {
-                if (recpUserList.size() > 0) {
-                    if (recpUserList.get(0).getDingdingUserid() != null) {
-                        //钉钉用户
-                        CompanyDingding dingding = companyDingdingService.getOne(new QueryWrapper<CompanyDingding>().eq("company_id", user.getCompanyId()));
-                        LocalDate endDate = task.getEndDate();
-                        String endStr = "";
-                        if (endDate != null) {
-                            endStr = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(endDate);
-                        }
-                        companyDingdingService.sendNewTaskMsg(dingding, recpUserList.stream().map(User::getDingdingUserid).collect(Collectors.joining(",")),
-                                task.getName(), endStr);
-                    } else if (recpUserList.get(0).getCorpwxUserid() != null) {
-                        String corpUid = recpUserList.stream().map(User::getCorpwxUserid).distinct().collect(Collectors.joining("|"));
-                        JSONObject json = new JSONObject();
-                        JSONArray dataJson = new JSONArray();
-                        JSONObject jsonObj = new JSONObject();
-                        jsonObj.put("key", "任务内容");
-                        jsonObj.put("value", task.getName());
-                        dataJson.add(jsonObj);
-                        json.put("template_id", "tty9TkCAAAovv416zsWtn0e06CJ635HA");
-                        json.put("url", "https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww4e237fd6abb635af&redirect_uri=http://worktime.ttkuaiban.com/api/corpWXAuth&response_type=code&scope=snsapi_base&state=task#wechat_redirect");
-                        json.put("content_item", dataJson);
-                        //todo:发送消息提醒任务
-                        wxCorpInfoService.sendWXCorpTemplateMsg(wxCorpInfo, corpUid, json);
+            if (recpUserList.size() > 0) {
+                if (recpUserList.get(0).getDingdingUserid() != null) {
+                    //钉钉用户
+                    CompanyDingding dingding = companyDingdingService.getOne(new QueryWrapper<CompanyDingding>().eq("company_id", user.getCompanyId()));
+                    LocalDate endDate = task.getEndDate();
+                    String endStr = "";
+                    if (endDate != null) {
+                        endStr = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(endDate);
                     }
+                    companyDingdingService.sendNewTaskMsg(dingding, recpUserList.stream().map(User::getDingdingUserid).collect(Collectors.joining(",")),
+                            task.getName(), endStr);
+                } else if (recpUserList.get(0).getCorpwxUserid() != null) {
+                    String corpUid = recpUserList.stream().map(User::getCorpwxUserid).distinct().collect(Collectors.joining("|"));
+                    JSONObject json = new JSONObject();
+                    JSONArray dataJson = new JSONArray();
+                    JSONObject jsonObj = new JSONObject();
+                    jsonObj.put("key", "任务内容");
+                    jsonObj.put("value", task.getName());
+                    dataJson.add(jsonObj);
+                    json.put("template_id", "tty9TkCAAAovv416zsWtn0e06CJ635HA");
+                    json.put("url", "https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww4e237fd6abb635af&redirect_uri=http://worktime.ttkuaiban.com/api/corpWXAuth&response_type=code&scope=snsapi_base&state=task#wechat_redirect");
+                    json.put("content_item", dataJson);
+                    //todo:发送消息提醒任务
+                    wxCorpInfoService.sendWXCorpTemplateMsg(wxCorpInfo, corpUid, json);
                 }
             }
         }
@@ -1103,44 +1080,6 @@ public class TaskController {
         HttpRespMsg msg = new HttpRespMsg();
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
-        if (Constant.MLD_COMPANY_ID==user.getCompanyId()){
-            int count= projectLeaderMapper.selectCountIsLeader(id,user.getId());
-            //是这个计划的小组长
-            if (count>0){
-                /**
-                 * 任务状态,0-进行中 1-已完成 2-已撤销 3-待第一审核人审核 4-待第二审核人审核 5-第一审核人驳回  6-第二审核人驳回
-                 */
-                //待第一审核人审核
-                if (task.getTaskStatus()==3&&task.getIsTaskPlan()==1){
-                    msg.setError("当前计划已处于一级审核状态,小组长不能删除");
-                    return msg;
-                }else if(task.getTaskStatus()==4&&task.getIsTaskPlan()==1){
-                    msg.setError("当前计划已处于二级审核状态,小组长不能删除");
-                    return msg;
-                }else if(task.getTaskStatus()==0&&task.getIsTaskPlan()==0){
-                    msg.setError("当前计划已审核通过,小组长不能删除");
-                    return msg;
-                }
-            }
-
-            if (task.getCheckFirstId()!=null&&task.getCheckFirstId().equals(user.getId())){
-                if(task.getTaskStatus()==4&&task.getIsTaskPlan()==1){
-                    msg.setError("当前计划已处于二级审核状态,项目经理不能删除");
-                    return msg;
-                }else if(task.getTaskStatus()==0&&task.getIsTaskPlan()==0){
-                    msg.setError("当前计划已审核通过,项目经理不能删除");
-                    return msg;
-                }
-            }
-
-            if (task.getCheckSecondId()!=null&&task.getCheckSecondId().equals(user.getId())){
-                if(task.getTaskStatus()==3&&task.getIsTaskPlan()==1){
-                    msg.setError("当前计划已处于一级审核状态,区域经理不能删除");
-                    return msg;
-                }
-            }
-        }
-
         if (task.getParentTid() == null) {
             //删除的是第一级任务,需要调整顺序
             List<Task> afterList = taskService.list(new QueryWrapper<Task>().eq("stages_id", task.getStagesId()).isNull("parent_tid").gt("seq", task.getSeq()));
@@ -1489,10 +1428,6 @@ public class TaskController {
         if(pageIndex!=null&&pageSize!=null){
             pageStart = (pageIndex - 1) * pageSize;
         }
-        if (companyId==Constant.MLD_COMPANY_ID){
-            //美莱德 任务计划状态是1
-            queryWrapper.ne("is_task_plan",1);
-        }
         List<Task> list = taskMapper.getTaskWithProjectName(queryWrapper,pageStart, pageSize,companyId,branchDepartment);
         List<Integer> collect = list.stream().map(l -> l.getId()).distinct().collect(Collectors.toList());
         collect.add(-1);

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

@@ -13,5 +13,5 @@ import com.management.platform.util.HttpRespMsg;
  * @since 2021-05-05
  */
 public interface GroupTemplateService extends IService<GroupTemplate> {
-    public HttpRespMsg addTemplate(String token, Integer groupId, String name, Boolean saveTask, Boolean saveMileStone, Boolean saveRisk, Boolean automatically);
+    public HttpRespMsg addTemplate(String token, Integer groupId, String name, Boolean saveTask, Boolean saveTaskFiles, Boolean saveMileStone, Boolean saveRisk, Boolean automatically);
 }

+ 26 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/GroupTemplateServiceImpl.java

@@ -6,9 +6,12 @@ import com.management.platform.mapper.*;
 import com.management.platform.service.GroupTemplateService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.service.GroupTmpstagesService;
+import com.management.platform.service.GtemplateTaskFilesService;
 import com.management.platform.service.GtemplateTaskService;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MessageUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -46,9 +49,13 @@ public class GroupTemplateServiceImpl extends ServiceImpl<GroupTemplateMapper, G
     OperationRecordMapper operationRecordMapper;
     @Resource
     TaskMapper taskMapper;
+    @Autowired
+    private TaskFilesMapper taskFilesMapper;
+    @Autowired
+    private GtemplateTaskFilesService gtemplateTaskFilesService;
 
     @Override
-    public HttpRespMsg addTemplate(String token, Integer groupId, String name, Boolean saveTask, Boolean saveMileStone, Boolean saveRisk,Boolean automatically) {
+    public HttpRespMsg addTemplate(String token, Integer groupId, String name, Boolean saveTask,Boolean saveTaskFiles,  Boolean saveMileStone, Boolean saveRisk,Boolean automatically) {
         User user = userMapper.selectById(token);
         HttpRespMsg msg = new HttpRespMsg();
         QueryWrapper<GroupTemplate> templateQueryWrapper = new QueryWrapper<>();
@@ -95,7 +102,7 @@ public class GroupTemplateServiceImpl extends ServiceImpl<GroupTemplateMapper, G
                     System.out.println("耗时==="+(t2-t1));
                     List<Task> filterTaskList = taskList.stream().filter(t->(saveTask && t.getTaskType() == 0) || (saveMileStone && t.getTaskType() == 1)
                             || (saveRisk && t.getTaskType() == 2)).collect(Collectors.toList());
-                    List<GtemplateTask> gtemplateTaskList = new ArrayList<>();
+//                    List<GtemplateTask> gtemplateTaskList = new ArrayList<>();
                     if (filterTaskList.size() > 0) {
                         filterTaskList.forEach(f->{
                             System.out.println(f);
@@ -106,11 +113,26 @@ public class GroupTemplateServiceImpl extends ServiceImpl<GroupTemplateMapper, G
                                 String stagesName = first.get().getStagesName();
                                 Integer tmpSid = tmpstagesList.stream().filter(tmp->tmp.getStagesName().equals(stagesName)).findFirst().get().getId();
                                 item.setTstagesId(tmpSid);
-                                gtemplateTaskList.add(item);
+//                                gtemplateTaskList.add(item);
+                                gtemplateTaskMapper.insert(item);
+                                if (saveTaskFiles) {
+                                    //保存任务的文件到模板中
+                                    List<TaskFiles> taskFilesList = taskFilesMapper.selectList(new QueryWrapper<TaskFiles>().eq("task_id", f.getId()));
+                                    if (taskFilesList.size() > 0) {
+                                        List<GtemplateTaskFiles> filesList = new ArrayList<>();
+                                        for (TaskFiles taskFiles : taskFilesList) {
+                                            GtemplateTaskFiles gtemplateTaskFile = new GtemplateTaskFiles();
+                                            gtemplateTaskFile.setTplTaskId(item.getId());
+                                            BeanUtils.copyProperties(taskFiles, gtemplateTaskFile);
+                                            filesList.add(gtemplateTaskFile);
+                                        }
+                                        //保存到数据库
+                                        gtemplateTaskFilesService.saveBatch(filesList);
+                                    }
+                                }
                             }
                         });
                     }
-                    gtemplateTaskService.saveBatch(gtemplateTaskList);
                 }
             }
         }

+ 0 - 24
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/InformationServiceImpl.java

@@ -89,30 +89,6 @@ public class InformationServiceImpl extends ServiceImpl<InformationMapper, Infor
                     String newMsg = msg.replace(name, "$userName=" + userWxId + "$");
                     info.setMsg(newMsg);
                 }
-                if (Constant.MLD_COMPANY_ID==user.getCompanyId()&&info.getTaskId()!=null){
-                    Task task = taskService.getById(info.getTaskId());
-                    if (task!=null){
-                        GanttDataItem dataItem = new GanttDataItem();
-                        dataItem.setTaskStatus(task.getTaskStatus());
-
-                        if(countLeader>0){
-                            dataItem.setLeaderOrManager(1);
-                        } else if (countFirstCheck > 0 || countSecondCheck > 0) {
-                            dataItem.setLeaderOrManager(2);
-                        }
-                        dataItem.setCheckFirstId(task.getCheckFirstId());
-                        dataItem.setCheckSecondId(task.getCheckSecondId());
-                        dataItem.setObjType(2);
-                        dataItem.setIsTaskPlan(task.getIsTaskPlan());
-                        dataItem.setTaskPlan(task.getTaskPlan());
-
-                        DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-                        dataItem.setEnd_date(task.getEndDate()!=null ? task.getEndDate().format(customFormatter) : null);
-                        dataItem.setStart_date(task.getStartDate()!=null ? task.getStartDate().format(customFormatter) : null);
-                        info.setGanttData(dataItem);
-                    }
-
-                }
             }
             httpRespMsg.data = information;
         } catch (NullPointerException e) {

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

@@ -1799,18 +1799,6 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     if(first1.isPresent()){
                         projectVO.setProjectSeparate(first1.get());
                     }
-                }else if (companyId==Constant.MLD_COMPANY_ID){
-                    if (!leaderList.isEmpty()) {
-                        List<ProjectLeader> leaderCollect = leaderList.stream().filter(l ->l.getProjectId()!=null&& l.getProjectId().equals(project.getId())).collect(Collectors.toList());
-                        leaderCollect.forEach(l -> {
-                            Optional<User> userOptional = userList.stream().filter(u -> u.getId().equals(l.getLeaderId())).findFirst();
-                            if (userOptional.isPresent()) {
-                                User user1 = userOptional.get();
-                                l.setUserName(user1.getName());
-                            }
-                        });
-                        projectVO.setLeaderList(leaderCollect);
-                    }
                 }
 
                 //工程专业版:计算当前项目的总进度
@@ -2061,26 +2049,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     } else {
                         project.setCustomerName("");
                     }
-                    if (companyId==Constant.MLD_COMPANY_ID){
-                        if (leaderIds!=null&&leaderIds.length>0) {
-                            List<User> userManagers = userMapper.selectList(new QueryWrapper<User>()
-                                    .eq("role_name", "区域经理&PM").eq("company_id",companyId));
-                            for (String leaderId : leaderIds) {
-                                ProjectLeader leader = new ProjectLeader();
-                                leader.setProjectId(project.getId());
-                                leader.setLeaderId(leaderId);
-                                if (!userManagers.isEmpty()){
-                                    boolean b = userManagers.stream().anyMatch(u -> u.getId().equals(leaderId));
-                                    if (b){
-                                        httpRespMsg.setError("区域经理不能担任小组长");
-                                        return httpRespMsg;
-                                    }
-                                }
-                                leader.setCompanyId(companyId);
-                                leaderArrayList.add(leader);
-                            }
-                        }
-                    }
+
                     if (projectMapper.insert(project) == 0) {
                         //httpRespMsg.setError("操作失败");
                         httpRespMsg.setError(MessageUtils.message("other.operationFail"));
@@ -2092,17 +2061,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                             updateProjectKeyNodesData(projectKeyNodesData, project.getId());
                         }
 
-                    }if (companyId==Constant.MLD_COMPANY_ID) {
-                        if (leaderIds != null && leaderIds.length > 0) {
-                            leaderArrayList.forEach(l->l.setProjectId(project.getId()));
-                            projectLeaderService.saveBatch(leaderArrayList);
-                        }
                     }
                     id = project.getId();
-                    if(companyId==936){
-                        projectSeparate.setId(id);
-                        projectSeparateMapper.insert(projectSeparate);
-                    }
                     //项目管理专业版要自动生成任务分组
                     if (company.getPackageProject() == 1) {
                         taskGroupService.initGroup(companyId, id, user);
@@ -2333,14 +2293,6 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     //httpRespMsg.setError("操作失败");
                     httpRespMsg.setError(MessageUtils.message("other.operationFail"));
                 } else {
-                    if (Constant.MLD_COMPANY_ID==companyId){
-                        //项目经理换人,对应任务计划的第一审核人得换
-                        String inchargerId_old = oldProject.getInchargerId();
-                        if (!inchargerId.equals(inchargerId_old)){
-                            taskService.update(null,new UpdateWrapper<Task>().eq("project_id",oldProject.getId())
-                                    .eq("task_plan",1).set("check_first_id",inchargerId));
-                        }
-                    }
                     if (customerId == null) {
                         //去掉客户
                         projectMapper.removeProjectCustomer(id);
@@ -2384,28 +2336,6 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                             content+="\n"+s;
                         }
                     }
-                }else if (companyId==Constant.MLD_COMPANY_ID){
-                    projectLeaderService.remove(new QueryWrapper<ProjectLeader>().eq("project_id",p.getId()));
-                    List<User> userManagers = userMapper.selectList(new QueryWrapper<User>()
-                            .eq("role_name", "区域经理&PM").eq("company_id",companyId));
-                    if (leaderIds!=null&&leaderIds.length>0) {
-                        ArrayList<ProjectLeader> leaderArrayList = new ArrayList<>();
-                        for (String leaderId : leaderIds) {
-                            ProjectLeader leader = new ProjectLeader();
-                            leader.setProjectId(p.getId());
-                            leader.setLeaderId(leaderId);
-                            leader.setCompanyId(companyId);
-                            if (!userManagers.isEmpty()){
-                                boolean b = userManagers.stream().anyMatch(u -> u.getId().equals(leaderId));
-                                if (b){
-                                    httpRespMsg.setError("区域经理不能担任小组长");
-                                    return httpRespMsg;
-                                }
-                            }
-                            leaderArrayList.add(leader);
-                        }
-                        projectLeaderService.saveBatch(leaderArrayList);
-                    }
                 }
                 operationRecord.setContent(content);
                 //operationRecord.setModuleName("项目管理");
@@ -5091,63 +5021,6 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 String btLastItemId = null;
                 //按人员获取
                 ganttData = projectMapper.getTaskPlanByMemb(userIds, startDate ,endDate, user.getCompanyId(),user.getId(),justWaitForMe);
-                System.out.println("renyuan==>"+ganttData.size());
-                if (user.getCompanyId()==Constant.MLD_COMPANY_ID){
-                    List<ProjectLeader> leaderList = projectLeaderService.list(new QueryWrapper<ProjectLeader>().eq("leader_id", user.getId()).eq("company_id", user.getCompanyId()));
-                    //是小组长
-                    if (!leaderList.isEmpty()){
-                        List<Integer> projectIdList = leaderList.stream().map(ProjectLeader::getProjectId).collect(Collectors.toList());
-                        projectIdList.add(-1);
-                        List<Participation> participations = participationMapper.selectList(new QueryWrapper<Participation>().in("project_id", projectIdList));
-                        List<String> userProjectIds = participations.stream().distinct().map(Participation::getUserId).collect(Collectors.toList());
-                        userProjectIds.add("-1");
-                        userIdsExtra.addAll(userProjectIds);
-                        List<Map> taskPlanByGeneralMemb = projectMapper.getTaskPlanByGeneralMemb(userProjectIds, startDate, endDate, user.getCompanyId(), user.getId(),targetUserId,justWaitForMe);
-                        for (Map map : taskPlanByGeneralMemb) {
-                            map.put("leaderOrManager",1);
-                        }
-                        List<Map> taskPlanWithLeave = projectMapper.getTaskPlanWithLeave(null, startDate, endDate, user.getCompanyId(), user.getId(), targetUserId);
-                        for (Map map : taskPlanWithLeave) {
-                            map.put("leaderOrManager",1);
-                        }
-                        ganttData.addAll(taskPlanByGeneralMemb);
-                        ganttData.addAll(taskPlanWithLeave);
-                        System.out.println("renyuan0==>"+taskPlanByGeneralMemb.size());
-                        System.out.println("renyuan1==>"+taskPlanWithLeave.size());
-                    }
-                    //找到自己担任项目经理的项目,: is_task_plan==1 ,checkFirstId=自己的id 并且 task_status=3
-                    List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().eq("incharger_id", user.getId()));
-                    if (!projectList.isEmpty()){
-                        List<Integer> projectIdList = projectList.stream().map(Project::getId).collect(Collectors.toList());
-                        projectIdList.add(-1);
-                        List<TaskExecutor> executorList = taskExecutorService.list(new QueryWrapper<TaskExecutor>().in("project_id", projectIdList).isNotNull("executor_id"));
-                        List<String> collectUserIdList = executorList.stream().distinct().map(TaskExecutor::getExecutorId).collect(Collectors.toList());
-                        collectUserIdList.add("-1");
-                        userIdsExtra.addAll(collectUserIdList);
-                        List<Map> getTaskPlanByProManager = projectMapper.getTaskPlanByProManager(collectUserIdList, startDate, endDate, user.getCompanyId(),user.getId(),targetUserId,justWaitForMe);
-                        for (Map map : getTaskPlanByProManager) {
-                            map.put("leaderOrManager",2);
-                        }
-                        System.out.println("renyuan2==>"+getTaskPlanByProManager.size());
-                        ganttData.addAll(getTaskPlanByProManager);
-                    }
-
-                    if (user.getRoleName().equals("区域经理&PM")){
-                        List<Task> taskList = taskService.list(new QueryWrapper<Task>().eq("check_second_id", user.getId()));
-                        List<Integer> taskIdList = taskList.stream().map(Task::getId).collect(Collectors.toList());
-                        taskIdList.add(-1);
-                        List<TaskExecutor> executorList = taskExecutorService.list(new QueryWrapper<TaskExecutor>().in("task_id", taskIdList).isNotNull("executor_id"));
-                        List<String> collectUserIdList = executorList.stream().distinct().map(TaskExecutor::getExecutorId).collect(Collectors.toList());
-                        collectUserIdList.add("-1");
-                        userIdsExtra.addAll(collectUserIdList);
-                        List<Map> getTaskPlanByProManager = projectMapper.getTaskPlanByAreaManager(collectUserIdList, startDate, endDate, user.getCompanyId(),user.getId(),targetUserId,justWaitForMe);
-                        for (Map map : getTaskPlanByProManager) {
-                            map.put("leaderOrManager",2);
-                        }
-                        System.out.println("renyuan3==>"+getTaskPlanByProManager.size());
-                        ganttData.addAll(getTaskPlanByProManager);
-                    }
-                }
                 QueryWrapper<LeaveSheet> lsQueryWrapper=new QueryWrapper();
                 lsQueryWrapper.in("owner_id", userIds);
                 if (startDate != null && endDate != null) {
@@ -5337,39 +5210,6 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     }
                 }
                 ganttData = projectMapper.getTaskPlanByProject(projectIds, startDate ,endDate, user.getCompanyId(),groupName,taskType,user.getId(),justWaitForMe);
-                System.out.println("ganttData1:"+ganttData.size());
-                if (user.getCompanyId()==Constant.MLD_COMPANY_ID){
-                    List<ProjectLeader> leaderList = projectLeaderService.list(new QueryWrapper<ProjectLeader>().eq("leader_id", user.getId()).eq("company_id", user.getCompanyId()));
-                    //是小组长
-                    if (!leaderList.isEmpty()){
-                        List<Integer> projectIdList = leaderList.stream().map(ProjectLeader::getProjectId).collect(Collectors.toList());
-                        projectIdList.add(-1);
-                        List<Map> taskPlanByGeneralMemb = projectMapper.getTaskPlanByProjectGeneralMemb(projectIdList,startDate ,endDate, user.getCompanyId(),user.getId(),groupName,taskType,targetProjectId,justWaitForMe);
-                        System.out.println("ganttData2:"+taskPlanByGeneralMemb.size());
-                        ganttData.addAll(taskPlanByGeneralMemb);
-                    }
-                    //找到自己担任项目经理的项目,: is_task_plan==1 ,checkFirstId=自己的id 并且 task_status=3
-                    List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().eq("incharger_id", user.getId()));
-                    if (!projectList.isEmpty()){
-                        List<Integer> projectIdList = projectList.stream().map(Project::getId).collect(Collectors.toList());
-                        projectIdList.add(-1);
-                        List<Map> taskPlanByProjectManager = projectMapper.getTaskPlanByProjectManager(projectIdList,startDate ,endDate, user.getCompanyId(),user.getId(),groupName,taskType,targetProjectId,justWaitForMe);
-                        System.out.println("ganttData2:"+taskPlanByProjectManager.size());
-                        ganttData.addAll(taskPlanByProjectManager);
-                    }
-
-                    if (user.getRoleName().equals("区域经理&PM")){
-                        List<Task> taskList = taskService.list(new QueryWrapper<Task>().eq("check_second_id", user.getId()));
-                        List<Integer> taskIdList = taskList.stream().map(Task::getId).collect(Collectors.toList());
-                        taskIdList.add(-1);
-                        List<TaskExecutor> executorList = taskExecutorService.list(new QueryWrapper<TaskExecutor>().in("task_id", taskIdList).isNotNull("executor_id"));
-                        List<Integer> projectIdList = executorList.stream().distinct().map(TaskExecutor::getProjectId).collect(Collectors.toList());
-                        projectIdList.add(-1);
-                        List<Map> taskPlanByProjectAreaManager = projectMapper.getTaskPlanByProjectAreaManager(projectIdList, startDate, endDate, user.getCompanyId(),user.getId(),groupName,taskType,targetProjectId,justWaitForMe);
-                        System.out.println("ganttData2:"+taskPlanByProjectAreaManager.size());
-                        ganttData.addAll(taskPlanByProjectAreaManager);
-                    }
-                }
                 QueryWrapper<BusinessTrip> btQueryWrapper =new QueryWrapper<>();
                 QueryWrapper<BustripProject> bpQueryWrapper =new QueryWrapper<>();
                 btQueryWrapper.in("owner_id", userIds);
@@ -9040,11 +8880,6 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             List<String> userIds = new ArrayList<>();
 
             List<Integer> proIds = projectList.stream().map(Project::getId).collect(Collectors.toList());
-            if (Constant.MLD_COMPANY_ID==user.getCompanyId()){
-                List<Integer> projectSelect =projectMapper.getRelatedProjectIds(user.getId(), user.getCompanyId());
-                proIds.addAll(projectSelect);
-            }
-
             proIds.add(-1);
             List<Participation> pList = participationMapper.selectList(new QueryWrapper<Participation>().in("project_id", proIds));
             userIds = pList.stream().map(Participation::getUserId).collect(Collectors.toList());

+ 44 - 29
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TaskGroupServiceImpl.java

@@ -6,13 +6,12 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.entity.*;
 import com.management.platform.entity.vo.setTemplate;
 import com.management.platform.mapper.*;
-import com.management.platform.service.StagesService;
-import com.management.platform.service.TaskExecutorService;
-import com.management.platform.service.TaskGroupService;
-import com.management.platform.service.TaskService;
+import com.management.platform.service.*;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.ListUtil;
 import com.management.platform.util.MessageUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
@@ -56,6 +55,15 @@ public class TaskGroupServiceImpl extends ServiceImpl<TaskGroupMapper, TaskGroup
     private ProjectMapper projectMapper;
     @Resource
     private OperationRecordMapper operationRecordMapper;
+    @Autowired
+    private TaskMapper taskMapper;
+    @Autowired
+    private GtemplateTaskFilesMapper gtemplateTaskFilesMapper;
+    @Autowired
+    private TaskFilesService taskFilesService;
+    @Autowired
+    private TaskFilesMapper taskFilesMapper;
+
     @Override
     public void saveGroupIncharger(TaskGroup taskGroup,User user) {
         if (StringUtils.isEmpty(taskGroup.getInchargerId())) {
@@ -113,7 +121,7 @@ public class TaskGroupServiceImpl extends ServiceImpl<TaskGroupMapper, TaskGroup
                         new QueryWrapper<GtemplateTask>().eq("gtemplate_id", template.getId())
                                 .orderByAsc("seq"));
                 if (gtemplateTaskList.size() > 0) {
-                    List<Task> taskList = new ArrayList<>();
+//                    List<Task> taskList = new ArrayList<>();
 //                List<TaskExecutor> taskExecutorList = new ArrayList<>();
                     gtemplateTaskList.forEach(gt->{
                         Task task = gt.toTask();
@@ -125,28 +133,22 @@ public class TaskGroupServiceImpl extends ServiceImpl<TaskGroupMapper, TaskGroup
                         task.setCreaterId(user.getId());
                         task.setCreaterName(user.getName());
                         task.setCreatorColor(user.getColor());
-//                    if(task.getTaskType()==1 && inchargerUser != null){
-//                        task.setExecutorId(inchargerUser.getId());
-//                        task.setExecutorName(inchargerUser.getName());
-//                        task.setExecutorColor(inchargerUser.getColor());
-//                    }
-
-                        taskList.add(task);
+//                        taskList.add(task);
+                        taskMapper.insert(task);
+                        //生成任务文件
+                        List<GtemplateTaskFiles> filesList = gtemplateTaskFilesMapper.selectList(new QueryWrapper<GtemplateTaskFiles>().eq("tpl_task_id", gt.getId()));
+                        if (filesList.size() > 0) {
+                            List<TaskFiles> saveFilesList = new ArrayList<>();
+                            for (GtemplateTaskFiles fromFile : filesList) {
+                                TaskFiles toFile = new TaskFiles();
+                                BeanUtils.copyProperties(fromFile, toFile);
+                                toFile.setTaskId(task.getId());
+                                saveFilesList.add(toFile);
+                            }
+                            taskFilesService.saveBatch(saveFilesList);
+                        }
                     });
-                    taskService.saveBatch(taskList);
-//                taskList.forEach(tl->{
-//                    TaskExecutor taskExecutor=new TaskExecutor();
-//                    //当为里程碑任务时
-//                    if(tl.getTaskType()==1 && inchargerUser != null){
-//                        taskExecutor.setTaskId(tl.getId());
-//                        taskExecutor.setExecutorId(inchargerUser.getId());
-//                        taskExecutor.setExecutorName(inchargerUser.getName());
-//                        taskExecutor.setExecutorColor(inchargerUser.getColor());
-//                        taskExecutor.setProjectId(projectId);
-//                        taskExecutorList.add(taskExecutor);
-//                    }
-//                });
-//                taskExecutorService.saveBatch(taskExecutorList);
+//                    taskService.saveBatch(taskList);
                 }
             }
         }else {
@@ -235,7 +237,7 @@ public class TaskGroupServiceImpl extends ServiceImpl<TaskGroupMapper, TaskGroup
                         new QueryWrapper<GtemplateTask>().eq("gtemplate_id", groupTemplate.getId())
                                 .orderByAsc("seq"));
                 if (gtemplateTaskList.size() > 0) {
-                    List<Task> taskList = new ArrayList<>();
+//                    List<Task> taskList = new ArrayList<>();
                     gtemplateTaskList.forEach(gt->{
                         Task task = gt.toTask();
                         task.setProjectId(projectId);
@@ -246,9 +248,22 @@ public class TaskGroupServiceImpl extends ServiceImpl<TaskGroupMapper, TaskGroup
                         task.setCreaterId(user.getId());
                         task.setCreaterName(user.getName());
                         task.setCreatorColor(user.getColor());
-                        taskList.add(task);
+//                        taskList.add(task);
+                        taskMapper.insert(task);
+                        //生成任务文件
+                        List<GtemplateTaskFiles> filesList = gtemplateTaskFilesMapper.selectList(new QueryWrapper<GtemplateTaskFiles>().eq("tpl_task_id", gt.getId()));
+                        if (filesList.size() > 0) {
+                            List<TaskFiles> saveFilesList = new ArrayList<>();
+                            for (GtemplateTaskFiles fromFile : filesList) {
+                                TaskFiles toFile = new TaskFiles();
+                                BeanUtils.copyProperties(fromFile, toFile);
+                                toFile.setTaskId(task.getId());
+                                saveFilesList.add(toFile);
+                            }
+                            taskFilesService.saveBatch(saveFilesList);
+                        }
                     });
-                    taskService.saveBatch(taskList);
+//                    taskService.saveBatch(taskList);
                 }
             }
         }

+ 4 - 45
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java

@@ -295,12 +295,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
                         LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
                 //检测是否是项目审核人,有没有权限进行审核
                 userVO.setLeader(judgeIsLeader(userVO.getId()));
-
-                if(company.getId()==Constant.MLD_COMPANY_ID) {
-                    //检测项目角色
-                    userVO.setProjectLeaderType(judgeIsProjectLeader(userVO.getId(),company.getId()));
-                }
-
                 userVO.setTimeType(timeTypeMapper.selectById(company.getId()));
                 List<Department> manageDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("manager_id", userVO.getId()));
                 List<Integer> deptIds = manageDeptList.stream().map(Department::getDepartmentId).collect(Collectors.toList());
@@ -2506,11 +2500,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         userVO.setHasAuditDept(num>0);
         //获取当前角色的权限菜单
         setUserRoleMenu(userVO);
-
-        if(company.getId()==Constant.MLD_COMPANY_ID) {
-            //检测项目角色
-            userVO.setProjectLeaderType(judgeIsProjectLeader(userVO.getId(),company.getId()));
-        }
         httpRespMsg.data = userVO;
         return httpRespMsg;
     }
@@ -2808,23 +2797,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         HttpRespMsg msg = new HttpRespMsg();
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
-        if (user.getCompanyId() != Constant.MLD_COMPANY_ID) {
-            msg.setData(new ArrayList<User>());
-            return msg;
-        } else {
-
-            List<SysRole> sysRoles = sysRoleMapper.selectList(new QueryWrapper<SysRole>().eq("company_id", user.getCompanyId()).eq("rolename", "项目经理"));
-            if (!sysRoles.isEmpty()) {
-                List<User> userList = userMapper.selectList(new QueryWrapper<User>()
-                        .eq("company_id", user.getCompanyId())
-                        .eq("is_active", 1)
-                        .eq("role_id", sysRoles.get(0).getId()));
-                msg.setData(userList);
-            } else {
-                msg.setData(new ArrayList<User>());
-            }
-            return msg;
-        }
+        msg.setData(new ArrayList<User>());
+        return msg;
     }
 
     @Override
@@ -2832,23 +2806,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         HttpRespMsg msg = new HttpRespMsg();
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
-        if (user.getCompanyId() != Constant.MLD_COMPANY_ID) {
-            msg.setData(new ArrayList<User>());
-            return msg;
-        } else {
-
-            List<SysRole> sysRoles = sysRoleMapper.selectList(new QueryWrapper<SysRole>().eq("company_id", user.getCompanyId()).eq("rolename", "区域经理&PM"));
-            if (!sysRoles.isEmpty()) {
-                List<User> userList = userMapper.selectList(new QueryWrapper<User>()
-                        .eq("company_id", user.getCompanyId())
-                        .eq("is_active", 1)
-                        .eq("role_id", sysRoles.get(0).getId()));
-                msg.setData(userList);
-            } else {
-                msg.setData(new ArrayList<User>());
-            }
-            return msg;
-        }
+        msg.setData(new ArrayList<User>());
+        return msg;
     }
 
     @Override

BIN
fhKeeper/formulahousekeeper/management-platform/workTime.2025-11-08.log.gz


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

@@ -63,6 +63,14 @@ public class DepartmentController {
         return departmentService.getDepartmentUserList(request);
     }
 
+    /**
+     *
+     */
+    @RequestMapping("/userListInMyRange")
+    public HttpRespMsg userListInMyRange(HttpServletRequest request) {
+        return departmentService.userListInMyRange(request);
+    }
+
     /**
      * 对部门进行排序
      * @param request

+ 49 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/OvertimeSettingController.java

@@ -0,0 +1,49 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.OvertimeSetting;
+import com.management.platform.service.OvertimeSettingService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-11-20
+ */
+@RestController
+@RequestMapping("/overtime-setting")
+public class OvertimeSettingController {
+    @Resource
+    private OvertimeSettingService overtimeSettingService;
+
+    @RequestMapping("/addOrUpdate")
+    public HttpRespMsg addOrUpdate(OvertimeSetting setting) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = overtimeSettingService.saveOrUpdate(setting);
+        return msg;
+    }
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(Integer pageIndex, Integer pageSize, Integer applicantId, String employeeIds, String startDate, String endDate) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = overtimeSettingService.list();
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = overtimeSettingService.removeById(id);
+        return msg;
+    }
+
+}
+

+ 375 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/WorkOvertimeController.java

@@ -0,0 +1,375 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.management.platform.entity.Company;
+import com.management.platform.entity.Department;
+import com.management.platform.entity.OvertimeSetting;
+import com.management.platform.entity.User;
+import com.management.platform.entity.WorkOvertime;
+import com.management.platform.mapper.CompanyMapper;
+import com.management.platform.mapper.DepartmentMapper;
+import com.management.platform.mapper.OvertimeSettingMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.OvertimeSettingService;
+import com.management.platform.service.WorkOvertimeService;
+import com.management.platform.util.ExcelUtil;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.WorkDayCalculateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-11-20
+ */
+@RestController
+@RequestMapping("/work-overtime")
+public class WorkOvertimeController {
+    @Resource
+    private WorkOvertimeService workOvertimeService;
+    @Autowired
+    private HttpServletRequest request;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private CompanyMapper companyMapper;
+    @Resource
+    private DepartmentMapper departmentMapper;
+    @Resource
+    private OvertimeSettingMapper overtimeSettingMapper;
+    
+    @Value(value = "${upload.path}")
+    private String path;
+
+    @RequestMapping("/addOrUpdate")
+    public HttpRespMsg addOrUpdate(WorkOvertime workOvertime) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        workOvertime.setApplicant(token);
+        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        if (WorkDayCalculateUtils.isWorkDay(workOvertime.getWorkDate())) {
+            //工作日禁止填报
+            msg.setError("工作日禁止填报");
+            return msg;
+        }
+
+        //判断是否有员工已经存在申请的记录
+        String[] ids = workOvertime.getEmployeeIds().split(",");
+        for (int i = 0; i < ids.length; i++) {
+            QueryWrapper<WorkOvertime> queryWrapper = new QueryWrapper<>();
+            queryWrapper.like("employee_ids", ids[i]);
+            queryWrapper.eq("work_date", workOvertime.getWorkDate());
+            if (workOvertimeService.list(queryWrapper).size() > 0) {
+                msg.setError("员工["+userMapper.selectById(ids[i]).getName()+"]已经存在"+ dtf.format(workOvertime.getWorkDate())+"的加班申请");
+                return msg;
+            }
+        }
+        msg.data = workOvertimeService.saveOrUpdate(workOvertime);
+        return msg;
+    }
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(String applicant, 
+                           String employeeIds, 
+                           String startDate, 
+                           String endDate,
+                           String mealType,
+                           Integer page,
+                           Integer size) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+
+        // 使用MyBatis-Plus的条件构造器进行查询
+        QueryWrapper<WorkOvertime> queryWrapper = new QueryWrapper<>();
+
+        User targetUser = userMapper.selectById(token);
+        List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", targetUser.getCompanyId()));
+        //非管理员只能看到自己的
+        if (!targetUser.getRoleName().equals("超级管理员") && !targetUser.getRoleName().equals("系统管理员")) {
+            applicant = token;
+        }
+        // 按申请人过滤
+        if (applicant != null && !applicant.trim().isEmpty()) {
+            queryWrapper.eq("applicant", applicant);
+        }
+
+        // 按员工过滤
+        if (employeeIds != null && !employeeIds.trim().isEmpty()) {
+            queryWrapper.like("employee_ids", employeeIds);
+        }
+        
+        // 按日期范围过滤
+        if (startDate != null && !startDate.trim().isEmpty()) {
+            queryWrapper.ge("work_date", LocalDate.parse(startDate));
+        }
+        if (endDate != null && !endDate.trim().isEmpty()) {
+            queryWrapper.le("work_date", LocalDate.parse(endDate));
+        }
+        if (!StringUtils.isEmpty(mealType)) {
+            queryWrapper.like("meal_type", mealType);
+        }
+        // 按时间倒序排列
+        queryWrapper.orderByDesc("work_date", "id");
+        
+        // 分页查询
+        if (page != null && size != null && page > 0 && size > 0) {
+            Page<WorkOvertime> pageData = new Page<>(page, size);
+            IPage<WorkOvertime> pageResult = workOvertimeService.page(pageData, queryWrapper);
+            pageResult.getRecords().forEach(workOvertime -> {
+                workOvertime.setApplicantName(userMapper.selectById(workOvertime.getApplicant()).getName());
+                String[] array = workOvertime.getEmployeeIds().split(",");
+                List<String> employeeNames = new ArrayList<>();
+                for (int i = 0; i < array.length; i++) {
+                    final String id = array[i];
+                    Optional<User> find = userList.stream().filter(u -> u.getId().equals(id)).findFirst();
+                    if (find.isPresent()) {
+                        employeeNames.add(find.get().getName());
+                    }
+                }
+                workOvertime.setEmployeeNames(employeeNames.stream().collect(Collectors.joining(",")));
+            });
+            msg.data = pageResult;
+        } else {
+            // 不分页查询
+            msg.data = workOvertimeService.list(queryWrapper);
+        }
+        
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = workOvertimeService.removeById(id);
+        return msg;
+    }
+
+    @RequestMapping("/export")
+    public HttpRespMsg export(String applicant, 
+                             String employeeIds, 
+                             String startDate, 
+                             String endDate,
+                             String mealType) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        
+        try {
+            // 使用MyBatis-Plus的条件构造器进行查询
+            QueryWrapper<WorkOvertime> queryWrapper = new QueryWrapper<>();
+
+            User targetUser = userMapper.selectById(token);
+            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", targetUser.getCompanyId()));
+            Company company = companyMapper.selectById(targetUser.getCompanyId());
+            
+            //非管理员只能看到自己的
+            if (!targetUser.getRoleName().equals("超级管理员") && !targetUser.getRoleName().equals("系统管理员")) {
+                applicant = token;
+            }
+            
+            // 按申请人过滤
+            if (applicant != null && !applicant.trim().isEmpty()) {
+                queryWrapper.eq("applicant", applicant);
+            }
+
+            // 按员工过滤
+            if (employeeIds != null && !employeeIds.trim().isEmpty()) {
+                queryWrapper.like("employee_ids", employeeIds);
+            }
+            
+            // 按日期范围过滤
+            if (startDate != null && !startDate.trim().isEmpty()) {
+                queryWrapper.ge("work_date", LocalDate.parse(startDate));
+            }
+            if (endDate != null && !endDate.trim().isEmpty()) {
+                queryWrapper.le("work_date", LocalDate.parse(endDate));
+            }
+            if (!StringUtils.isEmpty(mealType)) {
+                queryWrapper.like("meal_type", mealType);
+            }
+            
+            // 按日期正序排列
+            queryWrapper.orderByAsc("work_date", "id");
+            
+            // 获取所有数据(不分页)
+            List<WorkOvertime> overtimeList = workOvertimeService.list(queryWrapper);
+            
+            // 查询所有加班时段设置
+            List<OvertimeSetting> overtimeSettings = overtimeSettingMapper.selectList(new QueryWrapper<OvertimeSetting>());
+            
+            // 获取所有加班人员ID
+            Set<String> overtimeUserIds = new HashSet<>();
+            for (WorkOvertime overtime : overtimeList) {
+                String[] array = overtime.getEmployeeIds().split(",");
+                for (String id : array) {
+                    overtimeUserIds.add(id.trim());
+                }
+            }
+            
+            List<ExcelUtil.OvertimeStatisticsData> exportDataList = new ArrayList<>();
+            
+            if (!overtimeUserIds.isEmpty()) {
+                // 查询加班员工信息
+                List<User> overtimeUsers = userMapper.selectList(new QueryWrapper<User>().in("id", overtimeUserIds));
+                
+                // 获取这些员工所属的部门作为工位
+                Set<Integer> departmentIds = overtimeUsers.stream()
+                    .map(User::getDepartmentId)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+                
+                List<Department> workstations = new ArrayList<>();
+                if (!departmentIds.isEmpty()) {
+                    workstations = departmentMapper.selectList(new QueryWrapper<Department>().in("department_id", departmentIds));
+                }
+                
+                // 按日期分组数据
+                Map<String, List<WorkOvertime>> dateGroupedData = overtimeList.stream()
+                    .collect(Collectors.groupingBy(overtime -> 
+                        overtime.getWorkDate() != null ? 
+                        overtime.getWorkDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) : ""));
+                
+                // 构建导出数据
+                for (Map.Entry<String, List<WorkOvertime>> dateEntry : dateGroupedData.entrySet()) {
+                    String date = dateEntry.getKey();
+                    List<WorkOvertime> dateOvertimes = dateEntry.getValue();
+                    
+                    List<ExcelUtil.WorkstationData> workstationDataList = new ArrayList<>();
+                    
+                    // 为每个工位创建时段数据行
+                    for (Department workstation : workstations) {
+                        String workstationName = workstation.getDepartmentName();
+                        
+                        // 查找该工位在该日期的加班数据
+                        List<WorkOvertime> workstationOvertimes = dateOvertimes.stream()
+                            .filter(overtime -> {
+                                // 根据员工所属部门判断工位
+                                String[] empIds = overtime.getEmployeeIds() != null ? overtime.getEmployeeIds().split(",") : new String[0];
+                                for (String empId : empIds) {
+                                    Optional<User> user = overtimeUsers.stream().filter(u -> u.getId().equals(empId.trim())).findFirst();
+                                    if (user.isPresent() && user.get().getDepartmentId() != null && 
+                                        user.get().getDepartmentId().equals(workstation.getDepartmentId())) {
+                                        return true;
+                                    }
+                                }
+                                return false;
+                            })
+                            .collect(Collectors.toList());
+                        
+                        // 如果该工位有加班数据,则根据OvertimeSetting中的时段创建数据行
+                        if (!workstationOvertimes.isEmpty()) {
+                            for (OvertimeSetting setting : overtimeSettings) {
+                                ExcelUtil.WorkstationData workstationData = createWorkstationData(workstation.getDepartmentId(),
+                                    workstationName, workstationOvertimes, setting, overtimeUsers);
+                                workstationDataList.add(workstationData);
+                            }
+                        }
+                    }
+                    
+                    exportDataList.add(new ExcelUtil.OvertimeStatisticsData(date, workstationDataList));
+                }
+            }
+
+            // 生成Excel文件
+            String fileName = "生产制造部周末加班统计表_" + company.getCompanyName() + "_" + System.currentTimeMillis();
+            String resp = ExcelUtil.exportOvertimeStatisticsExcel(fileName, exportDataList, path);
+            msg.data = resp;
+            
+        } catch (Exception e) {
+            e.printStackTrace();
+            msg.setError("导出失败:" + e.getMessage());
+        }
+        
+        return msg;
+    }
+    
+    /**
+     * 创建工位数据
+     */
+    private ExcelUtil.WorkstationData createWorkstationData(Integer departmentId, String workstationName,
+                                                           List<WorkOvertime> overtimes, 
+                                                           OvertimeSetting setting,
+                                                           List<User> userList) {
+        String timeSlot = setting.getStartTime() + "-" + setting.getEndTime();
+        // 筛选符合时段的加班数据 - 精确匹配时段
+        List<WorkOvertime> timeSlotOvertimes = overtimes.stream()
+            .filter(overtime ->{
+                String overtimeSlot = overtime.getStartTime() + "-" + overtime.getEndTime();
+                return timeSlot.equals(overtimeSlot);
+            })
+            .collect(Collectors.toList());
+        
+        int lunchCount = 0, dinnerCount = 0, snackCount = 0;
+        List<String> allEmployees = new ArrayList<>();
+        List<String> allTasks = new ArrayList<>();
+        
+        for (WorkOvertime overtime : timeSlotOvertimes) {
+            //只统计该工位下的人员
+            String[] allOvertimeSheetEmployeeIds = overtime.getEmployeeIds() != null ? overtime.getEmployeeIds().split(",") : new String[0];
+            List<User> curStationUserList = new ArrayList<>();
+            for (String empId : allOvertimeSheetEmployeeIds) {
+                Optional<User> user = userList.stream().filter(u -> u.getId().equals(empId.trim())).findFirst();
+                if (user.isPresent()) {
+                    User user2 = user.get();
+                    if (user2.getDepartmentId() != null && user2.getDepartmentId().equals(departmentId)) {
+                        curStationUserList.add(user2);
+                    }
+                }
+            }
+
+
+            int employeeCount = curStationUserList.size();
+            
+            // 根据mealType字段判断用餐类型
+            String mealTypeNames = overtime.getMealType() != null ? overtime.getMealType() : "";
+            String[] mealTypes = mealTypeNames.split(",");
+            
+            // 遍历餐别,如果包含对应餐别则人数累加
+            for (String meal : mealTypes) {
+                meal = meal.trim();
+                if (meal.contains("中餐")) {
+                    lunchCount += employeeCount;
+                }
+                if (meal.contains("晚餐")) {
+                    dinnerCount += employeeCount;
+                }
+                if (meal.contains("夜宵")) {
+                    snackCount += employeeCount;
+                }
+            }
+            
+            // 收集员工姓名
+            for (User user : curStationUserList) {
+                allEmployees.add(user.getName());
+            }
+            
+            // 收集任务安排
+            if (overtime.getContent() != null && !overtime.getContent().trim().isEmpty()) {
+                allTasks.add(overtime.getContent());
+            }
+        }
+        
+        String employees = allEmployees.stream().distinct().collect(Collectors.joining(","));
+        String taskArrangement = allTasks.stream().distinct().collect(Collectors.joining(";"));
+        String cooperationPersonnel = "";
+        return new ExcelUtil.WorkstationData(workstationName, lunchCount, dinnerCount, snackCount,
+                                           timeSlot, employees, taskArrangement, cooperationPersonnel);
+    }
+}

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

@@ -0,0 +1,54 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-11-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class OvertimeSetting extends Model<OvertimeSetting> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 开始时间
+     */
+    @TableField("start_time")
+    private String startTime;
+
+    /**
+     * 结束时间
+     */
+    @TableField("end_time")
+    private String endTime;
+
+    /**
+     * 加班时长
+     */
+    @TableField("hours")
+    private Double hours;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 108 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/WorkOvertime.java

@@ -0,0 +1,108 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import java.time.LocalDate;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-11-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class WorkOvertime extends Model<WorkOvertime> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 申请人
+     */
+    @TableField("applicant")
+    private String applicant;
+
+    /**
+     * 加班员工
+     */
+    @TableField("employee_ids")
+    private String employeeIds;
+
+    /**
+     * 加班日期
+     */
+    @TableField("work_date")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate workDate;
+
+    /**
+     * 加班开始时间
+     */
+    @TableField("start_time")
+    private String startTime;
+
+    /**
+     * 加班结束时间
+     */
+    @TableField("end_time")
+    private String endTime;
+
+    /**
+     * 加班时长
+     */
+    @TableField("hours")
+    private Double hours;
+
+    /**
+     * 工作内容
+     */
+    @TableField("content")
+    private String content;
+
+    /**
+     * 加班时段id
+     */
+    @TableField("time_type_id")
+    private Integer timeTypeId;
+
+    /**
+     * 用餐类别:中餐,晚餐,夜宵
+     */
+    @TableField("meal_type")
+    private String mealType;
+
+
+    /**
+     * 申请人姓名
+     */
+    @TableField(exist = false)
+    private String applicantName;
+
+    /**
+     * 加班员工姓名
+     */
+    @TableField(exist = false)
+    private String employeeNames;
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.OvertimeSetting;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-11-20
+ */
+public interface OvertimeSettingMapper extends BaseMapper<OvertimeSetting> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.WorkOvertime;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-11-20
+ */
+public interface WorkOvertimeMapper extends BaseMapper<WorkOvertime> {
+
+}

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

@@ -64,4 +64,6 @@ public interface DepartmentService extends IService<Department> {
     HttpRespMsg sortList(HttpServletRequest request,List<DepartmentVO> list);
 
     HttpRespMsg getMyGroups(HttpServletRequest request);
+
+    HttpRespMsg userListInMyRange(HttpServletRequest request);
 }

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.OvertimeSetting;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-11-20
+ */
+public interface OvertimeSettingService extends IService<OvertimeSetting> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.WorkOvertime;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-11-20
+ */
+public interface WorkOvertimeService extends IService<WorkOvertime> {
+
+}

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

@@ -465,6 +465,34 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
     addUserListToDepartment(parentDept, allUsers);
 }
 
+    private void fillSubDepartmentListWithUsers(List<Department> allDepts, DepartmentVO parentDept,
+                                                List<User> allUsers) {
+        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);
+                // 添加当前部门的用户
+                addUserListToDepartment(vo, allUsers);
+                subResult.add(vo);
+                //继续添加当前部门的子部门
+                fillSubDepartmentListWithUsers(allDepts, vo, allUsers);
+            });
+        }
+
+        // 设置子部门列表
+        if (subResult.size() > 0) {
+            parentDept.setChildren(subResult);
+        }
+
+        // 为当前部门添加用户列表
+        addUserListToDepartment(parentDept, allUsers);
+    }
+
 private void addUserListToDepartment(DepartmentVO departmentVO, List<User> allUsers) {
     List<HashMap> userMapList = new ArrayList<>();
     // 筛选出属于当前部门的用户
@@ -561,6 +589,29 @@ private void addUserListToDepartment(DepartmentVO departmentVO, List<User> allUs
     return vo;
     }
 
+    private DepartmentVO formatDepartmentToVO(Department department) {
+        //获取该部门的其他管理者
+        //这俩东西并没有继承关系
+        DepartmentVO vo = new DepartmentVO()
+                .setId(department.getDepartmentId())
+                .setManagerId(department.getManagerId())
+                .setLabel(department.getDepartmentName())
+                .setParentId(department.getSuperiorId())
+                .setReportAuditUserid(department.getReportAuditUserid())
+                .setDdDeptid(department.getDdDeptid())
+                .setSeq(department.getSeq());
+
+        // 确保初始化children和userList
+        if (vo.getChildren() == null) {
+            vo.setChildren(new ArrayList<>());
+        }
+        if (vo.getUserList() == null) {
+            vo.setUserList(new ArrayList<>());
+        }
+
+        return vo;
+    }
+
     //获取某个项目下的统计
     @Override
     public HttpRespMsg getDepartmentStatistics(Integer parentDeptId, String startDate, String endDate, HttpServletRequest request) {
@@ -1712,6 +1763,45 @@ private void addUserListToDepartment(DepartmentVO departmentVO, List<User> allUs
         return msg;
     }
 
+    @Override
+    public HttpRespMsg userListInMyRange(HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            //筛选公司下所有的部门
+            User user = userMapper.selectById(request.getHeader("Token"));
+            Integer companyId = user.getCompanyId();
+            List<Department> departmentList = departmentMapper.selectList(new QueryWrapper<Department>()
+                    .eq("company_id", companyId));
+            Department manufacturingDept = departmentMapper.selectOne(new QueryWrapper<Department>().eq("department_name", "生产制造部"));
+            Department rootDept = manufacturingDept;
+//            if (user.getRoleName().equals("超级管理员") || user.getRoleName().equals("系统管理员") || user.getId().equals(manufacturingDept.getManagerId())) {
+//                rootDept = manufacturingDept;
+//            } else {
+//                //获取当前管理的部门
+//                rootDept = departmentMapper.selectOne(new QueryWrapper<Department>().eq("manager_id", user.getId()));
+//            }
+            // 获取公司所有活跃用户
+            List<User> userList = userMapper.selectList(new QueryWrapper<User>()
+                    .eq("company_id", companyId)
+                    .eq("is_active", 1));
+
+            //结果列表
+            List<DepartmentVO> list = new ArrayList<>();
+            DepartmentVO rootDeptVO = formatDepartmentToVO(rootDept);
+            list.add(rootDeptVO);
+            fillSubDepartmentListWithUsers(departmentList, rootDeptVO, userList);
+            //递归排序
+            sortResultDeptList(list);
+            //返回数据
+            httpRespMsg.data = list;
+        } catch (NullPointerException e) {
+            //httpRespMsg.setError("验证失败");
+            httpRespMsg.setError(MessageUtils.message("Company.validationError"));
+            return httpRespMsg;
+        }
+        return httpRespMsg;
+    }
+
     /**
      * 递归对返回的部门数据进行排序
      * @param list

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.OvertimeSetting;
+import com.management.platform.mapper.OvertimeSettingMapper;
+import com.management.platform.service.OvertimeSettingService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-11-20
+ */
+@Service
+public class OvertimeSettingServiceImpl extends ServiceImpl<OvertimeSettingMapper, OvertimeSetting> implements OvertimeSettingService {
+
+}

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

@@ -182,6 +182,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
     private UserWorkTypeMapper workTypeMapper;
     public static String provider_access_token = null;
     public static long providerTokenExpireTime = 0L;
+    @Autowired
+    private MealApplicationsMapper mealApplicationsMapper;
+    @Autowired
+    private ProdProcedureTeamMapper prodProcedureTeamMapper;
+
     //登录网页端
     @Override
     public HttpRespMsg loginAdmin(String username, String password){
@@ -853,30 +858,12 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
                     //httpRespMsg.setError("超级管理员不可删除");
                     httpRespMsg.setError(MessageUtils.message("role.deleteRootError"));
                 } else {
-                    //检测是否该人员已填日报,已填写日报的不能删除
-                    Integer userReportNum = reportMapper.selectCount(new QueryWrapper<Report>().eq("creator_id", target.getId()));
-                    if (userReportNum > 0) {
-                        //httpRespMsg.setError("该员工存在填写的日报,无法删除。");
-                        httpRespMsg.setError(MessageUtils.message("staff.deleteErrorByDaily"));
-                    } else {
-                        //检测是否有已参与的任务
-                        Integer taskNum = taskMapper.selectCount(new QueryWrapper<Task>().like("executor_id", userId));
-                        if (taskNum > 0) {
-                            //httpRespMsg.setError("该员工存在参与的任务,无法删除");
-                            httpRespMsg.setError(MessageUtils.message("staff.deleteErrorByTask"));
-                        } else {
-                            //检测是否担任项目负责人
-                            Integer projectNum = projectMapper.selectCount(new QueryWrapper<Project>().eq("incharger_id", userId));
-                            if (projectNum > 0) {
-                                //httpRespMsg.setError("该员工存在负责的项目,无法删除");
-                                httpRespMsg.setError(MessageUtils.message("staff.deleteErrorByProject"));
-                            } else {
-                                userMapper.deleteById(userId);
-                                //项目参与人可以直接删除
-                                participationMapper.delete(new QueryWrapper<Participation>().eq("user_id", userId));
-                            }
-                        }
-                    }
+                    //已填写日报先删除日报
+                    reportMapper.delete(new QueryWrapper<Report>().eq("creator_id", userId));
+                    //报餐数据,有的话删掉
+                    mealApplicationsMapper.delete(new QueryWrapper<MealApplications>().eq("user_id", userId));
+                    prodProcedureTeamMapper.delete(new QueryWrapper<ProdProcedureTeam>().eq("user_id", userId));
+                    userMapper.deleteById(userId);
                 }
             }
         } catch (NullPointerException e) {

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.WorkOvertime;
+import com.management.platform.mapper.WorkOvertimeMapper;
+import com.management.platform.service.WorkOvertimeService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-11-20
+ */
+@Service
+public class WorkOvertimeServiceImpl extends ServiceImpl<WorkOvertimeMapper, WorkOvertime> implements WorkOvertimeService {
+
+}

+ 292 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/util/ExcelUtil.java

@@ -820,4 +820,296 @@ public class ExcelUtil {
         }
         return "/upload/"+fileName;
     }
+
+    /**
+     * 导出生产制造部周末加班统计表
+     * @param title 文件标题
+     * @param dataList 数据列表,每个元素包含日期和该日期下的工位数据
+     * @param downloadPath 下载路径
+     * @return 文件路径
+     */
+    public static String exportOvertimeStatisticsExcel(String title, List<OvertimeStatisticsData> dataList, String downloadPath) {
+        String result = "系统提示:Excel文件导出成功!";
+        String fileName = title + ".xlsx";
+        
+        try {
+            // 创建工作簿
+            SXSSFWorkbook workBook = new SXSSFWorkbook();
+            Sheet sheet = workBook.createSheet("生产部");
+            sheet.setDefaultColumnWidth(16);
+            
+            // 设置特定列的宽度 - 第3、4、5列(中餐、晚餐、夜宵人数)宽度缩小一半
+            sheet.setColumnWidth(2, 8 * 256); // 中餐人数列宽度设为8
+            sheet.setColumnWidth(3, 8 * 256); // 晚餐人数列宽度设为8  
+            sheet.setColumnWidth(4, 8 * 256); // 夜宵人数列宽度设为8
+            
+            // 设置字体样式
+            Font titleFont = workBook.createFont();
+            titleFont.setBold(true);
+            titleFont.setFontHeightInPoints((short) 12);
+            titleFont.setFontName("黑体");
+            
+            Font headFont = workBook.createFont();
+            headFont.setBold(true);
+            headFont.setFontHeightInPoints((short) 10);
+            headFont.setFontName("黑体");
+            
+            Font font = workBook.createFont();
+            font.setFontHeightInPoints((short) 10);
+            font.setFontName("宋体");
+            
+            // 设置单元格样式
+            CellStyle titleStyle = workBook.createCellStyle();
+            titleStyle.setFont(titleFont);
+            titleStyle.setAlignment(HorizontalAlignment.CENTER);
+            titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            titleStyle.setBorderBottom(BorderStyle.THIN);
+            titleStyle.setBorderLeft(BorderStyle.THIN);
+            titleStyle.setBorderTop(BorderStyle.THIN);
+            titleStyle.setBorderRight(BorderStyle.THIN);
+            
+            CellStyle headStyle = workBook.createCellStyle();
+            headStyle.setFont(headFont);
+            headStyle.setAlignment(HorizontalAlignment.CENTER);
+            headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            headStyle.setBorderBottom(BorderStyle.THIN);
+            headStyle.setBorderLeft(BorderStyle.THIN);
+            headStyle.setBorderTop(BorderStyle.THIN);
+            headStyle.setBorderRight(BorderStyle.THIN);
+            headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index);
+            headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+            
+            CellStyle cellStyle = workBook.createCellStyle();
+            cellStyle.setFont(font);
+            cellStyle.setAlignment(HorizontalAlignment.CENTER);
+            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            cellStyle.setBorderBottom(BorderStyle.THIN);
+            cellStyle.setBorderLeft(BorderStyle.THIN);
+            cellStyle.setBorderTop(BorderStyle.THIN);
+            cellStyle.setBorderRight(BorderStyle.THIN);
+            
+            int currentRow = 0;
+            
+            // 创建标题行(合并单元格)
+            Row titleRow = sheet.createRow(currentRow++);
+            titleRow.setHeightInPoints(30);
+            for (int i = 0; i < 10; i++) {
+                Cell cell = titleRow.createCell(i);
+                cell.setCellStyle(titleStyle);
+                if (i == 0) {
+                    cell.setCellValue("生产制造部周末加班明细");
+                }
+            }
+            // 合并标题行
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 9));
+            
+            // 创建表头
+            Row headerRow = sheet.createRow(currentRow++);
+            headerRow.setHeightInPoints(24);
+            String[] headers = {"日期", "工位", "中餐人数", "晚餐人数", "夜宵人数", "时段", "人员", "任务安排", "需要配合部门人员", "备注"};
+            for (int i = 0; i < headers.length; i++) {
+                Cell cell = headerRow.createCell(i);
+                cell.setCellStyle(headStyle);
+                cell.setCellValue(headers[i]);
+            }
+            
+            // 填充数据并记录需要合并的日期单元格
+            List<CellRangeAddress> dateMergeRanges = new ArrayList<>();
+            
+            for (OvertimeStatisticsData dateData : dataList) {
+                String date = dateData.getDate();
+                List<WorkstationData> workstations = dateData.getWorkstations();
+                
+                int dateStartRow = currentRow; // 记录当前日期开始的行号
+                
+                for (WorkstationData workstation : workstations) {
+                    Row dataRow = sheet.createRow(currentRow++);
+                    dataRow.setHeightInPoints(24);
+                    
+                    // 日期 - 只在第一行填写,其他行留空
+                    Cell dateCell = dataRow.createCell(0);
+                    dateCell.setCellStyle(cellStyle);
+                    if (currentRow - 1 == dateStartRow) {
+                        dateCell.setCellValue(date);
+                    }
+                    
+                    // 工位
+                    Cell workstationCell = dataRow.createCell(1);
+                    workstationCell.setCellStyle(cellStyle);
+                    workstationCell.setCellValue(workstation.getWorkstationName());
+                    
+                    // 中餐人数
+                    Cell lunchCell = dataRow.createCell(2);
+                    lunchCell.setCellStyle(cellStyle);
+                    lunchCell.setCellValue(workstation.getLunchCount() > 0 ? String.valueOf(workstation.getLunchCount()) : "");
+                    
+                    // 晚餐人数
+                    Cell dinnerCell = dataRow.createCell(3);
+                    dinnerCell.setCellStyle(cellStyle);
+                    dinnerCell.setCellValue(workstation.getDinnerCount() > 0 ? String.valueOf(workstation.getDinnerCount()) : "");
+                    
+                    // 夜宵人数
+                    Cell snackCell = dataRow.createCell(4);
+                    snackCell.setCellStyle(cellStyle);
+                    snackCell.setCellValue(workstation.getSnackCount() > 0 ? String.valueOf(workstation.getSnackCount()) : "");
+                    
+                    // 时段
+                    Cell timeSlotCell = dataRow.createCell(5);
+                    timeSlotCell.setCellStyle(cellStyle);
+                    timeSlotCell.setCellValue(workstation.getTimeSlot());
+                    
+                    // 人员
+                    Cell employeesCell = dataRow.createCell(6);
+                    employeesCell.setCellStyle(cellStyle);
+                    employeesCell.setCellValue(workstation.getEmployees());
+                    
+                    // 任务安排
+                    Cell taskCell = dataRow.createCell(7);
+                    taskCell.setCellStyle(cellStyle);
+                    taskCell.setCellValue(workstation.getTaskArrangement());
+                    
+                    // 需要配合部门人员
+                    Cell cooperationCell = dataRow.createCell(8);
+                    cooperationCell.setCellStyle(cellStyle);
+                    cooperationCell.setCellValue(workstation.getCooperationPersonnel());
+                    
+                    // 备注
+                    Cell remarksCell = dataRow.createCell(9);
+                    remarksCell.setCellStyle(cellStyle);
+                    remarksCell.setCellValue("");
+                }
+                
+                // 添加合计行
+                if (!workstations.isEmpty()) {
+                    Row totalRow = sheet.createRow(currentRow++);
+                    totalRow.setHeightInPoints(24);
+                    
+                    // 日期 - 合计行也留空,会被合并
+                    Cell dateCell = totalRow.createCell(0);
+                    dateCell.setCellStyle(cellStyle);
+                    
+                    // 合计
+                    Cell totalCell = totalRow.createCell(1);
+                    totalCell.setCellStyle(cellStyle);
+                    totalCell.setCellValue("合计");
+                    
+                    // 计算合计数据
+                    int totalLunch = workstations.stream().mapToInt(WorkstationData::getLunchCount).sum();
+                    int totalDinner = workstations.stream().mapToInt(WorkstationData::getDinnerCount).sum();
+                    int totalSnack = workstations.stream().mapToInt(WorkstationData::getSnackCount).sum();
+                    
+                    Cell lunchTotalCell = totalRow.createCell(2);
+                    lunchTotalCell.setCellStyle(cellStyle);
+                    lunchTotalCell.setCellValue(totalLunch > 0 ? String.valueOf(totalLunch) : "");
+                    
+                    Cell dinnerTotalCell = totalRow.createCell(3);
+                    dinnerTotalCell.setCellStyle(cellStyle);
+                    dinnerTotalCell.setCellValue(totalDinner > 0 ? String.valueOf(totalDinner) : "");
+                    
+                    Cell snackTotalCell = totalRow.createCell(4);
+                    snackTotalCell.setCellStyle(cellStyle);
+                    snackTotalCell.setCellValue(totalSnack > 0 ? String.valueOf(totalSnack) : "");
+                    
+                    // 其他列留空
+                    for (int i = 5; i < 10; i++) {
+                        Cell emptyCell = totalRow.createCell(i);
+                        emptyCell.setCellStyle(cellStyle);
+                        emptyCell.setCellValue("");
+                    }
+                }
+                
+                // 记录需要合并的日期单元格范围(包括工位行和合计行)
+                int dateEndRow = currentRow - 1;
+                if (dateEndRow > dateStartRow) {
+                    dateMergeRanges.add(new CellRangeAddress(dateStartRow, dateEndRow, 0, 0));
+                }
+            }
+            
+            // 执行日期列的单元格合并
+            for (CellRangeAddress range : dateMergeRanges) {
+                sheet.addMergedRegion(range);
+            }
+            
+            // 添加签名行
+            Row signatureRow = sheet.createRow(currentRow++);
+            signatureRow.setHeightInPoints(24);
+            
+            Cell compilerCell = signatureRow.createCell(0);
+            compilerCell.setCellStyle(cellStyle);
+            compilerCell.setCellValue("编制:");
+            
+            Cell auditorCell = signatureRow.createCell(5);
+            auditorCell.setCellStyle(cellStyle);
+            auditorCell.setCellValue("审核:");
+            
+            Cell approverCell = signatureRow.createCell(7);
+            approverCell.setCellStyle(cellStyle);
+            approverCell.setCellValue("批准:");
+            
+            // 保存文件
+            File dir = new File(downloadPath);
+            if (!dir.exists()) {
+                dir.mkdirs();
+            }
+            FileOutputStream os = new FileOutputStream(downloadPath + fileName);
+            workBook.write(os);
+            os.flush();
+            os.close();
+            
+        } catch (Exception e) {
+            System.out.println(result);
+            e.printStackTrace();
+        }
+        
+        return "/upload/" + fileName;
+    }
+    
+    // 数据传输对象
+    public static class OvertimeStatisticsData {
+        private String date;
+        private List<WorkstationData> workstations;
+        
+        public OvertimeStatisticsData(String date, List<WorkstationData> workstations) {
+            this.date = date;
+            this.workstations = workstations;
+        }
+        
+        public String getDate() { return date; }
+        public List<WorkstationData> getWorkstations() { return workstations; }
+    }
+    
+    public static class WorkstationData {
+        private String workstationName;
+        private int lunchCount;
+        private int dinnerCount;
+        private int snackCount;
+        private String timeSlot;
+        private String employees;
+        private String taskArrangement;
+        private String cooperationPersonnel;
+        
+        public WorkstationData(String workstationName, int lunchCount, int dinnerCount, int snackCount,
+                             String timeSlot, String employees, String taskArrangement, 
+                             String cooperationPersonnel) {
+            this.workstationName = workstationName;
+            this.lunchCount = lunchCount;
+            this.dinnerCount = dinnerCount;
+            this.snackCount = snackCount;
+            this.timeSlot = timeSlot;
+            this.employees = employees;
+            this.taskArrangement = taskArrangement;
+            this.cooperationPersonnel = cooperationPersonnel;
+            System.out.println(workstationName+":"+lunchCount+":"+dinnerCount+":"+snackCount+":"+timeSlot+":"+employees+":"+taskArrangement+":"+cooperationPersonnel);
+        }
+        
+        // Getters
+        public String getWorkstationName() { return workstationName; }
+        public int getLunchCount() { return lunchCount; }
+        public int getDinnerCount() { return dinnerCount; }
+        public int getSnackCount() { return snackCount; }
+        public String getTimeSlot() { return timeSlot; }
+        public String getEmployees() { return employees; }
+        public String getTaskArrangement() { return taskArrangement; }
+        public String getCooperationPersonnel() { return cooperationPersonnel; }
+    }
 }

+ 18 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/OvertimeSettingMapper.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.OvertimeSettingMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.OvertimeSetting">
+        <id column="id" property="id" />
+        <result column="start_time" property="startTime" />
+        <result column="end_time" property="endTime" />
+        <result column="hours" property="hours" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, start_time, end_time, hours
+    </sql>
+
+</mapper>

+ 24 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/WorkOvertimeMapper.xml

@@ -0,0 +1,24 @@
+<?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.WorkOvertimeMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.WorkOvertime">
+        <id column="id" property="id" />
+        <result column="applicant" property="applicant" />
+        <result column="employee_ids" property="employeeIds" />
+        <result column="work_date" property="workDate" />
+        <result column="start_time" property="startTime" />
+        <result column="end_time" property="endTime" />
+        <result column="hours" property="hours" />
+        <result column="content" property="content" />
+        <result column="time_type_id" property="timeTypeId" />
+        <result column="meal_type" property="mealType" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, applicant, employee_ids, work_date, start_time, end_time, hours, content, time_type_id, meal_type
+    </sql>
+
+</mapper>

BIN
fhKeeper/formulahousekeeper/management-workshop/workshop_print.2025-11-11.log.gz


BIN
fhKeeper/formulahousekeeper/management-workshop/workshop_print.2025-11-12.log.gz


+ 4 - 0
fhKeeper/formulahousekeeper/timesheet-workshop/src/permissions.js

@@ -238,6 +238,10 @@ const StringUtil = {
         arr[i] == '全部子项目工时成本' ? obj.reportAllManhourCost = true : ''
         arr[i] == '负责项目子项目工时成本' ? obj.reportResponsibleManhourCost = true : ''
         arr[i] == '修改默认文件夹' ? obj.projectEditDefaultFolder = true : ''
+
+        arr[i] == '删除加班' ? obj.deleteOvertime = true : ''
+        arr[i] == '管理时间段' ? obj.manageTimeType = true : ''
+        
     }
     return obj
   }

+ 37 - 66
fhKeeper/formulahousekeeper/timesheet-workshop/src/views/team/index.vue

@@ -494,34 +494,12 @@
             </div>
             <span slot="footer" class="dialog-footer">
                 <!-- <el-button type="danger" @click="deleteUser(insertForm, '1')" style="float:left;">{{ $t('btn.delete') }}</el-button> -->
-                <el-button type="danger" @click="deleteUserFlg = true" style="float:left;">{{ $t('btn.delete') }}</el-button>
+                <el-button type="danger" @click="deleteUser()" style="float:left;">{{ $t('btn.delete') }}</el-button>
                 <el-button @click="dialogVisible=false">{{ $t('btn.cancel') }}</el-button>
                 <el-button type="primary" @click="submitInsert('insertForm')" :loading="submitLoading">{{ $t('btn.submit') }}</el-button>
             </span>
         </el-dialog>
-        <!-- 删除员工时转移日报 -->
-        <el-dialog title="提示" :visible.sync="deleteUserFlg" width="600px" :before-close="handleClose">
-        <div>
-          <div class="deteee">确定删除该员工吗?</div>
-          <div class="deteeeAce" v-if="deleteUserFlgData.isExistsReport">
-
-            <div style="margin-right: 10px">将该员工的工时数据、参与的项目与任务转移 至</div>
-            <el-select v-if="user.userNameNeedTranslate != 1" v-model="moveReportUserId" style="width:140px;" :placeholder="$t('defaultText.pleaseChoose')" clearable size="small" filterable popper-class="managePopperClass">
-                <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;">{{ item.jobNumber }}</span>
-                </el-option>
-            </el-select>
-
-            <selectCat v-if="user.userNameNeedTranslate == 1" :size="'small'" :subject="users" :widthStr="350" :subjectId="moveReportUserId" :distinction="'22'" :clearable="true" @selectCal="selectCal"></selectCat>
-
-          </div>
-        </div>
-        <span slot="footer" class="dialog-footer">
-          <el-button @click="deleteUserFlg = false">取 消</el-button>
-          <el-button type="primary" @click="deleteUser(deleteUserFlgData)" :loading="deleteUserFlgloading">确 定</el-button>
-        </span>
-      </el-dialog>
+        
 
         <el-dialog :title="$t('historicalpersonnelcost')" :visible.sync="userSalaryListDialog" width="550px" >
             <el-table :data="userSalaryList" highlight-current-row v-loading="listLoading" height="300px" style="width: 100%;">
@@ -1908,48 +1886,41 @@ export default {
             }
           );
     },
-    deleteUser(targetUser) {
-      console.log(targetUser, '数据', this.deleteUserFlgData)
-        // this.$confirm(this.$t('deletthisemployee'), this.$t('other.prompts'), {
-        //   //type: 'warning'
-        // }).then(() => {
-          this.dialogVisible = true
-          if(this.deleteUserFlgData.isExistsReport) {
-            this.transferDaily()
-          } else {
-            this.transferDailydete()
-          }
-          // this.http.post(
-          //   "/user/deleteUser",
-          //   {
-          //     // userId: targetUser.id,
-          //     userId: this.deleteUserFlgData.id,
-          //   },
-          //   (res) => {
-          //     if (res.code == "ok") {
-          //       this.$message({
-          //         message: this.$t('message.successfullyDeleted'),
-          //         type: "success",
-          //       });
-          //       this.dialogVisible = false;
-          //       this.getUser();
-          //     } else {
-          //       this.$message({
-          //         message: res.msg,
-          //         type: "error",
-          //       });
-          //       this.dialogVisible = false;
-          //     }
-          //   },
-          //   (error) => {
-          //     this.$message({
-          //       message: error,
-          //       type: "error",
-          //     });
-          //     this.dialogVisible = false;
-          //   }
-          // );
-        // });
+    deleteUser() {
+         this.$confirm(this.$t('deletthisemployee'), this.$t('other.prompts'), {
+           //type: 'warning'
+         }).then(() => {
+          this.http.post(
+            "/user/deleteUser",
+            {
+              // userId: targetUser.id,
+              userId: this.deleteUserFlgData.id,
+            },
+            (res) => {
+              if (res.code == "ok") {
+                this.$message({
+                  message: this.$t('message.successfullyDeleted'),
+                  type: "success",
+                });
+                this.dialogVisible = false;
+                this.getUser();
+              } else {
+                this.$message({
+                  message: res.msg,
+                  type: "error",
+                });
+                this.dialogVisible = false;
+              }
+            },
+            (error) => {
+              this.$message({
+                message: error,
+                type: "error",
+              });
+              this.dialogVisible = false;
+            }
+          );
+        });
     },
     chufa(data, b, c, e) {
       if (this.depData == null || data.id != this.depData.id) {

+ 325 - 79
fhKeeper/formulahousekeeper/timesheet-workshop/src/views/workOvertime/apply.vue

@@ -6,7 +6,7 @@
       </div>
       <el-form :model="overtimeForm" :rules="rules" ref="overtimeForm" label-width="100px">
         <el-form-item label="加班日期" prop="overtimeDate">
-          <el-date-picker
+          <el-date-picker style="width:300px;"
               v-model="overtimeForm.overtimeDate"
               type="date"
               placeholder="选择加班日期"
@@ -16,21 +16,44 @@
         </el-form-item>
 
         <el-form-item label="加班人员" prop="employees">
-          <el-cascader
+          <el-cascader style="width:300px;"
               v-model="overtimeForm.employees"
               :options="departmentTree"
               :props="cascaderProps"
               clearable
               filterable
-              multiple
               collapse-tags
               placeholder="请选择部门及人员"
               @change="handleEmployeeChange">
           </el-cascader>
-          <el-button type="primary" size="small" @click="showEmployeeDialog" style="margin-left: 10px;">添加加班人员</el-button>
         </el-form-item>
 
-        <el-form-item label="开始时间" prop="startTime">
+        <el-form-item label="用餐类别" prop="mealType">
+          <el-select
+              v-model="overtimeForm.mealType"
+              style="width:300px;"
+              placeholder="请选择用餐类别"
+              multiple
+              collapse-tags
+              clearable>
+            <el-option value="中餐" label="中餐"></el-option>
+            <el-option value="晚餐" label="晚餐"></el-option>
+            <el-option value="夜宵" label="夜宵"></el-option>
+          </el-select>
+        </el-form-item>
+
+        
+        <el-form-item label="加班时段" prop="timeType" >
+          <el-select
+              v-model="overtimeForm.timeType" style="width:300px;"
+              placeholder="选择开始时间">
+              <el-option v-for="item in timeTypeList" :value="item.id" :label="item.startTime+'-'+item.endTime+', '+item.hours+'小时'">
+              </el-option>
+          </el-select>
+          <el-button type="primary" @click="showTimeEditDialog" style="margin-left: 10px;" v-if="permissions.manageTimeType">管理时间段</el-button>
+        </el-form-item>
+
+        <!-- <el-form-item label="开始时间" prop="startTime">
           <el-time-picker
               v-model="overtimeForm.startTime"
               value-format="HH:mm"
@@ -46,13 +69,13 @@
               format="HH:mm"
               placeholder="选择结束时间">
           </el-time-picker>
-        </el-form-item>
-
+        </el-form-item> -->
+<!-- 
         <el-form-item label="加班时长" prop="duration">
           <el-input v-model="overtimeForm.duration" placeholder="自动计算或手动输入" readonly>
             <template slot="append">小时</template>
           </el-input>
-        </el-form-item>
+        </el-form-item> -->
 
         <el-form-item label="工作内容" prop="workContent">
           <el-input
@@ -64,31 +87,83 @@
         </el-form-item>
 
         <el-form-item>
-          <el-button type="primary" @click="submitForm('overtimeForm')">提交申请</el-button>
-          <el-button @click="resetForm('overtimeForm')">重置</el-button>
+          <el-button type="primary" @click="submitForm('overtimeForm')" >提交申请</el-button>
+          <el-button @click="resetForm('overtimeForm')" >重置</el-button>
         </el-form-item>
       </el-form>
     </el-card>
 
-    <!-- 添加人员对话框 -->
-    <el-dialog title="添加加班人员" :visible.sync="employeeDialogVisible" width="600px">
-      <el-table :data="allEmployees" style="width: 100%" max-height="400">
-        <el-table-column prop="name" label="姓名" width="120"></el-table-column>
-        <el-table-column prop="department" label="部门"></el-table-column>
-        <el-table-column prop="position" label="职位"></el-table-column>
-        <el-table-column label="操作" width="100">
+    <!-- 时间段管理对话框 -->
+    <el-dialog title="管理时间段" :visible.sync="timeDialogVisible" width="650px">
+      <div style="margin-bottom: 20px;">
+        <el-button type="primary" @click="showTimeForm" >添加时间段</el-button>
+      </div>
+      
+      <el-table :data="timeTypeList" style="width: 100%" max-height="400">
+        <el-table-column type="index" label="序号" width="60" :index="indexMethod"></el-table-column>
+        <el-table-column prop="startTime" label="开始时间" width="120"></el-table-column>
+        <el-table-column prop="endTime" label="结束时间" width="120"></el-table-column>
+        <el-table-column prop="hours" label="加班时长" width="120">
+          <template slot-scope="scope">
+            {{ scope.row.hours }}小时
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="150">
           <template slot-scope="scope">
             <el-button
                 size="mini"
-                @click="addEmployee(scope.row)"
-                :disabled="isEmployeeSelected(scope.row.id)">
-              添加
+                type="primary"
+                @click="editTimeType(scope.row)">
+              编辑
+            </el-button>
+            <el-button
+                size="mini"
+                type="danger"
+                @click="deleteTimeType(scope.row)">
+              删除
             </el-button>
           </template>
         </el-table-column>
       </el-table>
+      
       <span slot="footer" class="dialog-footer">
-        <el-button @click="employeeDialogVisible = false">关闭</el-button>
+        <el-button @click="timeDialogVisible = false">关闭</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 添加/编辑时间段对话框 -->
+    <el-dialog :title="timeFormTitle" :visible.sync="timeFormVisible" width="500px">
+      <el-form :model="timeForm" :rules="timeFormRules" ref="timeForm" label-width="100px">
+        <el-form-item label="开始时间" prop="startTime">
+          <el-time-picker
+              v-model="timeForm.startTime"
+              value-format="HH:mm"
+              format="HH:mm"
+              placeholder="选择开始时间"
+              style="width: 100%;">
+          </el-time-picker>
+        </el-form-item>
+        
+        <el-form-item label="结束时间" prop="endTime">
+          <el-time-picker
+              v-model="timeForm.endTime"
+              value-format="HH:mm"
+              format="HH:mm"
+              placeholder="选择结束时间"
+              style="width: 100%;">
+          </el-time-picker>
+        </el-form-item>
+        
+        <el-form-item label="加班时长" prop="hours">
+          <el-input v-model="timeForm.hours" placeholder="自动计算或手动输入" readonly>
+            <template slot="append">小时</template>
+          </el-input>
+        </el-form-item>
+      </el-form>
+      
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="timeFormVisible = false">取消</el-button>
+        <el-button type="primary" @click="saveTimeType" :loading="timeFormLoading">保存</el-button>
       </span>
     </el-dialog>
   </div>
@@ -101,25 +176,27 @@
       overtimeForm: {
         overtimeDate: '',
         employees: [],
-        startTime: '',
-        endTime: '',
-        duration: '',
+        mealType: [],
+        timeType: '',
         workContent: ''
       },
+      user: JSON.parse(sessionStorage.getItem("user")),
+      permissions: JSON.parse(sessionStorage.getItem("permissions")),
       // 级联选择器配置
      cascaderProps: {
-  value: 'id',
-  label: 'label',
-  children: 'children',
-  emitPath: false,
-  checkStrictly: false,
-  expandTrigger: 'hover',
-  // 添加以下配置以支持用户选择
-  leaf: (data, node) => {
-    // 可以根据数据特征判断是否为叶子节点(如用户节点)
-    return !data.children || data.children.length === 0;
-  }
-},
+        value: 'id',
+        label: 'label',
+        children: 'children',
+        emitPath: false,
+        checkStrictly: false,
+        expandTrigger: 'hover',
+        multiple: true,
+        // 添加以下配置以支持用户选择
+        leaf: (data, node) => {
+          // 可以根据数据特征判断是否为叶子节点(如用户节点)
+          return !data.children || data.children.length === 0;
+        }
+      },
       departmentTree: [],
       rules: {
         overtimeDate: [
@@ -128,11 +205,11 @@
         employees: [
           { required: true, message: '请选择加班人员', trigger: 'change' }
         ],
-        startTime: [
-          { required: true, message: '请选择开始时间', trigger: 'change' }
+        timeType: [
+          { required: true, message: '请选择加班时段', trigger: 'change' }
         ],
-        endTime: [
-          { required: true, message: '请选择结束时间', trigger: 'change' }
+        mealType: [
+          { required: true, message: '请选择用餐类别', trigger: 'change' }
         ],
         workContent: [
           { required: true, message: '请输入工作内容', trigger: 'blur' }
@@ -141,12 +218,31 @@
       employeeOptions: [],
       allEmployees: [],
       employeeLoading: false,
-      employeeDialogVisible: false
+      timeDialogVisible: false,
+      timeFormVisible: false,
+      timeFormLoading: false,
+      timeForm: {
+        id: null,
+        startTime: '',
+        endTime: '',
+        hours: ''
+      },
+      timeFormTitle: '添加时间段',
+      timeFormRules: {
+        startTime: [
+          { required: true, message: '请选择开始时间', trigger: 'change' }
+        ],
+        endTime: [
+          { required: true, message: '请选择结束时间', trigger: 'change' }
+        ]
+      },
+      timeTypeList: []
     }
   },
   mounted() {
     // 初始化加载部门数据
     this.searchEmployees();
+    this.getTimeTypeList();
   },
   watch: {
     // 监听开始时间和结束时间变化,自动计算时长
@@ -155,6 +251,13 @@
     },
     'overtimeForm.endTime'(newVal) {
       this.calculateDuration();
+    },
+    // 监听时间段表单的开始时间和结束时间变化,自动计算时长
+    'timeForm.startTime'(newVal) {
+      this.calculateTimeFormDuration();
+    },
+    'timeForm.endTime'(newVal) {
+      this.calculateTimeFormDuration();
     }
   },
   methods: {
@@ -179,32 +282,24 @@
         this.overtimeForm.duration = diff.toFixed(2);
       }
     },
+    getTimeTypeList() {
+      this.http.post('/overtime-setting/list',{
+          },
+          res => {
+            if (res.code == "ok") {
+              this.timeTypeList = res.data
+            } else {
+              
+            }
+          },
+          error => {
+          }
+      )
+    },
     // 获取部门树形结构
     searchEmployees() {
-      // this.employeeLoading = true;
-      // this.http.post('/department/list'),{},
-      //     res=> {
-      //       this.employeeLoading = false;
-      //       if (res.code == "ok") {
-      //         this.departmentTree = this.transformDepartmentData(res.data);
-      //       } else {
-      //         this.departmentTree = [];
-      //         this.$message({
-      //           message: res.message || '获取部门数据失败',
-      //           type: "error"
-      //         });
-      //       }
-      //     },
-      //     error => {
-      //       this.employeeLoading = false;
-      //       this.$message({
-      //         message: '请求异常',
-      //         type: "error"
-      //       });
-      //     };
-      //
       this.listLoading = true;
-      this.http.post('/department/userlist',{
+      this.http.post('/department/userListInMyRange',{
           },
           res => {
             this.listLoading = false;
@@ -213,7 +308,7 @@
             } else {
               this.departmentTree = [];
                this.$message({
-                 message: res.message || '获取部门数据失败',
+                 message: res.msg || '获取部门数据失败',
                  type: "error"
                });
             }
@@ -295,16 +390,137 @@
     //   }
     // },
 
-    // 显示添加员工对话框
-    showEmployeeDialog() {
-      this.employeeDialogVisible = true;
-      this.allEmployees = [
-        { id: 1, name: '张三', department: '技术部', position: '前端工程师' },
-        { id: 2, name: '李四', department: '产品部', position: '产品经理' },
-        { id: 3, name: '王五', department: '设计部', position: 'UI设计师' },
-        { id: 4, name: '赵六', department: '技术部', position: '后端工程师' },
-        { id: 5, name: '钱七', department: '测试部', position: '测试工程师' }
-      ];
+    // 计算时间段表单的加班时长
+    calculateTimeFormDuration() {
+      if (this.timeForm.startTime && this.timeForm.endTime) {
+        const start = this.timeForm.startTime.split(':');
+        const end = this.timeForm.endTime.split(':');
+
+        const startDate = new Date();
+        startDate.setHours(start[0], start[1], 0);
+
+        const endDate = new Date();
+        endDate.setHours(end[0], end[1], 0);
+
+        // 处理跨天情况
+        if (endDate < startDate) {
+          endDate.setDate(endDate.getDate() + 1);
+        }
+
+        let diff = (endDate - startDate) / (1000 * 60 * 60); // 转换为小时
+
+        // 检查是否包含午休时间 12:00-13:00,如果包含则减去1小时
+        const lunchStart = new Date();
+        lunchStart.setHours(12, 0, 0);
+        const lunchEnd = new Date();
+        lunchEnd.setHours(13, 0, 0);
+
+        // 如果跨天,午休时间也要相应调整
+        if (endDate.getDate() > startDate.getDate()) {
+          // 跨天情况下,检查第一天是否包含午休
+          if (startDate <= lunchStart) {
+            diff -= 1; // 减去午休1小时
+          }
+        } else {
+          // 同一天内,检查时间段是否包含午休时间
+          if (startDate <= lunchStart && endDate >= lunchEnd) {
+            diff -= 1; // 减去午休1小时
+          }
+        }
+
+        this.timeForm.hours = Math.max(0, diff).toFixed(2); // 确保不为负数
+      }
+    },
+
+    // 显示时间段管理对话框
+    showTimeEditDialog() {
+      this.timeDialogVisible = true;
+    },
+
+    // 序号方法
+    indexMethod(index) {
+      return index + 1;
+    },
+
+    // 显示添加时间段表单
+    showTimeForm() {
+      this.timeFormTitle = '添加时间段';
+      this.timeForm = {
+        id: null,
+        startTime: '',
+        endTime: '',
+        hours: ''
+      };
+      this.timeFormVisible = true;
+    },
+
+    // 编辑时间段
+    editTimeType(row) {
+      this.timeFormTitle = '编辑时间段';
+      this.timeForm = {
+        id: row.id,
+        startTime: row.startTime,
+        endTime: row.endTime,
+        hours: row.hours
+      };
+      this.timeFormVisible = true;
+    },
+
+    // 保存时间段
+    saveTimeType() {
+      this.$refs.timeForm.validate((valid) => {
+        if (valid) {
+          this.timeFormLoading = true;
+          const params = {
+            id: this.timeForm.id,
+            startTime: this.timeForm.startTime,
+            endTime: this.timeForm.endTime,
+            hours: this.timeForm.hours
+          };
+
+          this.http.post('/overtime-setting/addOrUpdate', params,
+            res => {
+              this.timeFormLoading = false;
+              if (res.code == "ok") {
+                this.$message.success(this.timeForm.id ? '编辑成功' : '添加成功');
+                this.timeFormVisible = false;
+                this.getTimeTypeList(); // 重新加载列表
+              } else {
+                this.$message.error(res.msg);
+              }
+            },
+            error => {
+              this.timeFormLoading = false;
+              this.$message.error('请求异常');
+            }
+          );
+        }
+      });
+    },
+
+    // 删除时间段
+    deleteTimeType(row) {
+      this.$confirm('确定要删除这个时间段吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.http.post('/overtime-setting/delete', { id: row.id },
+          res => {
+            if (res.code == "ok") {
+              this.$message.success('删除成功');
+              this.getTimeTypeList(); // 重新加载列表
+            } else {
+              this.$message.error(res.msg || '删除失败');
+            }
+          },
+          error => {
+            this.$message.error('请求异常');
+          }
+        );
+      }).catch(() => {
+        // 用户取消删除
+      });
     },
 
     // 添加员工到加班列表
@@ -323,9 +539,39 @@
     submitForm(formName) {
       this.$refs[formName].validate((valid) => {
         if (valid) {
-          // 这里处理表单提交逻辑
-          console.log('提交表单:', this.overtimeForm);
-          this.$message.success('加班申请提交成功!');
+          // 获取选中的时间段信息
+          const selectedTimeType = this.timeTypeList.find(item => item.id === this.overtimeForm.timeType);
+          if (!selectedTimeType) {
+            this.$message.error('请选择有效的加班时段!');
+            return;
+          }
+
+          // 构建提交参数,映射到后端实体字段
+          const params = {
+            // applicant: 申请人 - 可以从用户信息中获取,这里暂时留空让后端处理
+            employeeIds: this.overtimeForm.employees.join(','), // 加班员工ID列表,用逗号分隔
+            workDate: this.overtimeForm.overtimeDate, // 加班日期
+            startTime: selectedTimeType.startTime, // 加班开始时间
+            endTime: selectedTimeType.endTime, // 加班结束时间
+            hours: parseFloat(selectedTimeType.hours), // 加班时长
+            content: this.overtimeForm.workContent, // 工作内容
+            timeTypeId: this.overtimeForm.timeType, // 加班时段ID
+            mealType: this.overtimeForm.mealType.join(',') // 用餐类别,用逗号分隔
+          };
+
+          this.http.post('/work-overtime/addOrUpdate', params,
+            res => {
+              if (res.code == "ok") {
+                this.$message.success('加班申请提交成功!');
+                this.resetForm(formName); // 重置表单
+              } else {
+                this.$message.error(res.msg || '提交失败');
+              }
+            },
+            error => {
+              this.$message.error('请求异常');
+            }
+          );
         } else {
           this.$message.error('请完善表单信息!');
           return false;
@@ -357,4 +603,4 @@
     width: 100%;
   }
 }
-</style>
+</style>

+ 482 - 4
fhKeeper/formulahousekeeper/timesheet-workshop/src/views/workOvertime/applyList.vue

@@ -1,14 +1,492 @@
 <template>
-<div>111</div>
+  <div class="overtime-list">
+    <el-card class="filter-card">
+      <div slot="header" class="clearfix">
+        <span>加班申请列表</span>
+      </div>
+      
+      <!-- 筛选条件 -->
+      <el-form :model="searchForm" ref="searchForm" :inline="true" label-width="80px">
+        <el-form-item label="申请人">
+          <el-select
+              v-model="searchForm.applicant"
+              placeholder="请选择申请人"
+              style="width: 200px;"
+              clearable
+              filterable>
+            <el-option
+                v-for="user in userList"
+                :key="user.id"
+                :label="user.name"
+                :value="user.id">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        
+        <el-form-item label="加班人员">
+          <el-select
+              v-model="searchForm.employees"
+              placeholder="请选择加班人员"
+              style="width: 250px;"
+              clearable
+              filterable
+              multiple
+              collapse-tags>
+            <el-option
+                v-for="user in userList"
+                :key="user.id"
+                :label="user.name"
+                :value="user.id">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        
+        <el-form-item label="用餐类别">
+          <el-select
+              v-model="searchForm.mealType"
+              placeholder="请选择用餐类别"
+              style="width: 150px;"
+              clearable>
+            <el-option value="中餐" label="中餐"></el-option>
+            <el-option value="晚餐" label="晚餐"></el-option>
+            <el-option value="夜宵" label="夜宵"></el-option>
+          </el-select>
+        </el-form-item>
+        
+        <el-form-item label="加班日期">
+          <el-date-picker
+              v-model="searchForm.dateRange"
+              type="daterange"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              value-format="yyyy-MM-dd"
+              format="yyyy-MM-dd"
+              style="width: 250px;">
+          </el-date-picker>
+        </el-form-item>
+        
+        <el-form-item>
+          <el-button type="primary" @click="searchList">查询</el-button>
+          <el-button @click="resetSearch">重置</el-button>
+          <el-button type="success" @click="exportData">导出</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 数据列表 -->
+    <el-card class="table-card">
+      <el-table
+          :data="tableData"
+          v-loading="listLoading"
+          style="width: 100%"
+          border>
+        <el-table-column type="index" label="序号" width="60" :index="indexMethod"></el-table-column>
+        
+        <el-table-column prop="applicantName" label="申请人" width="100"></el-table-column>
+        
+        <el-table-column prop="employeeNames" label="加班人员" width="200">
+          <template slot-scope="scope">
+            <span>{{ scope.row.employeeNames.length>20? scope.row.employeeNames.substring(0,20)+'...':scope.row.employeeNames}}</span>
+          </template>
+        </el-table-column>
+        
+        <el-table-column prop="workDate" label="加班日期" width="120"></el-table-column>
+        
+        <el-table-column label="加班时间" width="150">
+          <template slot-scope="scope">
+            {{ scope.row.startTime }} - {{ scope.row.endTime }}
+          </template>
+        </el-table-column>
+        
+        <el-table-column prop="hours" label="加班时长" width="100">
+          <template slot-scope="scope">
+            {{ scope.row.hours }}小时
+          </template>
+        </el-table-column>
+        
+        <el-table-column prop="mealType" label="用餐类别" width="120">
+          <template slot-scope="scope">
+            <span v-if="scope.row.mealType">{{ scope.row.mealType }}</span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        
+        <el-table-column prop="content" label="工作内容" min-width="200" show-overflow-tooltip></el-table-column>
+        
+        <el-table-column label="操作" width="150" fixed="right">
+          <template slot-scope="scope">
+            <el-button
+                size="mini"
+                @click="viewDetail(scope.row)">
+              查看
+            </el-button>
+            <el-button v-if="permissions.deleteOvertime"
+                size="mini"
+                type="danger"
+                @click="deleteRecord(scope.row)">
+              删除
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 分页 -->
+      <div class="pagination-container">
+        <el-pagination
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+            :current-page="pagination.currentPage"
+            :page-sizes="[10, 20, 50, 100]"
+            :page-size="pagination.pageSize"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="pagination.total">
+        </el-pagination>
+      </div>
+    </el-card>
+
+    <!-- 详情对话框 -->
+    <el-dialog title="加班申请详情" :visible.sync="detailVisible" width="600px">
+      <div v-if="currentRecord">
+        <el-descriptions :column="2" border>
+          <el-descriptions-item label="申请人">{{ currentRecord.applicantName }}</el-descriptions-item>
+          <el-descriptions-item label="加班日期">{{ currentRecord.workDate }}</el-descriptions-item>
+          <el-descriptions-item label="加班时间">
+            {{ currentRecord.startTime }} - {{ currentRecord.endTime }}
+          </el-descriptions-item>
+          <el-descriptions-item label="加班时长">{{ currentRecord.hours }}小时</el-descriptions-item>
+          <el-descriptions-item label="加班人员" :span="2">{{ currentRecord.employeeNames }}
+          </el-descriptions-item>
+          <el-descriptions-item label="用餐类别" :span="2">
+            <span v-if="currentRecord.mealType">{{ currentRecord.mealType }}</span>
+            <span v-else>-</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="工作内容" :span="2">
+            {{ currentRecord.content }}
+          </el-descriptions-item>
+        </el-descriptions>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="detailVisible = false">关闭</el-button>
+      </span>
+    </el-dialog>
+  </div>
 </template>
 
-<script setup>
+<script>
 export default {
+  name: 'OvertimeApplyList',
+  data() {
+    return {
+      searchForm: {
+        applicant: '',
+        employees: [],
+        mealType: '',
+        dateRange: []
+      },
+      user: JSON.parse(sessionStorage.getItem("user")),
+      permissions: JSON.parse(sessionStorage.getItem("permissions")),
+      departmentTree: [],
+      userList: [],
+      tableData: [],
+      listLoading: false,
+      pagination: {
+        currentPage: 1,
+        pageSize: 20,
+        total: 0
+      },
+      detailVisible: false,
+      currentRecord: null
+    }
+  },
+  mounted() {
+    this.loadDepartmentTree();
+    this.loadUserList();
+    this.loadList();
+  },
+  methods: {
+    // 序号方法
+    indexMethod(index) {
+      return (this.pagination.currentPage - 1) * this.pagination.pageSize + index + 1;
+    },
 
-}
+    // 加载部门树
+    loadDepartmentTree() {
+      this.http.post('/department/userlist', {},
+        res => {
+          if (res.code == "ok") {
+            this.departmentTree = this.transformDepartmentData(res.data);
+          } else {
+            this.departmentTree = [];
+            this.$message({
+              message: res.message || '获取部门数据失败',
+              type: "error"
+            });
+          }
+        },
+        error => {
+          this.$message({
+            message: '请求异常',
+            type: "error"
+          });
+        }
+      );
+    },
+
+    // 加载用户列表
+    loadUserList() {
+      this.http.post('/user/getSimpleActiveUserList', {},
+        res => {
+          if (res.code == "ok") {
+            this.userList = res.data || [];
+          } else {
+            this.userList = [];
+            this.$message({
+              message: res.message || '获取用户列表失败',
+              type: "error"
+            });
+          }
+        },
+        error => {
+          this.$message({
+            message: '请求异常',
+            type: "error"
+          });
+        }
+      );
+    },
+
+    // 转换部门数据为级联选择器格式
+    transformDepartmentData(departments) {
+      return departments.map(dept => {
+        const item = {
+          id: dept.id,
+          label: dept.label,
+          value: dept.id
+        };
+
+        if (dept.children && dept.children.length > 0) {
+          item.children = this.transformDepartmentData(dept.children);
+        }
+
+        if (dept.userList && dept.userList.length > 0) {
+          if (!item.children) {
+            item.children = [];
+          }
+          dept.userList.forEach(user => {
+            item.children.push({
+              id: user.id,
+              label: user.name,
+              value: user.id
+            });
+          });
+        }
+
+        return item;
+      });
+    },
+
+    // 加载列表数据
+    loadList() {
+      this.listLoading = true;
+      
+      const params = {
+        page: this.pagination.currentPage,
+        size: this.pagination.pageSize,
+        applicant: this.searchForm.applicant || undefined,
+        employeeIds: this.searchForm.employees.length > 0 ? this.searchForm.employees.join(',') : undefined,
+        mealType: this.searchForm.mealType || undefined,
+        startDate: this.searchForm.dateRange && this.searchForm.dateRange[0] ? this.searchForm.dateRange[0] : undefined,
+        endDate: this.searchForm.dateRange && this.searchForm.dateRange[1] ? this.searchForm.dateRange[1] : undefined
+      };
+
+      // 移除undefined的参数
+      Object.keys(params).forEach(key => {
+        if (params[key] === undefined) {
+          delete params[key];
+        }
+      });
+
+      this.http.post('/work-overtime/list', params,
+        res => {
+          this.listLoading = false;
+          if (res.code == "ok") {
+            this.tableData = res.data.records || res.data;
+            this.pagination.total = res.data.total || 0;
+          } else {
+            this.$message({
+              message: res.message || '获取数据失败',
+              type: "error"
+            });
+          }
+        },
+        error => {
+          this.listLoading = false;
+          this.$message({
+            message: '请求异常',
+            type: "error"
+          });
+        }
+      );
+    },
+
+    // 根据ID查找员工姓名
+    findEmployeeById(id) {
+      // 首先在userList中查找
+      const userEmployee = this.userList.find(user => user.id === id);
+      if (userEmployee) {
+        return { name: userEmployee.name };
+      }
+      
+      // 如果userList中没有,再在departmentTree中查找(兼容性)
+      const findInTree = (nodes) => {
+        for (let node of nodes) {
+          if (node.id === id && !node.children) {
+            return { name: node.label };
+          }
+          if (node.children) {
+            const found = findInTree(node.children);
+            if (found) return found;
+          }
+        }
+        return null;
+      };
+      return findInTree(this.departmentTree);
+    },
 
+    // 查询
+    searchList() {
+      this.pagination.currentPage = 1;
+      this.loadList();
+    },
+
+    // 重置搜索
+    resetSearch() {
+      this.searchForm = {
+        applicant: '',
+        employees: [],
+        mealType: '',
+        dateRange: []
+      };
+      this.pagination.currentPage = 1;
+      this.loadList();
+    },
+
+    // 导出数据
+    exportData() {
+      // 构建导出参数,使用当前的搜索条件
+      const params = {
+        applicant: this.searchForm.applicant || undefined,
+        employeeIds: this.searchForm.employees.length > 0 ? this.searchForm.employees.join(',') : undefined,
+        mealType: this.searchForm.mealType || undefined,
+        startDate: this.searchForm.dateRange && this.searchForm.dateRange[0] ? this.searchForm.dateRange[0] : undefined,
+        endDate: this.searchForm.dateRange && this.searchForm.dateRange[1] ? this.searchForm.dateRange[1] : undefined
+      };
+
+      // 移除undefined的参数
+      Object.keys(params).forEach(key => {
+        if (params[key] === undefined) {
+          delete params[key];
+        }
+      });
+
+      this.http.post('/work-overtime/export', params,
+        res => {
+          if (res.code == "ok" && res.data) {
+            // 创建隐藏的a标签进行下载
+            const link = document.createElement('a');
+            link.href = res.data;
+            link.download = ''; // 让浏览器自动确定文件名
+            link.style.display = 'none';
+            document.body.appendChild(link);
+            link.click();
+            document.body.removeChild(link);
+            
+            this.$message.success('导出成功');
+          } else {
+            this.$message.error(res.message || '导出失败');
+          }
+        },
+        error => {
+          this.$message.error('导出请求异常');
+        }
+      );
+    },
+
+    // 分页大小改变
+    handleSizeChange(val) {
+      this.pagination.pageSize = val;
+      this.pagination.currentPage = 1;
+      this.loadList();
+    },
+
+    // 当前页改变
+    handleCurrentChange(val) {
+      this.pagination.currentPage = val;
+      this.loadList();
+    },
+
+    // 查看详情
+    viewDetail(row) {
+      this.currentRecord = row;
+      this.detailVisible = true;
+    },
+
+    // 编辑记录
+    editRecord(row) {
+      // 这里可以跳转到编辑页面或打开编辑对话框
+      this.$router.push({
+        path: '/work-overtime/apply',
+        query: { id: row.id }
+      });
+    },
+
+    // 删除记录
+    deleteRecord(row) {
+      this.$confirm('确定要删除这条加班申请记录吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.http.post('/work-overtime/delete', { id: row.id },
+          res => {
+            if (res.code == "ok") {
+              this.$message.success('删除成功');
+              this.loadList(); // 重新加载列表
+            } else {
+              this.$message.error(res.message || '删除失败');
+            }
+          },
+          error => {
+            this.$message.error('请求异常');
+          }
+        );
+      }).catch(() => {
+        // 用户取消删除
+      });
+    }
+  }
+}
 </script>
 
 <style scoped lang="scss">
+.overtime-list {
+  padding: 20px;
 
-</style>
+  .filter-card {
+    margin-bottom: 20px;
+  }
+
+  .table-card {
+    .pagination-container {
+      margin-top: 20px;
+      text-align: right;
+    }
+  }
+
+  .el-tag {
+    margin-right: 5px;
+    margin-bottom: 2px;
+  }
+}
+</style>

+ 25 - 4
fhKeeper/formulahousekeeper/timesheet/src/components/taskComponent.vue

@@ -1,7 +1,7 @@
 <template>
   <div>
     <div style="height: 72vh;overflow: auto;">
-        <el-form ref="form1" :model="addForm" :rules="taskRules" label-width="120px">
+        <el-form ref="form1" :model="addForm" :rules="user.companyId == 7783?zysbTaskRules:taskRules" label-width="120px">
             <template>
                 <el-form-item :label="$t('subordinatetotheproject')" v-if="showOrNot" prop="projectId">
                     <el-select v-model="addForm.projectId" :placeholder="$t('defaultText.pleaseChoose')" @change="agentCreatesEvents(1)" filterable="true" style="width:100%;" :disabled="doYouWantToDisableAll">
@@ -77,7 +77,7 @@
             <div style="border: 1px solid #ddd;margin:5px 0;padding:5px 0;">
             <div class="container" :style="{ maxHeight: '300px' }" ref="container">
                 <div class="list">
-                    <el-form-item :label="$t('zhi-hang-ren') + (index + 1)" v-for="(executorItem, index) in this.addForm.executorListFront" :key="index">
+                    <el-form-item :label="$t('zhi-hang-ren') + (index + 1)" v-for="(executorItem, index) in this.addForm.executorListFront" :key="index" :required="user.companyId == 7783?true:false">
                         <div class="editingTask">
                             <div style="margin-right: 30px;display: flex;align-items: center;">
                                 <div class="imitateTheInputBox-text" v-if="(addForm.id != null && user.id != addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement && !permissions.editAnyTask && !(groupResponsibleId == user.id)">
@@ -924,6 +924,14 @@ export default {
             taskPlanType: [{ required: true, message: '请选择类型', trigger: "blur" }],
             checkSecondId: [{ required: true, message: '请选择审核人', trigger: "blur" }]
         },
+        zysbTaskRules : {
+            name: [{ required: true, message: this.$t('enterthetaskcontent'), trigger: "blur" }],
+            projectId: [{ required: true, message: this.$t('qingXuanZeSuoShuXiangMu'), trigger: "blur" }],
+            groupId: [{ required: true, message: this.$t('qingXuanZeSuoShuRenWuFenZu'), trigger: "blur" }],
+            stagesId: [{ required: true, message: this.$t('qingXuanZeSuoShuRenWuLieBiao'), trigger: "blur" }],
+            startDate: [{ required: true, message: '请选择开始日期', trigger: "blur" }],
+            endDate: [{ required: true, message: '请选择结束日期', trigger: "blur" }],
+        },
         formGrouping: {
             name: [{ required: true, message: this.$t('pleaseenteragroupname'), trigger: "blur" }],
         },
@@ -1945,12 +1953,25 @@ export default {
             }
         }
 
-        if(this.showMmeiLaiDe && !this.addForm.endDate) {
-            return this.$message({
+        if(this.user.companyId == 7783) {
+            if (!this.addForm.endDate) {
+                return this.$message({
                     showClose: true,
                     message: '请选择截止时间',
                     type: 'warning'
                 });
+            }
+            if (this.addForm.executorListFront.length > 0) {
+                for (var i=0;i<this.addForm.executorListFront.length;i++) {
+                    if (!this.addForm.executorListFront[i].executorId) {
+                        return this.$message({
+                            showClose: true,
+                            message: '请选择执行人',
+                            type: 'warning'
+                        });
+                    }
+                }
+            }
         }
         this.$refs.form1.validate(valid => {
             if (valid) {

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/centerManage/centerManage.vue

@@ -371,7 +371,7 @@ export default {
                 this.addfm.name = subProject.name
                 this.addfm.id = subProject.id
                 this.addfm.rmark = subProject.rmark
-                this.addfm.positionArray = subProject.position.split(",")
+                this.addfm.positionArray = subProject.position?subProject.position.split(","):[]
             } else {
                 this.addfm = { name: '', rmark: '' ,positionArray:[]}
             }

+ 15 - 28
fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue

@@ -390,16 +390,14 @@
                     <el-button v-if="(permissions.projectManagement || user.id==scope.row.creatorId) && user.timeType.mainProjectState != '1' && !user.timeType.hideSubproject" size="mini"  @click="subProject(scope.row)">{{ $t('lable.subproject') }}</el-button>
                     <el-button size="mini" v-if="permissions.projectParticipator || permissions.projectManagement || user.id==scope.row.inchargerId || user.id==scope.row.creatorId" type="primary" @click="handleAdd(scope.$index, scope.row)">{{ $t('bian-ji') }}</el-button>
                     <!-- <el-button v-if="permissions.projectManagement || user.id==scope.row.creatorId" size="mini"  @click="deletePro(scope.$index, scope.row)">删除</el-button> -->
-                     <!--如果是威派格,项目经理不给权限-->
-                    <el-dropdown class="customdropdown" split-button size="mini" @click="finishPro(scope.row)" v-if="(user.companyId != 936 || user.id!=scope.row.inchargerId) && (permissions.projectManagement || user.id==scope.row.creatorId || user.id==scope.row.inchargerId) && scope.row.status == 1" placement="bottom-start">
+                    <el-dropdown class="customdropdown" split-button size="mini" @click="finishPro(scope.row)" v-if="user.id!=scope.row.inchargerId && (permissions.projectManagement || user.id==scope.row.creatorId || user.id==scope.row.inchargerId) && scope.row.status == 1" placement="bottom-start">
                         {{ $t('wan-cheng') }} 
                         <el-dropdown-menu slot="dropdown" class="customdropdown_menu">
                             <el-button size="mini"  @click="cancelPro(scope.row)" class="customdropdown_menu_btn">{{ $t('btn.undo') }}</el-button><br>
                             <el-button size="mini"  @click="suspendPro(scope.row)" class="customdropdown_menu_btn">{{ $t('zan-ting') }}</el-button><br>
                         </el-dropdown-menu>
                     </el-dropdown>
-                    <!--如果是威派格,项目经理不给权限-->
-                    <el-button v-if="(user.companyId != 936 || user.id!=scope.row.inchargerId)&& (permissions.projectManagement || user.id==scope.row.inchargerId || user.id==scope.row.creatorId) && scope.row.status >= 2" size="mini"  @click="restartPro(scope.row)">{{ $t('zhong-qi') }}</el-button>
+                    <el-button v-if="user.id!=scope.row.inchargerId&& (permissions.projectManagement || user.id==scope.row.inchargerId || user.id==scope.row.creatorId) && scope.row.status >= 2" size="mini"  @click="restartPro(scope.row)">{{ $t('zhong-qi') }}</el-button>
                 </template>
             </el-table-column>
         </el-table>
@@ -449,7 +447,7 @@
         <!--新增界面-->
         <el-dialog :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="960px" :top="'6vh'">
             <div style="height: 72vh;overflow-y: auto;overflow-x: hidden;">
-                <el-form ref="form1" :model="addForm" :rules="rules" label-width="120px">
+                <el-form ref="form1" :model="addForm" :rules="user.companyId == 7783?zysbRules:rules" label-width="120px">
                     <el-form-item :label="user.companyId == '7030' ? '项目令号' : $t('Itemno')" :class="title == $t('newproject')" v-if="user.companyId!=936">
                         <!-- <el-input v-model="addForm.code" :disabled="!permissions.projectManagement && addForm.creatorId != user.id" placeholder="请输入项目编号" clearable></el-input> -->
                         <el-input v-model="addForm.code" :placeholder="$t('peaseenterthe')" clearable :disabled="canOnlyModParticipator || (!permissions.projectManagement && addForm.creatorId != user.id && !permissions.projectCodeAndName)" maxlength="50" show-word-limit="true"></el-input>
@@ -467,7 +465,7 @@
                             </el-option>
                         </el-select>
                     </el-form-item>
-                    <el-form-item :label="$t('projectclassification')" v-if="user.timeType.mainProjectState != '1'">
+                    <el-form-item :label="$t('projectclassification')" v-if="user.timeType.mainProjectState != '1'"  prop="category">
                         <!-- <el-select v-model="addForm.category"  style="width:32%;" clearable :disabled="!permissions.projectManagement && addForm.creatorId != user.id"> -->
                         <el-select v-model="addForm.category"  style="width:32%;" clearable filterable :disabled="canOnlyModParticipator">
                             <el-option v-for="(item) in baseClfList" :key="item.id" :value="item.id" :label="item.name"></el-option>
@@ -519,11 +517,6 @@
                             </span> 
                         </el-select>
                     </el-form-item>
-                    <!-- <el-form-item label="客户" v-if="user.company.packageCustomer == 1">
-                        <el-select v-model="addForm.customerId" clearable="true" filterable placeholder="请选择客户" style="width:100%;" >
-                            <el-option v-for="item in customerList" :key="item.id" :label="item.customerName" :value="item.id"></el-option>
-                        </el-select>
-                    </el-form-item> -->
                     <el-form-item :label="$t('Allparticipants')" v-show="addForm.isPublic == 0" :class="title == $t('newproject') && user.companyId == 936 ? 'wpgCssClass' : ''">
                         <el-tooltip placement="top" effect="light" v-if="user.userNameNeedTranslate != 1">
                             <div slot="content" style="width:580px">{{addForm.userNames}}</div>
@@ -548,7 +541,7 @@
                             </div>
                         </el-tooltip>
                     </el-form-item>
-                    <el-form-item :label="$t('projectmanager')" :class="title == $t('newproject') && user.companyId == 936 ? 'wpgCssClass' : ''" v-if="user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0)">
+                    <el-form-item :label="$t('projectmanager')" :class="title == $t('newproject') && user.companyId == 936 ? 'wpgCssClass' : ''" v-if="user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0)" prop="inchargerId">
                        <el-select v-if="user.userNameNeedTranslate != 1" v-model="addForm.inchargerId" filterable :placeholder="$t('defaultText.pleaseChoose')" style="width:32%;" :disabled="canOnlyModParticipator || projectManagerEdit" @change="changeInchargerId">
                             <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id">
                                 <span style="float: left">{{ item.name }}</span>
@@ -567,19 +560,13 @@
                         </el-select>
                         <selectCat v-if="user.timeType.reportAuditType == 8 && user.userNameNeedTranslate == 1" :filterable="true" :size="'medium'" :subject="users" :subjectId="addForm.reviwerId" :distinction="'4'" @selectCal="selectCal" :disabled="canOnlyModParticipator || projectManagerEdit || isShowProjectName"></selectCat>
                     </el-form-item>
-
-                    <el-form-item label="LA" v-if="user.companyId == 876">
-                        <el-select v-model="addForm.leaderId" multiple placeholder="请选择LA" filterable style="width: 100%">
-                            <el-option v-for="item in (participator || []).filter(em => em.id != addForm.inchargerId)" :key="item.id" :label="item.name" :value="item.id"></el-option>
-                          </el-select>
-                    </el-form-item>
-
                     <span v-if="user.companyId != 469">
-                        <el-form-item :label="$t('newspaperauditor')" v-show="user.timeType.reportAuditType == 0 || user.timeType.reportAuditType == 4 || user.timeType.reportAuditType == 6 || user.timeType.reportAuditType == 9" v-if="user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0)">
+                        <el-form-item :label="$t('newspaperauditor')" v-show="user.timeType.reportAuditType == 0 || user.timeType.reportAuditType == 4 || user.timeType.reportAuditType == 6 || user.timeType.reportAuditType == 9" v-if="user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0)" prop="auditUserIds" >
                             <el-select v-if="user.userNameNeedTranslate != '1'" @change="$forceUpdate()" v-model="addForm.auditUserIds"  :disabled="!(permissions.projectManagement|| user.id == addForm.inchargerId || user.id == addForm.creatorId)" filterable :placeholder="$t('defaultistheprojectleader')" style="width:100%;" :multiple="user.timeType.reportAuditType != 6 && user.timeType.reportAuditType != 9" >
                                 <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id"></el-option>
                             </el-select>
                             <selectCat v-if="user.userNameNeedTranslate == '1'" :size="'medium'" :tile="true" :filterable="true" :widthStr="'800'" :disabled="!(permissions.projectManagement|| user.id == addForm.inchargerId || user.id == addForm.creatorId)" :subjectId="addForm.auditUserIds" :subject="participator" :clearable="false" :distinction="'10'"  :multiSelect="user.timeType.reportAuditType != 6 && user.timeType.reportAuditType != 9" @selectCal="selectCal"></selectCat>
+                            <!-- <selectCat v-if="user.userNameNeedTranslate == '1'" :filterable="true" :size="'medium'"  :subjectId="addForm.auditUserIds" :subject="participator" :distinction="'10'"  @selectCal="selectCal"  :disabled="!(permissions.projectManagement|| user.id == addForm.inchargerId || user.id == addForm.creatorId)"></selectCat> -->
                         </el-form-item>
                     </span>
                     
@@ -603,7 +590,7 @@
                             placeholder="整数" clearable  @keyup.native="restrictNumber('contractAmount')" :disabled="title == '新增项目' ? false : false"></el-input><span style="margin-left:10px;">元</span> -->
                     </el-form-item>
                     <!-- 增加合同金额字段 -->
-                    <el-form-item  :label="$t('contractamount')" v-if="(user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0))">
+                    <el-form-item  :label="$t('contractamount')" v-if="(user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0))" prop="contractAmount">
                         <el-input id="contractAmount" v-model="addForm.contractAmount" :disabled="canOnlyModParticipator" style="width:32%;" @input="contractAmountChange(addForm.contractAmount)" :placeholder="$t('zheng-shu')" clearable maxlength="9"  @keyup.native="restrictNumber('contractAmount')"></el-input><span style="margin-left:10px;position:absolute;">{{ $t('yuan') }}</span>
                         <template v-if="title == $t('modifytheproject') && contractAmountReasonShow">
                             <span style="margin-left:63px;margin-right:10px;">{{ $t('modifythereason') }}</span>
@@ -1980,6 +1967,13 @@ a {
                     projectLevelName: [{ required: true, message: this.$t('pleaseentername'), trigger: "blur" }],
                     deptId: [{ required: true, message: this.$t('qingXuanZeSuoShuBuMen'), trigger: "blur" }]
                 },
+                zysbRules: {
+                    name: [{ required: true, message: this.$t('pleaseentername'), trigger: "blur" }],
+                    category: [{ required: true, message: '请选择项目分类', trigger: ["blur","change"] }],
+                    inchargerId: [{ required: true, message: '请选择项目经理', trigger: ["blur","change"] }],
+                    contractAmount: [{ required: true, message: '请输入合同金额', trigger: "blur" }],
+                    planStartDate: [{ required: true, message: '请输入计划开始日期', trigger: "blur" }]
+                },
                 ause: [],
                 auseList: [],
                 yonghuUser: [],
@@ -5987,13 +5981,6 @@ a {
                     this.addForm.auditUserIds = (arrUserList && arrUserList.length) 
                         ? arrUserList.map(user => user.id)
                         : id;
-                    // let userList = obj.arrUserList
-                    // let arr = []
-                    // for(var i in userList) {
-                    //     arr.push(userList[i].id)
-                    // }
-                    // this.participator = JSON.parse(JSON.stringify(this.participator))
-                    // this.addForm.auditUserIds = arr
                 } else if(obj.distinction == '11') {
                     let userList = obj.id
                     console.log(obj)

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

@@ -1200,7 +1200,7 @@
                 <el-button type="primary" @click="changeBudgetTrue(groupBudgetData)" :loading="addLoading">{{ $t('btn.submit') }}</el-button>
             </div>
         </el-dialog>
-        <el-dialog :title="$t('addtemplate')" v-if="addToTmpDialog" :visible.sync="addToTmpDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
+        <el-dialog :title="$t('addtemplate')" v-if="addToTmpDialog" :visible.sync="addToTmpDialog" :close-on-click-modal="false" customClass="customWidth" width="550px">
             <el-form ref="formTmp" :model="templateForm" :rules="rules" style="margin-top:10px;">
                     <el-form-item prop="name">
                         <el-input v-model="templateForm.name" :placeholder="$t('entertemplatename')" maxlength="12"
@@ -1210,7 +1210,8 @@
                                 <el-checkbox v-model="templateForm.saveTask" :label="$t('other.task')"></el-checkbox>
                                 <el-checkbox v-model="templateForm.saveMileStone" :label="$t('other.milestone')"></el-checkbox>
                                 <el-checkbox v-model="templateForm.saveRisk" :label="$t('risk')"></el-checkbox>
-                                <el-checkbox v-model="templateForm.automatically" :label="$t('suixiangmuzidongchuangjian')"></el-checkbox>
+                                <el-checkbox v-model="templateForm.saveTaskFiles" label="相关文件" :disabled="!(templateForm.saveTask || templateForm.saveMileStone || templateForm.saveRisk)"></el-checkbox>
+                                <br/><el-checkbox v-model="templateForm.automatically" :label="$t('suixiangmuzidongchuangjian')"></el-checkbox>
                             </div>
                     </el-form-item>
             </el-form>
@@ -2183,7 +2184,7 @@
             },
             addToTemplate(item) {
                 this.addToTmpDialog = true;
-                this.templateForm = {groupId: item.id, name:item.name, saveTask:false, saveMileStone:false, saveRisk:false};
+                this.templateForm = {groupId: item.id, name:item.name, saveTask:false, saveTaskFiles:false, saveMileStone:false, saveRisk:false};
             },
             changeBase() {
                 // this.$refs.earning.refreshPage();

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

@@ -151,7 +151,7 @@
                                     <el-link type="primary" v-if="user.timeType.pushReportData == 1 && permissions.reportPush" :underline="false" @click="pushWorkTime">{{ $t('tuiSongGongShi') }}</el-link>
                                     <el-link type="primary" v-if="user.timeType.pushReportData == 1 && user.companyId==3092 && permissions.reportPush" :underline="false" @click="pushWorkTimeLogDig=true,getPushWorkLogData()">{{ $t('gongShiTuiSongRiZhi') }}</el-link>
                                     <el-link type="primary" v-if="user.roleName == $t('role.superAdministrator') && user.companyId==839" :underline="false" @click="reportLogCheckDialog=true">{{ $t('riBaoShenHeXiuGai') }}</el-link>
-                                    <el-link type="primary" v-if="(user.roleName == $t('role.superAdministrator') || user.roleName == $t('role.systemAdministrator')) && user.companyId==936" :underline="false" @click="transferWorkingHoursVisable=true">{{ $t('zhuanYIGongShi') }}</el-link>
+                                    <el-link type="primary" v-if="(user.roleName == $t('role.superAdministrator') || user.roleName == $t('role.systemAdministrator')) && user.companyId==5916" :underline="false" @click="transferWorkingHoursVisable=true">{{ $t('zhuanYIGongShi') }}</el-link>
                                     <!-- <el-button v-if="user.timeType.pushReportData == 1 && permissions.reportPush" style="margin-left:10px;" icon="iconfont firerock-icontuisong" size="mini" @click="pushWorkTime"></el-button> -->
                                 </span>
                             </div>
@@ -770,8 +770,8 @@
                                 <el-option v-for="item in domain.serviceList" :key="item.id" :label="item.serviceName" :value="item.id"></el-option>
                             </el-select>
                         </el-form-item>
-                        <!--工作事项-->
-                        <el-form-item :label="$t('other.workMatters') " :prop="'domains.' + index + '.content'" 
+                        <!--工作事项--> <!-- 加力股份不需要工作内容填报 -->
+                        <el-form-item :label="$t('other.workMatters') " :prop="'domains.' + index + '.content'" v-if="user.companyId != 7544"
                         :rules="user.timeType.workContentState == 1 ? { required: true, message: $t('other.tianworkMatters'), trigger: 'blur' } : null">
                             <el-input v-model="domain.content" type="textarea" :rows="4" :placeholder="$t('defaultText.pleaseFillOut')" clearable style="width:75%;margin-right:7%"
                             :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)"></el-input>
@@ -1275,7 +1275,7 @@
                         <el-col span="10"><span style="float:right;"><span style="margin-right:10px;">{{zhoBao.progress || 0}}%</span>{{zhoBao.workingTime | amounts}}{{$t('time.hour')}}</span></el-col>
                     </div>
                 </div>
-                <div class="zhoFel">
+                <div class="zhoFel" v-if="user.companyId != 7544">
                     <p>{{$t('other.workMatters')}}</p>
                     <el-input type="textarea" v-model="zhoBao.content" :placeholder="$t('other.tianworkMatters')" style="width: 355px" clearable></el-input>
                 </div>

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

@@ -425,7 +425,7 @@
                                 </div>
                             </template>
                         </van-cell>
-                        <van-field class="form_input" :disabled="!item.canEdit" v-model="item.content" name="content"
+                        <van-field class="form_input" :disabled="!item.canEdit" v-model="item.content" name="content" v-if="user.companyId != 7544"
                             type="textarea" :label="user.companyId == 781 ? '具体内容与结果' : '工作事项'" placeholder="请输入"
                             :rules="user.timeType.workContentState == 1 ? [{ required: true, message: '请填写工作事项' }] : null"
                             rows="3" autosize />

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

@@ -317,7 +317,7 @@
                                 </div>
                             </template>
                         </van-cell>
-                        <van-field class="form_input"
+                        <van-field class="form_input" v-if="user.companyId != 7544"
                         v-model="item.content" name="content" type="textarea" :label="user.companyId==781?'具体内容与结果': user.companyId == wuqiId ? '日报' : '工作事项'" :placeholder="user.companyId == wuqiId ? '所在项目负责哪一模块(可重复填写),无需涉及技术细节。' : '请输入'" :disabled="item.state<=1"
                         rows="3" autosize :rules="user.timeType.workContentState == 1 ? [{ required: true, message: user.companyId==781?'具体内容与结果':user.companyId == wuqiId ? '日报' : '工作事项' }] : null" :maxlength="user.companyId == wuqiId ? 30 : 150" />
                         </div>