Przeglądaj źródła

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

山水共长天一色 3 lat temu
rodzic
commit
eafa98b400
39 zmienionych plików z 647 dodań i 121 usunięć
  1. 14 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/CompanyDingdingController.java
  2. 10 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java
  3. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportAuditLogController.java
  4. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/StagesController.java
  5. 11 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java
  6. 7 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/CompanyDingdingService.java
  7. 4 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java
  8. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/TaskService.java
  9. 113 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/CompanyDingdingServiceImpl.java
  10. 4 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java
  11. 24 12
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectAddcostRecordServiceImpl.java
  12. 127 19
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  13. 10 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  14. 37 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java
  15. 49 24
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  16. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  17. 9 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/Sha1Util.java
  18. 6 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  19. 5 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml
  20. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  21. 1 1
      fhKeeper/formulahousekeeper/octopus/config/index.js
  22. 5 1
      fhKeeper/formulahousekeeper/octopus/src/views/customer/list.vue
  23. 7 0
      fhKeeper/formulahousekeeper/octopus/src/views/market/list.vue
  24. 29 1
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/controller/CompanyController.java
  25. 21 0
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/controller/VcompanyCustomerContactController.java
  26. 21 0
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/controller/WxCorpInfoController.java
  27. 6 0
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/entity/Company.java
  28. 12 6
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/entity/VcompanyCustomerContact.java
  29. 1 1
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/entity/WxCorpInfo.java
  30. 16 0
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/mapper/WxCorpInfoMapper.java
  31. 16 0
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/service/WxCorpInfoService.java
  32. 20 0
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  33. 1 3
      fhKeeper/formulahousekeeper/ops-platform/src/main/resources/application.yml
  34. 3 1
      fhKeeper/formulahousekeeper/ops-platform/src/main/resources/mapper/VcompanyCustomerContactMapper.xml
  35. 6 6
      fhKeeper/formulahousekeeper/timesheet/package-lock.json
  36. 2 1
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue
  37. 28 12
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  38. 4 4
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list_import.vue
  39. 10 10
      fhKeeper/formulahousekeeper/timesheet_h5/vue.config.js

+ 14 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/CompanyDingdingController.java

@@ -31,9 +31,22 @@ public class CompanyDingdingController {
     @RequestMapping("/pushAlertMsg")
     public HttpRespMsg pushAlertMsg(String corpid, String userDingId) {
         CompanyDingding companyDingding = companyDingdingMapper.selectById(corpid);
-        companyDingdingService.sendFillReportAlertMsg(companyDingding.getCompanyId(), 1339030842L, "填入日报哦", "040534176023851922");
+        companyDingdingService.sendFillReportAlertMsg(companyDingding.getCompanyId(), companyDingding.getAgentId(), "填入日报哦", "040534176023851922");
         return new HttpRespMsg();
     }
 
+    @RequestMapping("/pushFinishMileStoneMsg")
+    public HttpRespMsg pushFinishMileStoneMsg(String corpid, String userDingId) {
+        CompanyDingding companyDingding = companyDingdingMapper.selectById(corpid);
+        companyDingdingService.sendFinishMileStoneMsg(companyDingding, "040534176023851922", "获取伦理批件", "工时管家");
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/sendOAMsg")
+    public HttpRespMsg sendOAMsg(String corpid, String userDingId) {
+        CompanyDingding companyDingding = companyDingdingMapper.selectById(corpid);
+        companyDingdingService.sendOAMsg(companyDingding, "040534176023851922", null);
+        return new HttpRespMsg();
+    }
 }
 

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

@@ -432,5 +432,15 @@ public class ProjectController {
         return projectService.exportBaseCostAndRealCost(request);
     }
 
+    //按照获取一批项目下的分组合集
+    @RequestMapping("/getProjectsGroups")
+    public HttpRespMsg getProjectsGroups(String projectIdArray) {
+        return projectService.getProjectsGroups(projectIdArray);
+    }
+
+    @RequestMapping("/batchAddMembToGroup")
+    public HttpRespMsg batchAddMembToGroup(String membIdArray, String groupIds) {
+        return projectService.batchAddMembToGroup(membIdArray, groupIds);
+    }
 }
 

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

@@ -55,7 +55,7 @@ public class ReportAuditLogController {
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
         HttpRespMsg msg = new HttpRespMsg();
-        List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "导入日报记录");
+        List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看导审记录");
         if (functionList.size() > 0) {
             QueryWrapper<ReportAuditLog> queryWrapper = new QueryWrapper<>();
             queryWrapper.eq("company_id", companyId).eq("audit_channel", 0).orderByDesc("indate");

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

@@ -195,14 +195,14 @@ public class StagesController {
         //没有权限只能看到自己创建的,负责的和待分配的任务
         List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全部任务");
         if (functionList.size() == 0 && !userId.equals(project.getInchargerId())) {
-            tasks = tasks.stream().filter(t->t.getExecutorId() == null || t.getExecutorId().contains(userId) || t.getCreaterId().equals(userId)).collect(Collectors.toList());
+            tasks = tasks.stream().filter(t->t.getExecutorId() == null || t.getExecutorId().contains(userId) || userId.equals(t.getCreaterId())).collect(Collectors.toList());
         }
         List<Task> subTasks = new ArrayList<>();
         if (tasks.size() > 0) {
             List<Integer> collect = tasks.stream().map(Task::getId).collect(Collectors.toList());
             List<Task> subLists = taskService.simpleList(new QueryWrapper<Task>().in("parent_tid", collect));
             if (functionList.size() == 0 && !userId.equals(project.getInchargerId())) {
-                subLists = subLists.stream().filter(t->t.getExecutorId() == null || t.getExecutorId().contains(userId) || t.getCreaterId().equals(userId)).collect(Collectors.toList());
+                subLists = subLists.stream().filter(t->t.getExecutorId() == null || t.getExecutorId().contains(userId) || userId.equals(t.getCreaterId())).collect(Collectors.toList());
             }
             subTasks.addAll(subLists);
         }

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

@@ -10,6 +10,7 @@ import com.management.platform.entity.vo.SysRichFunction;
 import com.management.platform.mapper.*;
 import com.management.platform.service.*;
 import com.management.platform.util.HttpRespMsg;
+import org.assertj.core.util.Lists;
 import org.opencv.features2d.SimpleBlobDetector;
 import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.transaction.annotation.Transactional;
@@ -240,6 +241,8 @@ public class TaskController {
     @RequestMapping("/finish")
     public HttpRespMsg finish(Task task) {
         HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
         //进行完成操作时需要检查子任务是否全部完成
         if (task.getTaskStatus() == 0) {
             QueryWrapper<Task> subQuery = new QueryWrapper<Task>();
@@ -250,8 +253,10 @@ public class TaskController {
                 return msg;
             }
         }
+        boolean isFinishTask = false;
         if (task.getTaskStatus() == 0) {
             task.setTaskStatus(1);
+            isFinishTask = true;
             task.setFinishDate(LocalDate.now());
             //计算排序,需要移动到最后
             Task old = taskService.getById(task.getId());
@@ -276,6 +281,11 @@ public class TaskController {
         }
 
         taskService.updateById(task);
+        ArrayList<Integer> finishedTaskIds = Lists.list(task.getId());
+        if (isFinishTask) {
+            taskService.notifyMileStoneFinish(user.getCompanyId(), finishedTaskIds);
+        }
+
         //更新项目完成度
         Task item = taskService.getById(task.getId());
         if (item.getParentTid() == null) {
@@ -289,7 +299,6 @@ public class TaskController {
                 project.setProgress(progress);
                 projectService.updateById(project);
             }
-
         }
         return msg;
     }
@@ -396,7 +405,7 @@ public class TaskController {
         //没有权限只能看到自己创建的,负责的和待分配的任务
         List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全部任务");
         if (functionList.size() == 0 && !userId.equals(project.getInchargerId())) {
-            list = list.stream().filter(t->t.getExecutorId() == null || t.getExecutorId().contains(userId) || t.getCreaterId().equals(userId)).collect(Collectors.toList());
+            list = list.stream().filter(t->t.getExecutorId() == null || t.getExecutorId().contains(userId) || userId.equals(t.getCreaterId())).collect(Collectors.toList());
         }
         //设置列表名称
         list.forEach(item->{

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

@@ -4,6 +4,8 @@ import com.management.platform.entity.CompanyDingding;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.management.platform.entity.WxCorpInfo;
 
+import java.util.HashMap;
+
 /**
  * <p>
  *  服务类
@@ -25,4 +27,9 @@ public interface CompanyDingdingService extends IService<CompanyDingding> {
     public void sendBusinessTripSettingMsg(Integer companyId, Long agentId, String useridList);
 
     public void sendNewTaskMsg(CompanyDingding dingding, String userId, String title, String endDate);
+
+
+    public void sendFinishMileStoneMsg(CompanyDingding dingding, String useridList, String taskName, String project);
+
+    public void sendOAMsg(CompanyDingding dingding, String useridList, HashMap map);
 }

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

@@ -121,4 +121,8 @@ public interface ProjectService extends IService<Project> {
     HttpRespMsg getBaseCostAndRealCost(Integer pageIndex, Integer pageSize, HttpServletRequest request);
 
     HttpRespMsg exportBaseCostAndRealCost(HttpServletRequest request);
+
+    HttpRespMsg getProjectsGroups(String projectIdArray);
+
+    HttpRespMsg batchAddMembToGroup(String membIdArray, String groupIds);
 }

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

@@ -46,4 +46,6 @@ public interface TaskService extends IService<Task> {
     HttpRespMsg removeMileStoneTask(Integer id);
 
     HttpRespMsg getMilestoneTaskList(Integer milestoneId);
+
+    public void notifyMileStoneFinish(Integer companyId, List<Integer> taskIdList);
 }

+ 113 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/CompanyDingdingServiceImpl.java

@@ -9,8 +9,10 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.dingtalk.api.DefaultDingTalkClient;
 import com.dingtalk.api.DingTalkClient;
 import com.dingtalk.api.request.OapiGettokenRequest;
+import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
 import com.dingtalk.api.request.OapiMessageCorpconversationSendbytemplateRequest;
 import com.dingtalk.api.request.OapiServiceGetSuiteTokenRequest;
+import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
 import com.dingtalk.api.response.OapiMessageCorpconversationSendbytemplateResponse;
 import com.dingtalk.api.response.OapiServiceGetSuiteTokenResponse;
 import com.management.platform.entity.CompanyDingding;
@@ -20,10 +22,12 @@ import com.management.platform.mapper.SysConfigMapper;
 import com.management.platform.service.CompanyDingdingService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.taobao.api.ApiException;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
+import java.util.HashMap;
 
 /**
  * <p>
@@ -49,11 +53,13 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
     public static final String TEMPLATE_BUSTRIP_SETTING = "68cc6f3a150f4d869449e83a2f249b65";
     //新任务
     public static final String TEMPLATE_NEW_TASK = "b09b32a0431a47bdb791ba286e6d82ba";
-
-
+    //里程碑完成通知
+    public static final String TEMPLATE_FINISH_MILESTONE = "d171680279894f20b90d5c3e7679e1ac";
 
     @Resource
     private SysConfigMapper sysConfigMapper;
+    @Value("${dingding.appId}")
+    private long appId;//钉钉第三方应用的appId
 
     @Override
     public void sendFillReportAlertMsg(Integer companyId, Long agentId, String msg, String useridList) {
@@ -65,7 +71,11 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
 //        req.setDeptIdList("421897262");
         req.setUseridList(useridList);
         req.setTemplateId(TEMPLATE_ALERT_REPORT);
-        req.setData("{\"msg\":\""+msg+"\"}");
+        JSONObject json = new JSONObject();
+        json.put("APPID", appId);
+        json.put("CORPID", dingding.getCorpid());
+        json.put("msg", msg);
+        req.setData(json.toJSONString());
         OapiMessageCorpconversationSendbytemplateResponse rsp = null;
         try {
             rsp = client.execute(req, getCorpAccessToken(dingding));
@@ -90,6 +100,8 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
         json.put("project", projectNames);
         json.put("reason", reason);
         json.put("auditUser", auditorName);
+        json.put("APPID", appId);
+        json.put("CORPID", dingding.getCorpid());
         req.setData(json.toJSONString());
         OapiMessageCorpconversationSendbytemplateResponse rsp = null;
         try {
@@ -116,6 +128,8 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
         json.put("employeeName", "张辉");
         json.put("deptName", "质量部");
         json.put("date", "2022-03-29");
+        json.put("APPID", appId);
+        json.put("CORPID", dingding.getCorpid());
         req.setData(json.toJSONString());
         OapiMessageCorpconversationSendbytemplateResponse rsp = null;
         try {
@@ -139,6 +153,8 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
         req.setTemplateId(TEMPLATE_REPORT_WAITING_APPLY);
         JSONObject json = new JSONObject();
         json.put("auditNum", ""+auditNum);
+        json.put("APPID", appId);
+        json.put("CORPID", dingding.getCorpid());
         req.setData(json.toJSONString());
         OapiMessageCorpconversationSendbytemplateResponse rsp = null;
         try {
@@ -159,6 +175,10 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
         req.setAgentId(agentId);
         req.setUseridList(useridList);
         req.setTemplateId(TEMPLATE_BUSTRIP_SETTING);
+        JSONObject json = new JSONObject();
+        json.put("APPID", appId);
+        json.put("CORPID", dingding.getCorpid());
+        req.setData(json.toJSONString());
         OapiMessageCorpconversationSendbytemplateResponse rsp = null;
         try {
             rsp = client.execute(req, getCorpAccessToken(dingding));
@@ -183,6 +203,8 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
                 JSONObject json = new JSONObject();
                 json.put("name", ""+title);
                 json.put("endDate", ""+endDate);
+                json.put("APPID", appId);
+                json.put("CORPID", dingding.getCorpid());
                 req.setData(json.toJSONString());
 
                 OapiMessageCorpconversationSendbytemplateResponse rsp = null;
@@ -198,6 +220,94 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
         }.start();
     }
 
+
+    @Override
+    public void sendFinishMileStoneMsg(CompanyDingding dingding, String useridList, String taskName, String project) {
+        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/sendbytemplate");
+        OapiMessageCorpconversationSendbytemplateRequest req = new OapiMessageCorpconversationSendbytemplateRequest();
+        req.setAgentId(dingding.getAgentId());
+        req.setUseridList(useridList);
+        req.setTemplateId(TEMPLATE_FINISH_MILESTONE);
+        JSONObject json = new JSONObject();
+        json.put("taskName", taskName);
+        json.put("project", project);
+        json.put("APPID", appId);
+        json.put("CORPID", dingding.getCorpid());
+        req.setData(json.toJSONString());
+        OapiMessageCorpconversationSendbytemplateResponse rsp = null;
+        try {
+            rsp = client.execute(req, getCorpAccessToken(dingding));
+        } catch (ApiException e) {
+            e.printStackTrace();
+        } catch (Exception exception) {
+            exception.printStackTrace();
+        }
+        System.out.println(rsp.getBody());
+    }
+
+    @Override
+    public void sendOAMsg(CompanyDingding dingding, String useridList, HashMap map) {
+        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
+        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
+        request.setAgentId(dingding.getAgentId());
+        request.setUseridList(useridList);
+        request.setToAllUser(false);
+
+        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
+//        msg.setMsgtype("text");
+//        msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());
+//        msg.getText().setContent("test123");
+//        request.setMsg(msg);
+//
+//        msg.setMsgtype("image");
+//        msg.setImage(new OapiMessageCorpconversationAsyncsendV2Request.Image());
+//        msg.getImage().setMediaId("@lADOdvRYes0CbM0CbA");
+//        request.setMsg(msg);
+//
+//        msg.setMsgtype("file");
+//        msg.setFile(new OapiMessageCorpconversationAsyncsendV2Request.File());
+//        msg.getFile().setMediaId("@lADOdvRYes0CbM0CbA");
+//        request.setMsg(msg);
+//
+//        msg.setMsgtype("link");
+//        msg.setLink(new OapiMessageCorpconversationAsyncsendV2Request.Link());
+//        msg.getLink().setTitle("test");
+//        msg.getLink().setText("test");
+//        msg.getLink().setMessageUrl("test");
+//        msg.getLink().setPicUrl("test");
+//        request.setMsg(msg);
+//
+//        msg.setMsgtype("markdown");
+//        msg.setMarkdown(new OapiMessageCorpconversationAsyncsendV2Request.Markdown());
+//        msg.getMarkdown().setText("##### text");
+//        msg.getMarkdown().setTitle("### Title");
+//        request.setMsg(msg);
+
+        msg.setOa(new OapiMessageCorpconversationAsyncsendV2Request.OA());
+        msg.getOa().setHead(new OapiMessageCorpconversationAsyncsendV2Request.Head());
+        msg.getOa().getHead().setText("这里是标题");
+        msg.getOa().setBody(new OapiMessageCorpconversationAsyncsendV2Request.Body());
+        msg.getOa().getBody().setContent("这里是内容");
+        msg.setMsgtype("oa");
+        msg.getOa().setMessageUrl("dingtalk://dingtalkclient/action/openapp?corpid=="+dingding.getCorpid()+"&container_type=work_platform&app_id="+appId+"&redirect_type=jump&redirect_url=https%3A%2F%2Fworktime.ttkuaiban.com%2F%3Fcorpid%3D%24CORPID%24");
+        request.setMsg(msg);
+
+//        msg.setActionCard(new OapiMessageCorpconversationAsyncsendV2Request.ActionCard());
+//        msg.getActionCard().setTitle("xxx123411111");
+//        msg.getActionCard().setMarkdown("### 测试123111");
+//        msg.getActionCard().setSingleTitle("测试测试");
+//        msg.getActionCard().setSingleUrl("https://www.dingtalk.com");
+//        msg.setMsgtype("action_card");
+//        request.setMsg(msg);
+        OapiMessageCorpconversationAsyncsendV2Response rsp = null;
+        try {
+            rsp = client.execute(request, getCorpAccessToken(dingding));
+        } catch (Exception exception) {
+            exception.printStackTrace();
+        }
+        System.out.println(rsp.getBody());
+    }
+
     private String getDDSuiteAccessToken() throws ApiException {
         if (DingDingServiceImpl.SUITE_ACCESS_TOKEN == null || DingDingServiceImpl.suiteTokenExpireTime < System.currentTimeMillis()) {
             DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/service/get_suite_token");

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

@@ -45,7 +45,7 @@ public class DingDingServiceImpl implements DingDingService {
     private final Logger bizLogger = LoggerFactory.getLogger(getClass());
     public static final DateTimeFormatter timeDtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
     public static final DateTimeFormatter mmDtf = DateTimeFormatter.ofPattern("HH:mm");
-    long appId = 71020L;
+//    public static long appId = 71020L;
     String token = "cf776d62c5fb3508b5d8c2cbb9f3df0c";
     String aesKey = "ktmbamhymjsf60ndwp6n81mnu92847oynsgj9e0zr9v";
     public static String suiteKey = "suitejwoq9dw4bxv4stdb";
@@ -114,6 +114,9 @@ public class DingDingServiceImpl implements DingDingService {
 
     @Value("${configEnv.isPrivateDeploy}")
     private boolean isPrivateDeploy;//企业内部应用,私有化部署的情况
+    @Value("${dingding.appId}")
+    private long appId;//钉钉第三方应用的appId
+
     @Override
     @Async
     public void corpAuth(String corpid, String corpName, String authUserId, Long agentId) throws ApiException {

+ 24 - 12
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectAddcostRecordServiceImpl.java

@@ -13,6 +13,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.text.DecimalFormat;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Optional;
@@ -49,19 +50,24 @@ public class ProjectAddcostRecordServiceImpl extends ServiceImpl<ProjectAddcostR
         projectAddcostRecordMapper.insert(item);
         List<ProjectAddcostItem> list = JSONArray.parseArray(itemList, ProjectAddcostItem.class);
         List<ProjectCurrentcost> curList = projectCurrentcostMapper.selectList(new QueryWrapper<ProjectCurrentcost>().eq("project_id", item.getProjectId()));
-
+        DecimalFormat df = new DecimalFormat("#.00");
         //校验,当前下拨的不能超过剩余可下拨金额
         List<ProjectBasecost> totalCost = projectBasecostMapper.selectList(new QueryWrapper<ProjectBasecost>().eq("project_id", item.getProjectId()));
         for (ProjectAddcostItem addItem : list) {
             if (addItem.getBaseAmount() > 0) {
-                double available = totalCost.stream().filter(t->t.getBaseId().intValue() == addItem.getBaseId().intValue()).findFirst().get().getBaseAmount()
-                            - curList.stream().filter(t->t.getBaseId().intValue() == addItem.getBaseId().intValue()).findFirst().get().getBaseAmount();
-                if (addItem.getBaseAmount() > available) {
+                double available = totalCost.stream().filter(t->t.getBaseId().intValue() == addItem.getBaseId().intValue()).findFirst().get().getBaseAmount();
+                double curAmount = 0;
+                if (curList.size() > 0) {
+                    Optional<ProjectCurrentcost> first = curList.stream().filter(t -> t.getBaseId().intValue() == addItem.getBaseId().intValue()).findFirst();
+                    if (first.isPresent()) {
+                        curAmount = first.get().getBaseAmount();
+                    }
+                }
+                if (addItem.getBaseAmount() > (available - curAmount)) {
                     HttpRespMsg msg = new HttpRespMsg();
-                    msg.setError(addItem.getBaseName()+"可下拨额度不足"+addItem.getBaseAmount()+", 请校正总成本预算。");
+                    msg.setError(addItem.getBaseName()+"可下拨额度不足"+df.format(addItem.getBaseAmount())+", 请校正总成本预算。");
                     return msg;
                 }
-
             }
         }
         list.forEach(li->{
@@ -117,17 +123,23 @@ public class ProjectAddcostRecordServiceImpl extends ServiceImpl<ProjectAddcostR
             //检查是否是最新的一条
             List<ProjectAddcostRecord> latestItem = projectAddcostRecordMapper.selectList(new QueryWrapper<ProjectAddcostRecord>().eq("project_id", record.getProjectId()).orderByDesc("id").last("limit 1"));
             if (latestItem.get(0).getId().equals(record.getId())) {
+                System.out.println("record.getId()==="+record.getId());
                 List<ProjectAddcostItem> itemList = projectAddcostItemMapper.selectList(new QueryWrapper<ProjectAddcostItem>().eq("record_id", id));
                 //使用当前的来减掉
                 List<ProjectCurrentcost> curList = projectCurrentcostMapper.selectList(new QueryWrapper<ProjectCurrentcost>().eq("project_id", record.getProjectId()));
                 curList.forEach(cur->{
-                    ProjectAddcostItem matchItem = itemList.stream().filter(item->item.getBaseId().intValue() == cur.getBaseId().intValue()).findFirst().get();
-                    cur.setBaseAmount(cur.getBaseAmount() - matchItem.getBaseAmount());
+                    Optional<ProjectAddcostItem> first = itemList.stream().filter(item -> item.getBaseId().intValue() == cur.getBaseId().intValue()).findFirst();
+                    if (first.isPresent()) {
+                        ProjectAddcostItem matchItem = first.get();
+                        cur.setBaseAmount(cur.getBaseAmount() - matchItem.getBaseAmount());
+                    } else {
+                        System.out.println("添加记录的明细里匹配不上cur baseId=="+cur.getBaseId()+", curBaseName=="+cur.getBaseName());
+                    }
                 });
-                projectCurrentcostService.updateBatchById(curList);
-                //删除添加的这条记录
-                projectAddcostItemMapper.delete(new QueryWrapper<ProjectAddcostItem>().eq("record_id", id));
-                projectAddcostRecordMapper.deleteById(id);
+//                projectCurrentcostService.updateBatchById(curList);
+//                //删除添加的这条记录
+//                projectAddcostItemMapper.delete(new QueryWrapper<ProjectAddcostItem>().eq("record_id", id));
+//                projectAddcostRecordMapper.deleteById(id);
             } else {
                 msg.setError("只有最新的一次下拨可以撤销");
             }

+ 127 - 19
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -9,10 +9,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.entity.*;
 import com.management.platform.entity.vo.*;
 import com.management.platform.mapper.*;
-import com.management.platform.service.ProjectAuditorService;
-import com.management.platform.service.ProjectNotifyUserService;
-import com.management.platform.service.ProjectService;
-import com.management.platform.service.SysFunctionService;
+import com.management.platform.service.*;
 import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.ListUtil;
@@ -57,6 +54,10 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     @Resource
     private ProjectNotifyUserService projectNotifyUserService;
     @Resource
+    private GroupParticipatorMapper groupParticipatorMapper;
+    @Resource
+    private GroupParticipatorService groupParticipatorService;
+    @Resource
     private ProjectMapper projectMapper;
     @Resource
     private SysRoleFunctionMapper sysRoleFunctionMapper;
@@ -71,6 +72,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     @Resource
     private ParticipationMapper participationMapper;
     @Resource
+    private ParticipationService participationService;
+    @Resource
     private FinanceProjectsMapper financeProjectsMapper;
     @Resource
     private ProjectTimerMapper projectTimerMapper;
@@ -2369,26 +2372,66 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             headList.add(setting.getName()+"已发生占比");
         }
         exportList.add(headList);
+
+        //查询项目的各个成本项实际的成本
+        List<Integer> pids = new ArrayList<>();
+        for (int i=0;i<projectList.size(); i++) {
+            HashMap map = (HashMap)projectList.get(i);
+            pids.add((Integer)map.get("id"));
+        }
+
+        if (pids.size() > 0) {
+            List<ProjectCurrentcost> currentcostList = projectCurrentcostMapper.selectList(new QueryWrapper<ProjectCurrentcost>().in("project_id", pids));
+            List realCostData = reportMapper.getProjectCost(companyId, pids);
+            for (int i=0;i<projectList.size(); i++) {
+                HashMap item = (HashMap)projectList.get(i);
+                int pid = (Integer)item.get("id");
+                item.put("curcostList", currentcostList.stream().filter(cur->cur.getProjectId() == pid).collect(Collectors.toList()));
+                List proRealCost = new ArrayList();
+                for (int m=0;m<realCostData.size(); m++) {
+                    HashMap realCostItem = (HashMap)realCostData.get(m);
+                    if ((int)realCostItem.get("projectId") == pid) {
+                        proRealCost.add(realCostItem);
+                    }
+                }
+                item.put("realcostList", proRealCost);
+            }
+        }
+        DecimalFormat df = new DecimalFormat("#0.00");
+        DecimalFormat df2 = new DecimalFormat("#0");
         for (HashMap project : projectList) {
             List<String> data = new ArrayList<>();
             data.add((String)project.get("projectCode"));
             data.add((String)project.get("projectName"));
             data.add(project.get("baseCurcost") != null?project.get("baseCurcost").toString():"");
-            data.add(""+project.get("freeMan"));
-//            data.add(project.getFeeNormal().toString());
-//            data.add(project.getFeeTravel().toString());
-//            data.add(project.getFeeOutsourcing().toString());
-//            double totalFee = project.getFeeMan() + project.getFeeNormal()+ project.getFeeTravel()+ project.getFeeOutsourcing();
-//            data.add(totalFee+"");
-//            if (project.getContractAmount() != null && project.getContractAmount() > 0) {
-//                double profitAmt = project.getContractAmount() - totalFee;
-//                data.add(profitAmt+"");
-//                data.add(new java.text.DecimalFormat("#.0").format((100*profitAmt/project.getContractAmount()))+"%");
-//            } else {
-//                double profitAmt = -totalFee;
-//                data.add(profitAmt+"");
-//                data.add("");
-//            }
+            data.add(""+project.get("feeMan"));
+            List<ProjectCurrentcost> curList = (List<ProjectCurrentcost>)project.get("curcostList");
+            List<HashMap> realList = (List<HashMap>)project.get("realcostList");
+            for (ProjectBasecostSetting setting : settingList) {
+                int baseId = setting.getId();
+                double curCost = 0;
+                Optional<ProjectCurrentcost> first = curList.stream().filter(cur -> cur.getBaseId().intValue() == baseId).findFirst();
+                if (first.isPresent()) {
+                    curCost = (double) first.get().getBaseAmount();
+                }
+                data.add(df.format(curCost));
+                double real = 0;
+
+                for (HashMap mapReal : realList) {
+                    int bid = (int)mapReal.get("basecostId");
+                    if (bid == baseId) {
+                        real = ((BigDecimal)mapReal.get("cost")).doubleValue();
+                        break;
+                    }
+                }
+
+                data.add(df.format(real));
+                if (real == 0 || curCost == 0) {
+                    data.add("-");
+                } else {
+                    data.add(df2.format(real/curCost*100)+"%");
+                }
+            }
             exportList.add(data);
         }
         String fileName = "工时成本预警表_"+System.currentTimeMillis();
@@ -2397,6 +2440,71 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         return httpRespMsg;
     }
 
+    @Override
+    public HttpRespMsg getProjectsGroups(String projectIdArray) {
+        List<Integer> ids = JSONArray.parseArray(projectIdArray, Integer.class);
+        List<TaskGroup> taskGroups = taskGroupMapper.selectList(new QueryWrapper<TaskGroup>().in("project_id", ids));
+        Map<String, List<TaskGroup>> collect = taskGroups.stream().collect(Collectors.groupingBy(TaskGroup::getName));
+        Iterator<String> iterator = collect.keySet().iterator();
+        List<HashMap> result = new ArrayList<>();
+        while (iterator.hasNext()) {
+            String name = iterator.next();
+            List<TaskGroup> taskGroups1 = collect.get(name);
+            List<Integer> groupIds = taskGroups1.stream().map(TaskGroup::getId).collect(Collectors.toList());
+            HashMap mapItem = new HashMap();
+            mapItem.put("name", name);
+            mapItem.put("groupIds", groupIds);
+            result.add(mapItem);
+        }
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = result;
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg batchAddMembToGroup(String membIdArray, String groupIds) {
+        List<String> membArray = JSONArray.parseArray(membIdArray, String.class);
+        List<Integer> groupArray = JSONArray.parseArray(groupIds, Integer.class);
+        List<GroupParticipator> gpList = groupParticipatorMapper.selectList(new QueryWrapper<GroupParticipator>().in("group_id", groupArray));
+        List<GroupParticipator> addToGpList = new ArrayList<>();
+        for (Integer groupId : groupArray) {
+            for (String memb : membArray) {
+                if (!gpList.stream().anyMatch(gp->gp.getGroupId().equals(groupId) && memb.equals(gp.getUserId()))) {
+                    //不存在的加上
+                    GroupParticipator participator = new GroupParticipator();
+                    participator.setGroupId(groupId);
+                    participator.setUserId(memb);
+                    addToGpList.add(participator);
+                }
+            }
+        }
+        if (addToGpList.size() > 0) {
+            //本次有新增的
+            groupParticipatorService.saveBatch(addToGpList);
+            //给项目增加参与人
+            List<Integer> collect = addToGpList.stream().map(GroupParticipator::getGroupId).collect(Collectors.toList());
+            List<TaskGroup> taskGroups = taskGroupMapper.selectList(new QueryWrapper<TaskGroup>().in("id", collect));
+            List<Integer> projectIds = taskGroups.stream().map(TaskGroup::getProjectId).collect(Collectors.toList());
+            List<Participation> participationList = participationMapper.selectList(new QueryWrapper<Participation>().in("project_id", projectIds));
+            List<Participation> addPartiToProject = new ArrayList<>();
+            for (Integer proId : projectIds) {
+                for (String memb : membArray) {
+                    if (!participationList.stream().anyMatch(part->part.getProjectId().equals(proId) && part.getUserId().equals(memb))) {
+                        Participation p = new Participation();
+                        p.setUserId(memb);
+                        p.setProjectId(proId);
+                        addPartiToProject.add(p);
+                    }
+                }
+            }
+            if (addPartiToProject.size() > 0) {
+                participationService.saveBatch(addPartiToProject);
+            }
+        }
+
+        return new HttpRespMsg();
+    }
+
 
     private List<Department> getSubDepts(Department dp, List<Department> list) {
         List<Department> collect = list.stream().filter(l -> dp.getDepartmentId().equals(l.getSuperiorId())).collect(Collectors.toList());;

+ 10 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -11,6 +11,7 @@ import com.management.platform.service.*;
 import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.ListUtil;
+import com.management.platform.util.WorkDayCalculateUtils;
 import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
 import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
@@ -124,6 +125,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     @Resource
     private TaskMapper taskMapper;
     @Resource
+    private TaskService taskService;
+    @Resource
     private UserRecentTaskMapper userRecentTaskMapper;
     @Resource
     private PpMembsMapper ppMembsMapper;
@@ -685,6 +688,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         if (finishedTaskIds.size() > 0) {
             Task fTask = new Task();
             taskMapper.update(fTask.setTaskStatus(1), new QueryWrapper<Task>().in("id", finishedTaskIds));
+            taskService.notifyMileStoneFinish(companyId, finishedTaskIds);
         }
 
         int enginerring = companyMapper.selectById(companyId).getPackageEngineering();
@@ -872,6 +876,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 map2.put("state", list2.get(0).get("state"));
                 map2.put("auditDeptName", list2.get(0).get("auditDeptName"));
                 map2.put("isDeptAudit", list2.get(0).get("isDeptAudit"));
+                //增加填报人所属部门
+                map2.put("departmentName", list2.get(0).get("departmentName"));
             }
 
             //设置照片显示
@@ -2943,6 +2949,10 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     if((curUser.getIsActive()==0&&date.isAfter(curUser.getInactiveDate()))) {
                         continue;
                     }
+                    //去掉非工作日
+                    if (!WorkDayCalculateUtils.isWorkDay(date)) {
+                        continue;
+                    }
                     final String dateStr = dtf.format(date);
                     if (!list.stream().anyMatch(item->item.get("id").equals(curUser.getId())&&sdf.format((java.sql.Date)item.get("createDate")).equals(dateStr))) {
                         UserDailyWorkItem noRecord = new UserDailyWorkItem();

+ 37 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.github.pagehelper.util.StringUtil;
 import com.management.platform.entity.*;
 import com.management.platform.mapper.*;
+import com.management.platform.service.CompanyDingdingService;
 import com.management.platform.service.MilestoneTaskRefService;
 import com.management.platform.service.TaskExecutorService;
 import com.management.platform.service.TaskService;
@@ -34,6 +35,7 @@ import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -55,6 +57,8 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
     @Resource
     private UserMapper userMapper;
     @Resource
+    private CompanyDingdingService companyDingdingService;
+    @Resource
     private StagesMapper stagesMapper;
     @Resource
     private TaskGroupMapper taskGroupMapper;
@@ -62,6 +66,10 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
     private TaskExecutorService taskExecutorService;
     @Resource
     private MilestoneTaskRefMapper milestoneTaskRefMapper;
+    @Resource
+    private CompanyDingdingMapper companyDingdingMapper;
+    @Resource
+    private ParticipationMapper participationMapper;
 
     @Override
     public HttpRespMsg getExecutorPanel(Integer projectId) {
@@ -293,7 +301,9 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         HttpRespMsg httpRespMsg = new HttpRespMsg();
 
         //首先先搞到公司id
-        Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
+        String userId = request.getHeader("Token");
+        User creator = userMapper.selectById(userId);
+        Integer companyId = creator.getCompanyId();
         List<User> allUserList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
         //获取当前导入的任务列表
         Stages stages = stagesMapper.selectById(stagesId);
@@ -360,6 +370,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                     continue;
                 }
                 Task task = new Task();
+                task.setCompanyId(companyId);
                 task.setProjectId(projectId);
                 task.setGroupId(groupId);
                 String executorName = executorCell.getStringCellValue();
@@ -383,7 +394,9 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                 LocalDate endDate = LocalDate.parse(formatValue, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                 task.setEndDate(endDate);
                 task.setPlanHours(Integer.parseInt(planHoursCell.getStringCellValue()));
-
+                task.setCreaterId(creator.getId());
+                task.setCreatorColor(creator.getColor());
+                task.setCreaterName(creator.getName());
                 task.setCreateDate(LocalDate.now());
                 taskList.add(task);
             }
@@ -493,4 +506,26 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         return msg;
     }
 
+    @Override
+    public void notifyMileStoneFinish(Integer companyId, List<Integer> taskIdList) {
+        new Thread() {
+            public void run() {
+                List<CompanyDingding> dingdingList = companyDingdingMapper.selectList(new QueryWrapper<CompanyDingding>().eq("company_id", companyId));
+                //钉钉注册的公司
+                if (dingdingList.size() > 0) {
+                    CompanyDingding dingding = dingdingList.get(0);
+                    List<Task> taskList = taskMapper.selectList(new QueryWrapper<Task>().in("id", taskIdList).eq("task_type", 1));
+                    for (Task task : taskList) {
+                        Project project = projectMapper.selectById(task.getProjectId());
+                        List<Participation> participationList = participationMapper.selectList(new QueryWrapper<Participation>().eq("project_id", task.getProjectId()));
+                        List<User> partUserList = userMapper.selectList(new QueryWrapper<User>().in("id", participationList.stream().map(Participation::getUserId).collect(Collectors.toList())));
+                        String useridList = partUserList.stream().map(User::getDingdingUserid).collect(Collectors.joining(","));
+                        companyDingdingService.sendFinishMileStoneMsg(dingding, useridList, task.getName(), project.getProjectName());
+                    }
+                }
+                //TODO: 企业微信注册的公司
+            }
+        }.start();
+    }
+
 }

+ 49 - 24
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -307,6 +307,14 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     String curUserid = base_info.getString("acctid");
                     String name = base_info.getString("name");
                     Long time = base_info.getLong("date");
+                    JSONArray workRules = base_info.getJSONObject("rule_info").getJSONArray("checkintime");
+                    //获取上下午的考勤打卡规则
+                    String baseMorningStart = DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(0).getIntValue("work_sec"));
+                    String baseMorningEnd = DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(0).getIntValue("off_work_sec"));
+                    String baseAfternoonStart = DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(1).getIntValue("work_sec"));
+                    String baseAfternoonEnd = DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(1).getIntValue("off_work_sec"));
+                    int restTime = workRules.getJSONObject(1).getIntValue("work_sec") - workRules.getJSONObject(0).getIntValue("off_work_sec");
+
                     LocalDate localDate = LocalDateTime.ofInstant(Instant.ofEpochSecond(time), ZoneId.systemDefault()).toLocalDate();
                     UserCorpwxTime ct = new UserCorpwxTime();
                     ct.setCompanyId(corpInfo.getCompanyId());
@@ -342,53 +350,61 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                             if (leaveText.startsWith("请假")) {
                                 //获取对应位置的请假时间段
                                 String string = holiday.getJSONObject("sp_description").getJSONArray("data").getJSONObject(m).getString("text");
-                                String[] s = string.split(" ");
+                                String[] s = string.split(" |\\~");
+                                boolean isOldFormat = false;
+                                if (s.length < 5) {
+                                    isOldFormat = true;
+                                    for (String it : s) {
+                                        System.out.println(it);
+                                    }
+                                }
+
                                 //获取到请假的开始时间和结束时间
-                                String leaveEnd = s[4];
+                                String leaveEnd = isOldFormat?s[3]:s[4];
                                 String leaveStart = s[1];
                                 //请假开始的日期和结束的日期
                                 String dateStart = localDate.getYear() + "/" + s[0];
-                                String dateEnd =  localDate.getYear() + "/" +s[3];
+                                String dateEnd =  localDate.getYear() + "/" +(isOldFormat?s[2]:s[3]);
                                 LocalDate sDate = LocalDate.parse(dateStart, mdFormat);
                                 LocalDate eDate = LocalDate.parse(dateEnd, mdFormat);
                                 if (sDate.isEqual(eDate)) {
                                     //请假在一天内
                                     if (leaveEnd.equals("下午")) {
                                         if (leaveStart.equals("上午")) {
-                                            leaveEnd = "18:00";//上午和下午都请假,算全天
-                                            leaveStart = "09:00";
+                                            leaveEnd = baseAfternoonEnd;//上午和下午都请假,算全天
+                                            leaveStart = baseMorningStart;
                                         } else {
                                             leaveStart = "14:00";
-                                            leaveEnd = "18:00";//请假的下班打卡时间,算上午结束的时间
+                                            leaveEnd = baseAfternoonEnd;//请假的下班打卡时间,算上午结束的时间
                                         }
                                     } else if (leaveEnd.equals("上午")){
                                         //上午请假
-                                        leaveEnd = "14:00";
-                                        leaveStart = "09:00";
+                                        leaveEnd = baseMorningEnd;
+                                        leaveStart = baseMorningStart;
                                     }
                                 } else {
                                     if (showLog)System.out.println("跨天请假@@@@");
                                     if (showLog)System.out.println("当天=="+localDate+", sDate=" + sDate+", 比较="+(localDate.isEqual(sDate)));
                                     //跨天请假
                                     if (localDate.isEqual(sDate)) {
-                                        //当前日期就是最后一天,需判断上下午半天请假的情况
+                                        //当前日期一天,需判断上下午半天请假的情况
                                         if (leaveStart.equals("上午")) {
-                                            leaveEnd = "18:00";//上午开始请假的算全天
-                                            leaveStart = "09:00";
+                                            leaveStart = baseMorningStart;
                                         } else {
-                                            leaveStart = "14:00";
-                                            leaveEnd = "18:00";//下午开始请假的,算半天
+                                            leaveStart = baseAfternoonStart;
                                         }
+                                        //跨天请假的第一天,结束时间默认为18:00
+                                        leaveEnd = baseAfternoonEnd;//上午开始请假的算全天
                                     } else if (localDate.isEqual(eDate)) {
                                         //当前日期就是最后一天,需判断上下午半天请假的情况
                                         if (leaveEnd.equals("下午")) {
-                                            leaveEnd = "18:00";//请假到最后一天的下午,就算是全天
-                                            leaveStart = "09:00";
+                                            leaveEnd = baseAfternoonEnd;//请假到最后一天的下午,就算是全天
                                         } else if (leaveEnd.equals("上午")){
                                             //上午请假
-                                            leaveEnd = "14:00";
-                                            leaveStart = "09:00";
+                                            leaveEnd = baseMorningEnd;
                                         }
+                                        //跨天请假的最后一天,开始时间默认为9:00
+                                        leaveStart = baseMorningStart;
                                     } else {
                                         //中间日期就是全天
                                         leaveEnd = "00:00";
@@ -397,7 +413,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                     }
                                 }
 
-                                //获取外出的最早的开始时间和最晚的结束时间最为当天考勤的最早和最晚时间
+                                //获取请假最早的开始时间和最晚的结束时间最为当天考勤的最早和最晚时间
                                 if (ct.getStartTime().equals("00:00") || ct.getStartTime().compareTo(leaveStart) > 0) {
                                     ct.setStartTime(leaveStart);
                                     needRecaculate = true;
@@ -408,9 +424,13 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                 }
                             } else if (leaveText.startsWith("外出")) {
                                 String string = holiday.getJSONObject("sp_description").getJSONArray("data").getJSONObject(m).getString("text");
-                                String[] s = string.split(" ");
+                                String[] s = string.split(" |\\~");
                                 //获取到外出的开始时间和结束时间
-                                String outEnd = s[4];
+                                boolean isOldFormat = false;
+                                if (s.length < 5) {
+                                    isOldFormat = true;
+                                }
+                                String outEnd = isOldFormat?s[3]:s[4];
                                 String outStart = s[1];
 
                                 //获取外出的最早的开始时间和最晚的结束时间最为当天考勤的最早和最晚时间
@@ -429,9 +449,10 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     //时间有变化,需要重新计算
                     if (needRecaculate) {
                         timeDelta = DateTimeUtil.getHoursFromSeconds(DateTimeUtil.getSecondsFromTime(ct.getEndTime()) - DateTimeUtil.getSecondsFromTime(ct.getStartTime()));
-                        if (ct.getEndTime().compareTo("13:30") >= 0) {
+                        //超过下午上班的开始时间,需要减去午休的时间
+                        if (ct.getEndTime().compareTo(baseAfternoonStart) >= 0) {
                             //重新计算打卡工时时,需要减去中间午休时间
-                            timeDelta -= 1.0;
+                            timeDelta -= restTime;
                         }
                     } else {
                         timeDelta = ct.getCardTime();
@@ -478,10 +499,14 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                             if (leaveText.startsWith("请假")) {
                                 //获取对应位置的请假时间段
                                 String string = holiday.getJSONObject("sp_description").getJSONArray("data").getJSONObject(m).getString("text");
-                                String[] s = string.split(" ");
+                                String[] s = string.split(" |\\~");
+                                boolean isOldFormat = false;
+                                if (s.length < 5) {
+                                    isOldFormat = true;
+                                }
                                 //获取到请假的开始时间和结束时间
                                 String leaveStart = s[1];
-                                String leaveEnd = s[4];
+                                String leaveEnd = isOldFormat?s[3]:s[4];
 
                                 //检查请假时间段是否在打卡的时间范围内
                                 if ("上午".equals(leaveEnd) || "下午".equals(leaveEnd)) {

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

@@ -252,7 +252,7 @@ public class TimingTask {
     //发送关联出差的提醒
     @Scheduled(cron = "0 5 9 ? * *")
     private void linkBusinessTripAlert() {
-//        if (isDev) return;
+        if (isDev) return;
         List<TimeType> timeTypes = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_dingding", 1));
         List<Integer> companyIds = timeTypes.stream().map(TimeType::getCompanyId).collect(Collectors.toList());
         List<CompanyDingding> dingdingList = companyDingdingService.list(

+ 9 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/Sha1Util.java

@@ -14,9 +14,15 @@ import java.util.*;
 public class Sha1Util {
 
     public static void main(String[] args) {
-        String str = "jsapi_ticket=kgt8ON7yVITDhtdwci0qecaNzS34qhbQACy88uRm_S0XvT3hcWiBONbLzKnA5o5uPukt2sA3a8bBfETg4TyaQg&noncestr=10907813b97e249163587e6246612e21&timestamp=1516590573&url=http://www.dzjy.com/payHtml.html?num=1&code=001EjC0a2q6qoO0fn2Z92E6D0a2EjC0D&state=1";
-        String sign = getSha1(str);
-        System.out.println(sign);
+//        String str = "jsapi_ticket=kgt8ON7yVITDhtdwci0qecaNzS34qhbQACy88uRm_S0XvT3hcWiBONbLzKnA5o5uPukt2sA3a8bBfETg4TyaQg&noncestr=10907813b97e249163587e6246612e21&timestamp=1516590573&url=http://www.dzjy.com/payHtml.html?num=1&code=001EjC0a2q6qoO0fn2Z92E6D0a2EjC0D&state=1";
+//        String sign = getSha1(str);
+//        System.out.println(sign);
+        String string = "10/30 下午~04/26 上午";
+        String[] arr = string.split(" |\\~");
+        for (String s : arr) {
+            System.out.println(s);
+        }
+
     }
 
     public static String getNonceStr() {

+ 6 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml

@@ -14,9 +14,10 @@ spring:
       location: C:/upload/
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://47.101.180.183:3306/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
+    url: jdbc:mysql://47.101.180.183:3306/man_hour_manager?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
     username: root
     password: HuoshiDB@2022
+
     hikari:
       maximum-pool-size: 10
       minimum-idle: 3
@@ -95,6 +96,10 @@ wx:
   template_project_deadline: kY2Qzec64uOANNXA0yn-PV09ZnNjCeGXwWjTaVmQiLU
   template_report_reject: TICiRkvCpF4NCbkPOjefXTpz7jXgpt0SZGkNjCMIt3M
   template_report_week: lhwkaW9BKwCvMtCuoAxLw4lZoGgMaucL0Ap0Vz-5KOY
+
+#钉钉参数配置
+dingding:
+  appId: 71020
 ##actuator健康检查配置
 management:
   security:

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

@@ -344,7 +344,9 @@
     <select id="getOvertimeList" resultType="java.util.Map">
         SELECT report.`creator_id` AS userId, user.`name` AS username, SUM(report.`working_time`) AS workingTime,
         IFNULL(SUM(report.`overtime_hours`),0) AS overtimeHours,
+        group_concat(distinct(project.project_code)) as projectCode,
         IFNULL(SUM(report.overtime_cost), 0) AS cost FROM report LEFT JOIN user ON user.id = report.`creator_id`
+        left join project on project.id = report.project_id
         WHERE report.is_overtime = 1
         and report.`state` = 1
         AND report.`create_date` BETWEEN #{startDate} and #{endDate}
@@ -362,7 +364,9 @@
     <select id="getOvertimeDetail" resultType="java.util.Map">
         SELECT date_format(report.`create_date`, '%Y-%m-%d') AS createDate, report.`creator_id` AS userId, user.`name` AS username, SUM(report.`working_time`) AS workingTime,
         IFNULL(SUM(report.`overtime_hours`), 0) AS overtimeHours,
+        project.project_name as projectName,project.project_code as projectCode,
         IFNULL(SUM(report.overtime_cost), 0) AS cost FROM report LEFT JOIN user ON user.id = report.`creator_id`
+        left join project on project.id = report.project_id
         WHERE report.is_overtime = 1
         and report.`state` = 1
         AND report.`create_date` BETWEEN #{startDate} and #{endDate}
@@ -426,7 +430,7 @@
     <select id="getBaseCostAndRealCost" resultType="java.util.HashMap">
         SELECT project.id,project_code as projectCode, project.`project_name` as projectName,
         (SELECT IFNULL(SUM(base_amount), 0) FROM project_currentcost LEFT JOIN project_basecost_setting
-        ON project_basecost_setting.id = project_currentcost.`base_id` WHERE alarm_type=1 AND company_id=10 AND project_currentcost.`project_id`=project.id) AS baseCurcost,
+        ON project_basecost_setting.id = project_currentcost.`base_id` WHERE alarm_type=1 AND company_id=#{companyId} AND project_currentcost.`project_id`=project.id) AS baseCurcost,
         (SELECT IFNULL(SUM(cost), 0) FROM report WHERE report.`company_id` = #{companyId} AND project_id = project.id AND state=1 AND basecost_id >0) AS feeMan
         FROM project WHERE (STATUS &lt;&gt; 3  OR project.status IS NULL) AND company_id=#{companyId}
         <if test="pageStart != null and pageSize != null">

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

@@ -239,7 +239,7 @@
     <select id="getAuditReportList" resultType="java.util.Map">
         SELECT a.id, user.id as userId, user.name, DATE_FORMAT(a.create_date, '%Y-%m-%d') as date, a.project_id as projectId, b.project_name AS project, a.working_time AS time, a.content, a.state, a.time_type as timeType,
         a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,
-        a.end_time as endTime, b.incharger_id as inchargerId,
+        a.end_time as endTime, b.incharger_id as inchargerId,dept.department_name as departmentName,
         a.creator_id as creatorId, d.name as subProjectName,a.task_id as taskId, task.name as taskName, a.is_overtime as isOvertime,a.progress as progress,
         a.department_audit_state as departmentAuditState, a.stage, a.pic_str as picStr, multi_worktime as multiWorktime
         , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,
@@ -252,6 +252,7 @@
         left join task on task.id = a.task_id
         left join report_extra_degree on report_extra_degree.id = a.degree_id
         left join department on department.department_id = a.audit_deptid
+        left join department dept on dept.department_id = a.dept_id
         left join task_group on task_group.id = a.group_id
         left join user u on u.id = a.project_auditor_id
         WHERE a.company_id = #{companyId}

+ 1 - 1
fhKeeper/formulahousekeeper/octopus/config/index.js

@@ -28,7 +28,7 @@ module.exports = {
   },
   dev: {
     env: require('./dev.env'),
-    port: 10086,
+    port: 10085,
     autoOpenBrowser: true,
     assetsSubDirectory: 'static',
     assetsPublicPath: '/',

+ 5 - 1
fhKeeper/formulahousekeeper/octopus/src/views/customer/list.vue

@@ -32,6 +32,10 @@
             
             <el-table-column prop="expirationDate" label="有效期"  min-width="160" align="center">
             </el-table-column>
+            <el-table-column prop="wxCorpid" label="企业微信"  min-width="160" align="center">
+            </el-table-column>
+            <el-table-column prop="dingdingCorpid" label="钉钉"  min-width="160" align="center">
+            </el-table-column>
             <el-table-column prop="staffCountMax" label="人数上限"  min-width="80" align="center">
             </el-table-column>
             <el-table-column prop="packageWorktime" label="使用版本" align="left" min-width="500" header-align="center">
@@ -52,7 +56,7 @@
                 </template>
             </el-table-column>
             
-            <el-table-column label="操作" width="240" class-name="btns" header-align="center">
+            <el-table-column label="操作" width="240" class-name="btns" header-align="center" fixed="right">
                 <template slot-scope="scope">
                     <el-button size="mini"  @click="editClick('A', scope.row)">增加人数</el-button>
                     <el-button size="mini"  @click="editClick('B', scope.row)">修改有效期</el-button>

+ 7 - 0
fhKeeper/formulahousekeeper/octopus/src/views/market/list.vue

@@ -17,6 +17,13 @@
                     </template>
             </el-table-column>
             <el-table-column prop="companyName" label="公司名称"  ></el-table-column>
+            <el-table-column prop="wx_corpid" label="来源"  >
+                <template slot-scope="scope">
+                    <span>{{scope.row.wxCorpid!=null?"企业微信":""}}</span>
+                    <span>{{scope.row.dingdingCorpid!=null?"钉钉":""}}</span>
+                    <span>{{scope.row.wxCorpid==null&&scope.row.dingdingCorpid==null?"官网":""}}</span>
+                </template>
+            </el-table-column>
             <el-table-column prop="cTime" label="注册时间"  ></el-table-column>
             <el-table-column prop="name" label="联系人" ></el-table-column>
             <el-table-column prop="phone" label="联系方式"  width="150"></el-table-column>

+ 29 - 1
fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/controller/CompanyController.java

@@ -2,10 +2,15 @@ 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.CompanyDingding;
 import com.management.platform.entity.VcompanyCustomerContact;
+import com.management.platform.entity.WxCorpInfo;
+import com.management.platform.mapper.CompanyDingdingMapper;
 import com.management.platform.mapper.CompanyMapper;
+import com.management.platform.mapper.WxCorpInfoMapper;
 import com.management.platform.service.CompanyService;
 import com.management.platform.util.HttpRespMsg;
 import org.apache.el.parser.BooleanNode;
@@ -16,6 +21,9 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -32,6 +40,11 @@ public class CompanyController {
     CompanyMapper companyMapper;
     @Resource
     CompanyService companyService;
+    @Resource
+    WxCorpInfoMapper wxCorpInfoMapper;
+    @Resource
+    CompanyDingdingMapper companyDingdingMapper;
+
     /**
      * 获取企业列表,显示到期时间
      * @return
@@ -48,7 +61,22 @@ public class CompanyController {
         queryWrapper.orderByDesc("id");
         HttpRespMsg msg = new HttpRespMsg();
 
-        msg.data = companyMapper.selectPage(new Page<>(pageIndex, pageSize), queryWrapper);
+        IPage<Company> result = companyMapper.selectPage(new Page<>(pageIndex, pageSize), queryWrapper);
+        List<Company> records = result.getRecords();
+        List<Integer> collect = records.stream().map(Company::getId).collect(Collectors.toList());
+        List<WxCorpInfo> wxComps = wxCorpInfoMapper.selectList(new QueryWrapper<WxCorpInfo>().in("company_id", collect));
+        List<CompanyDingding> dingdingList = companyDingdingMapper.selectList(new QueryWrapper<CompanyDingding>().in("company_id", collect));
+        records.forEach(r->{
+            Optional<WxCorpInfo> first = wxComps.stream().filter(wx -> wx.getCompanyId().intValue() == r.getId()).findFirst();
+            if (first.isPresent()) {
+                r.setWxCorpid(first.get().getCorpid());
+            }
+            Optional<CompanyDingding> first1 = dingdingList.stream().filter(d -> d.getCompanyId().intValue() == r.getId()).findFirst();
+            if (first1.isPresent()) {
+                r.setDingdingCorpid(first1.get().getCorpid());
+            }
+        });
+        msg.data = result;
         return msg;
     }
 

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

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * VIEW 前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-05-12
+ */
+@RestController
+@RequestMapping("/vcompany-customer-contact")
+public class VcompanyCustomerContactController {
+
+}
+

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

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-05-12
+ */
+@RestController
+@RequestMapping("/wx-corp-info")
+public class WxCorpInfoController {
+
+}
+

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

@@ -121,6 +121,12 @@ public class Company extends Model<Company> {
     private Integer packageFinance;
 
 
+    @TableField(exist = false)
+    private String wxCorpid;
+
+    @TableField(exist = false)
+    private String dingdingCorpid;
+
     @Override
     protected Serializable pkVal() {
         return this.id;

+ 12 - 6
fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/entity/VcompanyCustomerContact.java

@@ -4,12 +4,9 @@ import com.baomidou.mybatisplus.extension.activerecord.Model;
 import java.time.LocalDateTime;
 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>
@@ -17,7 +14,7 @@ import org.springframework.format.annotation.DateTimeFormat;
  * </p>
  *
  * @author Seyason
- * @since 2021-04-09
+ * @since 2022-05-12
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -51,7 +48,7 @@ public class VcompanyCustomerContact extends Model<VcompanyCustomerContact> {
     private LocalDateTime expirationDate;
 
     /**
-     * 选择的套餐(单位:/年)
+     * 是否签约
      */
     @TableField("set_meal")
     private Integer setMeal;
@@ -87,9 +84,18 @@ public class VcompanyCustomerContact extends Model<VcompanyCustomerContact> {
      * 创建时间
      */
     @TableField("c_time")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
     private LocalDateTime cTime;
 
+    @TableField("wx_corpid")
+    private String wxCorpid;
+
+    /**
+     * 钉钉企业id
+     */
+    @TableField("dingding_corpid")
+    private String dingdingCorpid;
+
+
     @Override
     protected Serializable pkVal() {
         return null;

+ 1 - 1
fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/entity/WxCorpInfo.java

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2021-09-05
+ * @since 2022-05-12
  */
 @Data
 @EqualsAndHashCode(callSuper = false)

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

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

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

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

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.WxCorpInfo;
+import com.management.platform.mapper.WxCorpInfoMapper;
+import com.management.platform.service.WxCorpInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-05-12
+ */
+@Service
+public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpInfo> implements WxCorpInfoService {
+
+}

+ 1 - 3
fhKeeper/formulahousekeeper/ops-platform/src/main/resources/application.yml

@@ -104,9 +104,7 @@ referer:
   refererDomain:
     - localhost
     - ttkuaiban.com
-    - www.ttkuaiban.com
-    - mobworktime.ttkuaiban.com
-    - worktime.ttkuaiban.com
+    - ops.ttkuaiban.com
 excludeUrls: /wxcorp/*,/wxcorp/*/*,/dingding/*,/error,/testClient,/corpWXAuth,/wx-corp-info/*,/clean/*,/innerRoles/*
 
 

+ 3 - 1
fhKeeper/formulahousekeeper/ops-platform/src/main/resources/mapper/VcompanyCustomerContactMapper.xml

@@ -15,11 +15,13 @@
         <result column="feedback" property="feedback" />
         <result column="indate" property="indate" />
         <result column="c_time" property="cTime" />
+        <result column="wx_corpid" property="wxCorpid" />
+        <result column="dingding_corpid" property="dingdingCorpid" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, company_name, staff_count_max, expiration_date, set_meal, name, phone, contacted, feedback, indate, c_time
+        id, company_name, staff_count_max, expiration_date, set_meal, name, phone, contacted, feedback, indate, c_time, wx_corpid, dingding_corpid
     </sql>
 
 </mapper>

+ 6 - 6
fhKeeper/formulahousekeeper/timesheet/package-lock.json

@@ -2815,7 +2815,7 @@
     },
     "el-table-infinite-scroll": {
       "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/el-table-infinite-scroll/-/el-table-infinite-scroll-2.0.0.tgz",
+      "resolved": "https://registry.npmmirror.com/el-table-infinite-scroll/-/el-table-infinite-scroll-2.0.0.tgz",
       "integrity": "sha512-zDmsGvce4V0wx7j4CBdYi2wgMsv66SbQBp7984gk25Jc8b2nKdjBYrXpFLfMDZ0iYjTDpxkH9+5iEhCgM3+byw==",
       "requires": {
         "core-js": "^3.x",
@@ -2825,7 +2825,7 @@
       "dependencies": {
         "core-js": {
           "version": "3.22.5",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.5.tgz",
+          "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.22.5.tgz",
           "integrity": "sha512-VP/xYuvJ0MJWRAobcmQ8F2H6Bsn+s7zqAAjFaHGBMc5AQm7zaelhD1LGduFn2EehEcQcU+br6t+fwbpQ5d1ZWA=="
         }
       }
@@ -5098,7 +5098,7 @@
       "dependencies": {
         "semver": {
           "version": "5.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.3.0.tgz?cache=0&sync_timestamp=1616463603361&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.3.0.tgz",
           "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
           "dev": true
         }
@@ -5218,7 +5218,7 @@
     },
     "normalize-wheel": {
       "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
+      "resolved": "https://registry.nlark.com/normalize-wheel/download/normalize-wheel-1.0.1.tgz",
       "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
     },
     "npmlog": {
@@ -5235,7 +5235,7 @@
     },
     "nprogress": {
       "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
+      "resolved": "https://registry.npm.taobao.org/nprogress/download/nprogress-0.2.0.tgz",
       "integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E="
     },
     "nth-check": {
@@ -9343,7 +9343,7 @@
         },
         "path-exists": {
           "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+          "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-3.0.0.tgz",
           "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
           "dev": true
         },

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

@@ -272,7 +272,8 @@
                 </el-table-column>
                 <el-table-column v-for="item in stages" :label="item" min-width="150" :key="item" align="right" show-overflow-tooltip="true" >
                   <template slot-scope="scope" >
-                    {{scope.row.stageCostList.filter(s=>s.stageName == item).length == 0?'0':scope.row.stageCostList.filter(s=>s.stageName == item)[0].workingTime.toFixed(1)}}
+                    {{scope.row.stageCostList.filter(s=>s.stageName == item).length == 0?'0':scope.row.stageCostList.filter(s=>s.stageName == item)[0].workingTime.toFixed(1)}}h
+                    /¥{{scope.row.stageCostList.filter(s=>s.stageName == item).length == 0?'0':scope.row.stageCostList.filter(s=>s.stageName == item)[0].cost.toFixed(1)}}
                   </template>
                  
                 </el-table-column>

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

@@ -404,7 +404,7 @@
                     </el-form-item>
                     <!--项目管理专业版模式下,项目下的近期执行的任务 -->
                     <el-form-item label="相关任务" :prop="'domains.' + index + '.taskId'" v-if="user.company.packageProject==1" >
-                        <el-select v-model="domain.taskId" placeholder="请选择" style="width:100%;" filterable="true" 
+                        <el-select v-model="domain.taskId" placeholder="请选择" style="width:75%;margin-right:7%" filterable="true" 
                         :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
                             <el-option v-for="item in domain.taskList" :key="item.taskId" :label="item.taskName" :value="item.taskId"></el-option>
                         </el-select>
@@ -1099,7 +1099,7 @@
 
         <!--基于企业微信考勤数据的工时导入 -->
         <el-dialog title="工时批量导入" v-if="importWxDialog" :visible.sync="importWxDialog" customClass="customWidth" width="1100px">
-            <el-steps :active="active" finish-status="success">
+            <el-steps :active="active" finish-status="success" style="margin-left:50px;">
             <el-step title="选择要导入工时的日期范围">
                 
             </el-step>
@@ -1152,13 +1152,19 @@
                     </el-upload>
                 </p>
             </div>
-            <el-button style="margin: 0 auto;" @click="pre">上一步</el-button>
-            <div style="display: inline-block;width: 80%;text-align: center;" v-if="active==0">
-                <el-link type="primary" @click="toView()">查看工时导入记录</el-link>
+            <div  slot="title">
+                <span style="font-size:16px;">工时批量导入</span>
+                <el-link v-if="active==0"  style="float:right;margin-right:100px;" type="primary" @click="toView()">查看工时导入记录</el-link>
             </div>
-            <el-button style="float:right;" @click="next" :disabled="importWxParam.date==null" v-if="active<2">下一步</el-button>
-            <el-link v-if="active==1" style="float:right;margin-right:350px;margin-top:10px;" 
+            
+            <span slot="footer">
+            <el-link v-show="active==1" style="margin-right:300px;margin-top:10px;" 
                 type="primary" @click="downloadCheckInExcel">下载员工工时统计模板.xlsx</el-link>
+            <el-button @click="pre" v-if="active!=0">上一步</el-button>
+            
+            <el-button @click="next" :disabled="importWxParam.date==null" v-if="active<2">下一步</el-button>
+            
+            </span>
         </el-dialog>
 
         <!--基于企业微信考勤数据的工时导入 -->
@@ -3422,6 +3428,7 @@
                                     projectAuditorName: list.report[i].projectAuditorName,
                                     overtimeHours: list.report[i].overtimeHours,
                                     customText: list.report[i].customText,
+                                    basecostId: list.report[i].basecostId,
                                 })
                                 if (list.report[i].state >= 2) {
                                     this.canEdit = true;
@@ -3453,6 +3460,10 @@
                                 userNames:null,
                                 time: this.report.time
                             }
+                            if (this.timeBasecostList.length > 0) {
+                                //默认给第一个,必填字段
+                                this.workForm.domains[0].basecostId = this.timeBasecostList[0].id;
+                            }
                             
                             this.canEdit = true;
                         }
@@ -4177,7 +4188,7 @@
                         leftProgress = 100 - totalProgress;
                     }
                 }
-                this.workForm.domains.push({
+                var addItem = {
                         projectId: "",
                         workingTime: this.reportTimeType.type == 3?(leftProgress*this.reportTimeType.allday/100).toFixed(1):"",
                         content: "",
@@ -4186,7 +4197,12 @@
                         multiWorktime: this.reportTimeType.multiWorktime,
                         worktimeList:[{}],
                         // degreeId: '',
-                });
+                };
+                if (this.timeBasecostList.length > 0) {
+                    //默认给第一个,必填字段
+                    addItem.basecostId = this.timeBasecostList[0].id;
+                }
+                this.workForm.domains.push(addItem);
                 
                 if (this.reportTimeType.type == 0) {
                     //全天上下午模式下,检测时间段数量,达到2个,不能再加了
@@ -4381,11 +4397,11 @@
                         if (this.reportTimeType.type == 1 && this.workForm.time) {
                             var totalTime = 0;
                             for (var t=0;t<this.workForm.domains.length; t++) {
-                                totalTime += this.workForm.domains[t].workingTime;
+                                totalTime += parseFloat(this.workForm.domains[t].workingTime);
                             }
-                            if (this.workForm.time.workHours > 0 && totalTime > this.workForm.time.workHours) {
+                            if (this.workForm.time.workHours && totalTime > parseFloat(this.workForm.time.workHours)) {
                                 this.$message({
-                                        message: "填报工时之和不能超过考勤总工时("+this.workForm.time.workHours+"h)",
+                                        message: "填报工时之和"+(totalTime)+"h不能超过考勤总工时("+this.workForm.time.workHours.toFixed(1)+"h)",
                                         type: "error"
                                     });
                                 return;

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

@@ -158,26 +158,26 @@
                     <el-table-column prop="userName" label="操作人" width="150"></el-table-column>
                     <el-table-column prop="indate" label="审核时间"></el-table-column>
                     <el-table-column prop="result" label="审核结果"></el-table-column>
-                    <el-table-column prop="date" label="员工" width="200">
+                    <el-table-column prop="date" label="员工/日期" width="200">
                         <template slot-scope="scope">
                             <div>
                                 <div v-if="scope.row.membdateList.length > 3">
                                     <el-popover placement="top" width="400" trigger="hover">
                                     <div>
                                         <span v-for="(item, index) in scope.row.membdateList" :key="index">
-                                            {{item.userName}} <span v-if="scope.row.membdateList.length > 1 && scope.row.membdateList.length - 1 != index">,</span>
+                                            {{item.userName}}/{{item.createDate}} <span v-if="scope.row.membdateList.length > 1 && scope.row.membdateList.length - 1 != index">,</span>
                                         </span>
                                     </div>
                                     <div slot="reference" style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width: 180px;">
                                         <span v-for="(item, index) in scope.row.membdateList" :key="index">
-                                            {{item.userName}} <span v-if="scope.row.membdateList.length > 1 && scope.row.membdateList.length - 1 != index">,</span>
+                                            {{item.userName}}/{{item.createDate}} <span v-if="scope.row.membdateList.length > 1 && scope.row.membdateList.length - 1 != index">,</span>
                                         </span>
                                     </div>
                                     </el-popover>
                                 </div>
                                 <div style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width: 180px;" v-else>
                                     <span v-for="(item, index) in scope.row.membdateList" :key="index">
-                                        {{item.userName}} <span v-if="scope.row.membdateList.length > 1 && scope.row.membdateList.length - 1 != index">,</span>
+                                        {{item.userName}}/{{item.createDate}} <span v-if="scope.row.membdateList.length > 1 && scope.row.membdateList.length - 1 != index">,</span>
                                     </span>
                                 </div>
                             </div>

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

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