瀏覽代碼

自定义基线成本项,客户管理,删除基线记录

seyason 3 年之前
父節點
當前提交
606f9f0422
共有 53 個文件被更改,包括 1511 次插入1126 次删除
  1. 68 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AuditWorkflowTimeSettingController.java
  2. 108 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/CustomerInfoController.java
  3. 38 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/EarningSnapshotController.java
  4. 0 51
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ImageProcessingController.java
  5. 69 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectBasecostController.java
  6. 108 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectBasecostSettingController.java
  7. 21 14
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java
  8. 0 57
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ScreenshotController.java
  9. 9 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java
  10. 12 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java
  11. 57 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/AuditWorkflowTimeSetting.java
  12. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Company.java
  13. 78 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/CustomerInfo.java
  14. 17 37
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/EarningSnapshot.java
  15. 13 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Project.java
  16. 60 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectBasecost.java
  17. 48 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectBasecostSetting.java
  18. 19 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/CustomerProject.java
  19. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/AuditWorkflowTimeSettingMapper.java
  20. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/CustomerInfoMapper.java
  21. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectBasecostMapper.java
  22. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectBasecostSettingMapper.java
  23. 6 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectMapper.java
  24. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/AuditWorkflowTimeSettingService.java
  25. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/CustomerInfoService.java
  26. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectBasecostService.java
  27. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectBasecostSettingService.java
  28. 7 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java
  29. 0 30
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ScreenshotService.java
  30. 6 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserService.java
  31. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/AuditWorkflowTimeSettingServiceImpl.java
  32. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/CustomerInfoServiceImpl.java
  33. 11 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java
  34. 7 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceServiceImpl.java
  35. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectBasecostServiceImpl.java
  36. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectBasecostSettingServiceImpl.java
  37. 197 48
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  38. 0 778
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ScreenshotServiceImpl.java
  39. 148 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  40. 1 42
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  41. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/CodeGenerator.java
  42. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/Constant.java
  43. 36 36
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/OpenOfficeService.java
  44. 5 9
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application-prod.yml
  45. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  46. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/AuditWorkflowTimeSettingMapper.xml
  47. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CompanyMapper.xml
  48. 26 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CustomerInfoMapper.xml
  49. 5 9
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/EarningSnapshotMapper.xml
  50. 19 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectBasecostMapper.xml
  51. 17 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectBasecostSettingMapper.xml
  52. 49 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml
  53. 二進制
      fhKeeper/formulahousekeeper/management-platform/财务人员成本模板_已填写.xlsx

+ 68 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AuditWorkflowTimeSettingController.java

@@ -0,0 +1,68 @@
+package com.management.platform.controller;
+
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.AuditWorkflowTimeSetting;
+import com.management.platform.mapper.AuditWorkflowTimeSettingMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.util.HttpRespMsg;
+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.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-07-25
+ */
+@RestController
+@RequestMapping("/audit-workflow-time-setting")
+public class AuditWorkflowTimeSettingController {
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    AuditWorkflowTimeSettingMapper auditWorkflowTimeSettingMapper;
+    @Resource
+    UserMapper userMapper;
+
+    @RequestMapping("/add")
+    public HttpRespMsg add(String json) {
+        String token = request.getHeader("TOKEN");
+        Integer companyId = userMapper.selectById(token).getCompanyId();
+        auditWorkflowTimeSettingMapper.delete(new QueryWrapper<AuditWorkflowTimeSetting>().eq("company_id", companyId));
+        JSONArray array = JSONArray.parseArray(json);
+
+        for (int i=0;i<array.size(); i++) {
+            JSONObject obj = array.getJSONObject(i);
+            AuditWorkflowTimeSetting auditWorkflowTimeSetting = JSONObject.toJavaObject(obj, AuditWorkflowTimeSetting.class);
+            auditWorkflowTimeSetting.setCompanyId(companyId);
+            auditWorkflowTimeSetting.setSeq(i+1);
+            auditWorkflowTimeSettingMapper.insert(auditWorkflowTimeSetting);
+        }
+        return new HttpRespMsg();
+
+    }
+
+
+    @RequestMapping("/get")
+    public HttpRespMsg get() {
+        String token = request.getHeader("TOKEN");
+        Integer companyId = userMapper.selectById(token).getCompanyId();
+        List<AuditWorkflowTimeSetting> auditWorkflowTimeSettings = auditWorkflowTimeSettingMapper.selectList(new QueryWrapper<AuditWorkflowTimeSetting>().eq("company_id", companyId).orderByAsc("seq"));
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = auditWorkflowTimeSettings;
+        return msg;
+    }
+
+
+}
+

+ 108 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/CustomerInfoController.java

@@ -0,0 +1,108 @@
+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.CustomerInfo;
+import com.management.platform.entity.Project;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.CustomerInfoMapper;
+import com.management.platform.mapper.ProjectMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-07-31
+ */
+@RestController
+@RequestMapping("/customer-info")
+public class CustomerInfoController {
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    ProjectMapper projectMapper;
+    @Resource
+    CustomerInfoMapper customerInfoMapper;
+
+    @RequestMapping("/addOrMod")
+    public HttpRespMsg addOrMod(CustomerInfo info) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        if (info.getId() == null) {
+            info.setCompanyId(user.getCompanyId());
+            customerInfoMapper.insert(info);
+        } else {
+            info.setCompanyId(user.getCompanyId());
+            customerInfoMapper.updateById(info);
+            //更新项目表中的客户名称
+            Project p = new Project();
+            p.setCustomerName(info.getCustomerName());
+            projectMapper.update(p, new QueryWrapper<Project>().eq("customer_id", info.getId()));
+        }
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        int r = customerInfoMapper.delete(new QueryWrapper<CustomerInfo>().eq("id", id).eq("company_id", user.getCompanyId()));
+        if (r <= 0) {
+            msg.setError("无权删除");
+        }
+        return msg;
+    }
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(@RequestParam Integer pageIndex, @RequestParam Integer pageSize, String keyword) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        QueryWrapper<CustomerInfo> queryWrapper = new QueryWrapper<CustomerInfo>().eq("company_id", user.getCompanyId()).orderByDesc("id");
+        if (!StringUtils.isEmpty(keyword)) {
+            queryWrapper.like("customer_name", keyword);
+        }
+        IPage<CustomerInfo> projectIPage = customerInfoMapper.selectPage(new Page<>(pageIndex, pageSize),
+                queryWrapper);
+        List<CustomerInfo> list = projectIPage.getRecords();
+        Long total = projectIPage.getTotal();
+        Map<String, Object> map = new HashMap<>();
+        map.put("records", list);
+        map.put("total", total);
+        msg.data = map;
+        return msg;
+    }
+
+    @RequestMapping("/getAll")
+    public HttpRespMsg getAll() {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        List<CustomerInfo> all = customerInfoMapper.getAll(user.getCompanyId());
+        msg.data = all;
+        return msg;
+    }
+
+}
+

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

@@ -1,21 +1,27 @@
 package com.management.platform.controller;
 
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.EarningSnapshot;
 import com.management.platform.entity.Project;
+import com.management.platform.entity.ProjectBasecost;
 import com.management.platform.entity.User;
 import com.management.platform.mapper.ProjectMapper;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.EarningSnapshotService;
 import com.management.platform.service.FinanceService;
 import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.ListUtil;
 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.util.ArrayList;
+import java.util.List;
 
 /**
  * <p>
@@ -45,12 +51,43 @@ public class EarningSnapshotController {
         HttpRespMsg msg = new HttpRespMsg();
         Project project = projectMapper.selectById(projectId);
         if (userId.equals(project.getInchargerId()) || userId.equals(project.getCreatorId()) || user.getRole() > 0) {
-            msg.data = earningSnapshotService.list(new QueryWrapper<EarningSnapshot>().eq("project_id", projectId).orderByDesc("id"));
+            List<EarningSnapshot> list = earningSnapshotService.list(new QueryWrapper<EarningSnapshot>().eq("project_id", projectId).orderByDesc("id"));
+            for (EarningSnapshot snapshot : list) {
+                if (snapshot.getCostData() != null) {
+                    JSONArray array = JSONArray.parseArray(snapshot.getCostData());
+                    List<ProjectBasecost> costList = new ArrayList<>();
+                    for (int i=0;i<array.size();i++) {
+                        ProjectBasecost projectBasecost = JSONObject.toJavaObject(array.getJSONObject(i), ProjectBasecost.class);
+                        costList.add(projectBasecost);
+                    }
+                    snapshot.setCostList(costList);
+                    snapshot.setCostData(null);
+                }
+            }
+            msg.data = list;
         } else {
             msg.setError("无权查看");
         }
 
         return msg;
     }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer projectId, String ids) {
+        String userId = request.getHeader("Token");
+        User user = userMapper.selectById(userId);
+
+
+        HttpRespMsg msg = new HttpRespMsg();
+        Project project = projectMapper.selectById(projectId);
+        if (userId.equals(project.getInchargerId()) || userId.equals(project.getCreatorId()) || user.getRole() > 0) {
+            List<Integer> idArray = ListUtil.convertIntegerIdsArrayToList(ids);
+            earningSnapshotService.removeByIds(idArray);
+        } else {
+            msg.setError("无权操作");
+        }
+
+        return msg;
+    }
 }
 

+ 0 - 51
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ImageProcessingController.java

@@ -1,51 +0,0 @@
-package com.management.platform.controller;
-
-import com.management.platform.entity.vo.ScreenshotVO;
-import com.management.platform.service.ScreenshotService;
-import com.management.platform.util.HttpRespMsg;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import javax.annotation.Resource;
-
-/**
- * Author: 吴涛涛
- * Date : 2020 - 01 - 03 9:38
- * Description:<描述>
- * Version: 1.0
- */
-@RestController
-@RequestMapping("/imageProcessing")
-@EnableScheduling
-public class ImageProcessingController {
-
-    @Resource
-    private ScreenshotService screenshotService;
-
-    /**
-     * 参数:uid 用户id
-     * indate 截图时间 如 "2018-08-01 22:32:57"
-     * file 上传的图片文件
-     */
-    @RequestMapping("/saveAndProcessImage")
-    public HttpRespMsg pictureDetectionTask(ScreenshotVO screenshotvo) {
-        return screenshotService.saveAndProcessImage(screenshotvo);
-    }
-
-    @RequestMapping("/reTestPic")
-    public HttpRespMsg reTestPic(Integer id) {
-        return screenshotService.reTestPicMatch(id);
-    }
-    /**
-     * 初始化redis图片搜索的关键词,
-     * 防止数据库初始添加了其他字段导致redis里的数据不是最新的,
-     * 做定时在系统不忙时进行更新redis里的最新图片关键词(注意:如果想要立即更新可手动调用)
-     */
-    @RequestMapping("/updateKeyWords")
-    @Scheduled(cron = "0 0 23 * * ?")//配置时间点触发(每日23点)
-    public HttpRespMsg updateRedisPicContentKeywords() {
-        return screenshotService.updateRedisPicContentKeywords();
-    }
-
-}

+ 69 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectBasecostController.java

@@ -0,0 +1,69 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.ProjectBasecost;
+import com.management.platform.entity.ProjectBasecostSetting;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.ProjectBasecostMapper;
+import com.management.platform.mapper.ProjectBasecostSettingMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.util.HttpRespMsg;
+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.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-08-02
+ */
+@RestController
+@RequestMapping("/project-basecost")
+public class ProjectBasecostController {
+
+    @Resource
+    ProjectBasecostMapper projectBasecostMapper;
+    @Resource
+    ProjectBasecostSettingMapper projectBasecostSettingMapper;
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    HttpServletRequest request;
+
+    @RequestMapping("/get")
+    public HttpRespMsg get(Integer projectId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        List<ProjectBasecost> list = projectBasecostMapper.selectList(new QueryWrapper<ProjectBasecost>().eq("project_id", projectId));
+        //检查最新的字段是否有
+        User user = userMapper.selectById(request.getHeader("TOKEN"));
+        List<ProjectBasecostSetting> allSettings = projectBasecostSettingMapper.selectList(new QueryWrapper<ProjectBasecostSetting>().eq("company_id", user.getCompanyId()));
+        List<ProjectBasecost> additionalList = new ArrayList<>();
+        allSettings.forEach(all->{
+            if (!list.stream().filter(costItem->costItem.getBaseId().equals(all.getId())).findAny().isPresent()) {
+                ProjectBasecost add = new ProjectBasecost();
+                add.setBaseName(all.getName());
+                add.setBaseId(all.getId());
+                add.setProjectId(projectId);
+                add.setBaseAmount(0);
+                additionalList.add(add);
+            }
+        });
+        if (additionalList.size() > 0) {
+            list.addAll(additionalList);
+        }
+        msg.data = list;
+        return msg;
+    }
+
+
+}
+

+ 108 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectBasecostSettingController.java

@@ -0,0 +1,108 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.ProjectBasecost;
+import com.management.platform.entity.ProjectBasecostSetting;
+import com.management.platform.mapper.ProjectBasecostMapper;
+import com.management.platform.mapper.ProjectBasecostSettingMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.util.HttpRespMsg;
+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.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-08-02
+ */
+@RestController
+@RequestMapping("/project-basecost-setting")
+public class ProjectBasecostSettingController {
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    ProjectBasecostSettingMapper projectBasecostSettingMapper;
+
+    @Resource
+    ProjectBasecostMapper projectBasecostMapper;
+
+    @RequestMapping("/addOrMod")
+    public HttpRespMsg addOrMod(ProjectBasecostSetting setting) {
+        HttpRespMsg msg = new HttpRespMsg();
+        if (StringUtils.isEmpty(setting.getName())) {
+            msg.setError("名称不能为空");
+            return msg;
+        }
+        Integer companyId = userMapper.selectById(request.getHeader("TOKEN")).getCompanyId();
+        if (setting.getId() == null) {
+            setting.setCompanyId(companyId);
+            int count = projectBasecostSettingMapper.selectCount(new QueryWrapper<ProjectBasecostSetting>().eq("name", setting.getName()).eq("company_id", setting.getCompanyId()));
+            if (count > 0) {
+                msg.setError("该名称已存在");
+            } else {
+                projectBasecostSettingMapper.insert(setting);
+                msg.data = projectBasecostSettingMapper.selectList(new QueryWrapper<ProjectBasecostSetting>().eq("company_id", companyId));
+            }
+        } else {
+            int count = projectBasecostSettingMapper.selectCount(new QueryWrapper<ProjectBasecostSetting>().eq("name", setting.getName())
+                    .eq("company_id", companyId).ne("id", setting.getId()));
+            if (count > 0) {
+                msg.setError("该名称已存在");
+            } else {
+                //检查名称是否有变化
+                ProjectBasecostSetting oldSetting = projectBasecostSettingMapper.selectById(setting.getId());
+                if (!setting.getName().equals(oldSetting.getName())) {
+                    projectBasecostSettingMapper.updateById(setting);
+                    ProjectBasecost cost = new ProjectBasecost();
+                    cost.setBaseName(setting.getName());
+                    projectBasecostMapper.update(cost, new QueryWrapper<ProjectBasecost>().eq("base_id", setting.getId()));
+                }
+                msg.data = projectBasecostSettingMapper.selectList(new QueryWrapper<ProjectBasecostSetting>().eq("company_id", companyId));
+            }
+        }
+
+        return msg;
+    }
+
+    @RequestMapping("/list")
+    public HttpRespMsg list() {
+        HttpRespMsg msg = new HttpRespMsg();
+
+        Integer companyId = userMapper.selectById(request.getHeader("TOKEN")).getCompanyId();
+        List<ProjectBasecostSetting> list = projectBasecostSettingMapper.selectList(new QueryWrapper<ProjectBasecostSetting>().eq("company_id", companyId));
+        msg.data = list;
+
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        ProjectBasecostSetting projectBasecostSetting = projectBasecostSettingMapper.selectById(id);
+        Integer companyId = userMapper.selectById(request.getHeader("TOKEN")).getCompanyId();
+        if (!projectBasecostSetting.getCompanyId().equals(companyId)) {
+            msg.setError("无权操作");
+        } else {
+            projectBasecostSettingMapper.deleteById(id);
+        }
+
+        return msg;
+    }
+
+
+
+
+}
+

+ 21 - 14
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java

@@ -63,26 +63,19 @@ public class ProjectController {
                                    String planEndDate,
                                    Integer level,
                                    Integer contractAmount,
-                                   Integer baseMan,
-                                   Integer baseFee,
-                                   Integer baseOutsourcing,
-                                   Integer baseRisk1,
-                                   Integer baseRisk2,
-                                   Integer budget
+                                   Integer budget,
+                                   Integer customerId,
+                                   String projectBaseCostData
                                    ) {
         return projectService.editProject(id, name, code, userId, inchargerId, planStartDate, planEndDate, level, contractAmount,
-                 baseMan,
-                 baseFee,
-                 baseOutsourcing,
-                 baseRisk1,
-                 baseRisk2,
-                 budget,request);
+                projectBaseCostData,
+                 budget,customerId,request);
     }
 
     @RequestMapping("/adjustBase")
-    public HttpRespMsg adjustBase(Project project
+    public HttpRespMsg adjustBase(String baseCostData, Project project
     ) {
-        return projectService.adjustBase(project,request);
+        return projectService.adjustBase(baseCostData, project,request);
     }
 
 
@@ -242,17 +235,31 @@ public class ProjectController {
     public HttpRespMsg getProjectInAndOut(@RequestParam Integer pageIndex, @RequestParam Integer pageSize) {
         return projectService.getProjectInAndOut(pageIndex, pageSize, request);
     }
+
+
     //导出项目收支平衡表
     @RequestMapping("/exportProjectInAndOut")
     public HttpRespMsg exportProjectInAndOut() {
         return projectService.exportProjectInAndOut(request);
     }
 
+    //分页查询客户项目统计报表
+    @RequestMapping("/getCustomerProjectInAndOut")
+    public HttpRespMsg getCustomerProjectInAndOut(@RequestParam Integer pageIndex, @RequestParam Integer pageSize) {
+        return projectService.getCustomerProjectInAndOut(pageIndex, pageSize, request);
+    }
+    //导出项目收支平衡表
+    @RequestMapping("/exportCustomerProjectInAndOut")
+    public HttpRespMsg exportCustomerProjectInAndOut() {
+        return projectService.exportCustomerProjectInAndOut(request);
+    }
+
     @RequestMapping("/importData")
     public HttpRespMsg importData(String userId, MultipartFile file, HttpServletRequest request) {
         return projectService.importData(userId, file, request);
     }
 
 
+    //
 }
 

+ 0 - 57
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ScreenshotController.java

@@ -1,57 +0,0 @@
-package com.management.platform.controller;
-
-
-import com.management.platform.service.ScreenshotService;
-import com.management.platform.util.HttpRespMsg;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * <p>
- * 前端控制器
- * </p>
- *
- * @author 吴涛涛
- * @since 2020-01-03
- */
-@RestController
-@RequestMapping("/screenshot")
-public class ScreenshotController {
-    @Autowired
-    private ScreenshotService screenshotService;
-    @Autowired
-    private HttpServletRequest request;
-
-    /**
-     * 获取每个人最新的截图
-     * date 要筛选的日期 格式yyyy-mm-dd
-     */
-    @RequestMapping("/getLatestScreenshotList")
-    public HttpRespMsg getLatestScreenshotList(@RequestParam String date) {
-        return screenshotService.getLatestScreenshotList(date, request);
-    }
-
-    /**
-     * 获取某人截图列表
-     * userId 用户id
-     * date 要筛选的日期 格式yyyy-mm-dd
-     */
-    @RequestMapping("/getTodayScreenshotList")
-    public HttpRespMsg getTodayScreenshotList(@RequestParam String userId, @RequestParam String date) {
-        return screenshotService.getTodayScreenshotList(userId, date);
-    }
-
-    /**
-     * 获取最近有截图的日期
-     * date 目标日期 格式yyyy-mm-dd
-     */
-    @RequestMapping("/getScreenshotDate")
-    public HttpRespMsg getScreenshotDate(@RequestParam String date) {
-        return screenshotService.getScreenshotDate(date, request);
-    }
-}
-

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

@@ -164,5 +164,14 @@ public class UserController {
     public HttpRespMsg exportUsers(Integer containInvalid) {
         return userService.exportUsers(containInvalid,request);
     }
+
+    @RequestMapping("/pushFillReport")
+    public HttpRespMsg pushFillReport(String ids, String date) {return userService.pushFillReport(ids, request, date); }
+
+    @RequestMapping("/exportMembList")
+    public HttpRespMsg exportMembList(boolean isFill, String ids, String date) {return userService.exportMembList(isFill, ids, request, date); }
+
+    @RequestMapping("/getHRList")
+    public HttpRespMsg getHRList() {return userService.getHRList(request); }
 }
 

+ 12 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java

@@ -61,6 +61,8 @@ public class WeiXinCorpController {
 
     @Resource
     CompanyMapper companyMapper;
+    @Resource
+    ProjectBasecostSettingMapper projectBasecostSettingMapper;
 
     public static String SUITE_ACCESS_TOKEN = null;
     public static long suiteTokenExpireTime = 0L;
@@ -397,6 +399,16 @@ public class WeiXinCorpController {
                                 .setExpirationDate(LocalDateTime.now().plusMonths(1));
                         companyMapper.insert(company);
 
+                        //生成项目的成本基线默认条目
+                        String[] array = com.management.platform.util.Constant.DEFAULT_BASE_COST_ITEMS;
+                        for (String baseItem : array) {
+                            ProjectBasecostSetting setting = new ProjectBasecostSetting();
+                            setting.setName(baseItem);
+                            setting.setCompanyId(company.getId());
+                            projectBasecostSettingMapper.insert(setting);
+                        }
+
+
                         //生成工作时长
                         TimeType timeType = new TimeType();
                         timeType.setCompanyId(company.getId());

+ 57 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/AuditWorkflowTimeSetting.java

@@ -0,0 +1,57 @@
+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 2021-07-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class AuditWorkflowTimeSetting extends Model<AuditWorkflowTimeSetting> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @TableField("company_id")
+    private Integer companyId;
+
+    @TableField("role_id")
+    private Integer roleId;
+
+    @TableField("role_name")
+    private String roleName;
+
+    @TableField("seq")
+    private Integer seq;
+
+    /**
+     * 指定该节点的审核人员
+     */
+    @TableField("user_id")
+    private String userId;
+
+    @TableField("user_name")
+    private String userName;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

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

@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2021-05-27
+ * @since 2021-08-01
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -91,6 +91,12 @@ public class Company extends Model<Company> {
     @TableField("package_expense")
     private Integer packageExpense;
 
+    /**
+     * 客户管理
+     */
+    @TableField("package_customer")
+    private Integer packageCustomer;
+
 
     @Override
     protected Serializable pkVal() {

+ 78 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/CustomerInfo.java

@@ -0,0 +1,78 @@
+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 2021-07-31
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class CustomerInfo extends Model<CustomerInfo> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 客户编码
+     */
+    @TableField("customer_code")
+    private String customerCode;
+
+    /**
+     * 客户公司名称
+     */
+    @TableField("customer_name")
+    private String customerName;
+
+    /**
+     * 联系人
+     */
+    @TableField("contact_name")
+    private String contactName;
+
+    /**
+     * 联系人电话
+     */
+    @TableField("contact_phone")
+    private String contactPhone;
+
+    /**
+     * 邮箱
+     */
+    @TableField("email")
+    private String email;
+
+    /**
+     * 地址
+     */
+    @TableField("address")
+    private String address;
+
+    /**
+     * 系统公司id
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 17 - 37
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/EarningSnapshot.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
 import java.io.Serializable;
+import java.util.List;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
@@ -19,7 +20,7 @@ import org.springframework.format.annotation.DateTimeFormat;
  * </p>
  *
  * @author Seyason
- * @since 2021-05-15
+ * @since 2021-08-02
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -41,8 +42,8 @@ public class EarningSnapshot extends Model<EarningSnapshot> {
      * 发生时间
      */
     @TableField("indate")
-    @DateTimeFormat(pattern = "yyyy-MM-dd")
     @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDateTime indate;
 
     /**
@@ -64,53 +65,32 @@ public class EarningSnapshot extends Model<EarningSnapshot> {
     private Integer contractAmount;
 
     /**
-     * 人员成本
+     * 利润
      */
-    @TableField("base_man")
-    private Integer baseMan;
+    @TableField("profit")
+    private Integer profit;
 
     /**
-     * 费用
+     * 利润率
      */
-    @TableField("base_fee")
-    private Integer baseFee;
+    @TableField("profit_percent")
+    private Double profitPercent;
 
     /**
-     * 外包费用
+     * 总成本
      */
-    @TableField("base_outsourcing")
-    private Integer baseOutsourcing;
+    @TableField("cost_total")
+    private Integer costTotal;
 
     /**
-     * 风险预留金额1
+     * 细分项
      */
-    @TableField("base_risk1")
-    private Integer baseRisk1;
+    @TableField("cost_data")
+    private String costData;
 
-    /**
-     * 风险预留金额2
-     */
-    @TableField("base_risk2")
-    private Integer baseRisk2;
-
-    /**
-     * 利润率A
-     */
-    @TableField("profit_a")
-    private Double profitA;
-
-    /**
-     * 利润率B
-     */
-    @TableField("profit_b")
-    private Double profitB;
-
-    /**
-     * 利润率C
-     */
-    @TableField("profit_c")
-    private Double profitC;
 
+    @TableField(exist = false)
+    private List<ProjectBasecost> costList;
 
     @Override
     protected Serializable pkVal() {

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

@@ -21,7 +21,7 @@ import org.springframework.format.annotation.DateTimeFormat;
  * </p>
  *
  * @author Seyason
- * @since 2021-06-22
+ * @since 2021-08-01
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -194,6 +194,18 @@ public class Project extends Model<Project> {
 
     @TableField(exist = false)
     private List<Map<String, Object>> participationList;
+    /**
+     * 客户id
+     */
+    @TableField("customer_id")
+    private Integer customerId;
+
+    /**
+     * 客户名称
+     */
+    @TableField("customer_name")
+    private String customerName;
+
 
     @Override
     protected Serializable pkVal() {

+ 60 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectBasecost.java

@@ -0,0 +1,60 @@
+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 2021-08-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ProjectBasecost extends Model<ProjectBasecost> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 项目id
+     */
+    @TableField("project_id")
+    private Integer projectId;
+
+    /**
+     * 预算项id
+     */
+    @TableField("base_id")
+    private Integer baseId;
+
+    /**
+     * 预算项名称
+     */
+    @TableField("base_name")
+    private String baseName;
+
+    /**
+     * 预算金额
+     */
+    @TableField("base_amount")
+    private Integer baseAmount;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

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

@@ -0,0 +1,48 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-08-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ProjectBasecostSetting extends Model<ProjectBasecostSetting> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 预估成本项名称
+     */
+    @TableField("name")
+    private String name;
+
+    /**
+     * 公司id
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 19 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/CustomerProject.java

@@ -0,0 +1,19 @@
+package com.management.platform.entity.vo;
+
+import com.management.platform.entity.Project;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class CustomerProject extends Project {
+    private Integer projectNum;
+    private String projectIds;
+    private String projectNames;
+
+    private List<CustomerProject> children;
+}

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

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

+ 20 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/CustomerInfoMapper.java

@@ -0,0 +1,20 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.CustomerInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.test.context.jdbc.Sql;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-07-31
+ */
+public interface CustomerInfoMapper extends BaseMapper<CustomerInfo> {
+
+    public List<CustomerInfo> getAll(Integer companyId);
+}

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

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

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

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

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

@@ -2,6 +2,7 @@ package com.management.platform.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.management.platform.entity.Project;
+import com.management.platform.entity.vo.CustomerProject;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Update;
@@ -36,4 +37,9 @@ public interface ProjectMapper extends BaseMapper<Project> {
 
     List<Project> getProjectInAndOut(Integer companyId, Integer pageStart, Integer pageSize);
 
+    List<CustomerProject> getCustomerProjectInAndOut(Integer companyId, Integer pageStart, Integer pageSize);
+
+    Integer getCustomerProjectInAndOutCount(Integer companyId);
+
+    List<CustomerProject> getProjectInAndOutByRange(Integer companyId, List<Integer> ids);
 }

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

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

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

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

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.ProjectBasecost;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-08-02
+ */
+public interface ProjectBasecostService extends IService<ProjectBasecost> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.ProjectBasecostSetting;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-08-02
+ */
+public interface ProjectBasecostSettingService extends IService<ProjectBasecostSetting> {
+
+}

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

@@ -26,12 +26,9 @@ public interface ProjectService extends IService<Project> {
                             String planEndDate,
                             Integer level,
                             Integer contractAmount,
-                            Integer baseMan,
-                            Integer baseFee,
-                            Integer baseOutsourcing,
-                            Integer baseRisk1,
-                            Integer baseRisk2,
+                            String projectBaseCostData,
                             Integer budget,
+                            Integer customerId,
                             HttpServletRequest request);
 
     HttpRespMsg deleteProject(Integer id);
@@ -56,7 +53,7 @@ public interface ProjectService extends IService<Project> {
 
     HttpRespMsg addMemb(Integer id, String[] userId);
 
-    HttpRespMsg adjustBase(Project project, HttpServletRequest request);
+    HttpRespMsg adjustBase(String baseCostData, Project project, HttpServletRequest request);
 
     HttpRespMsg exportProfit(HttpServletRequest request);
 
@@ -75,4 +72,8 @@ public interface ProjectService extends IService<Project> {
     HttpRespMsg exportProjectInAndOut(HttpServletRequest request);
 
     HttpRespMsg importData(String userId, MultipartFile file, HttpServletRequest request);
+
+    HttpRespMsg getCustomerProjectInAndOut(Integer pageIndex, Integer pageSize, HttpServletRequest request);
+
+    HttpRespMsg exportCustomerProjectInAndOut(HttpServletRequest request);
 }

+ 0 - 30
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ScreenshotService.java

@@ -1,30 +0,0 @@
-package com.management.platform.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.management.platform.entity.Screenshot;
-import com.management.platform.entity.vo.ScreenshotVO;
-import com.management.platform.util.HttpRespMsg;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * <p>
- * 服务类
- * </p>
- *
- * @author 吴涛涛
- * @since 2020-01-02
- */
-public interface ScreenshotService extends IService<Screenshot> {
-    HttpRespMsg getLatestScreenshotList(String date, HttpServletRequest request);
-
-    HttpRespMsg getTodayScreenshotList(String userId, String date);
-
-    HttpRespMsg getScreenshotDate(String date, HttpServletRequest request);
-
-    HttpRespMsg saveAndProcessImage(ScreenshotVO screenshotvo);
-
-    HttpRespMsg reTestPicMatch(int id);
-
-    HttpRespMsg updateRedisPicContentKeywords();
-}

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

@@ -49,4 +49,10 @@ public interface UserService extends IService<User> {
     HttpRespMsg exportUsers(Integer containInvalid, HttpServletRequest request);
 
     HttpRespMsg sendVcode(String mobile);
+
+    HttpRespMsg pushFillReport(String ids, HttpServletRequest request, String date);
+
+    HttpRespMsg exportMembList(boolean isFill, String ids, HttpServletRequest request, String date);
+
+    HttpRespMsg getHRList(HttpServletRequest request);
 }

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.AuditWorkflowTimeSetting;
+import com.management.platform.mapper.AuditWorkflowTimeSettingMapper;
+import com.management.platform.service.AuditWorkflowTimeSettingService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-07-25
+ */
+@Service
+public class AuditWorkflowTimeSettingServiceImpl extends ServiceImpl<AuditWorkflowTimeSettingMapper, AuditWorkflowTimeSetting> implements AuditWorkflowTimeSettingService {
+
+}

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.CustomerInfo;
+import com.management.platform.mapper.CustomerInfoMapper;
+import com.management.platform.service.CustomerInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-07-31
+ */
+@Service
+public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, CustomerInfo> implements CustomerInfoService {
+
+}

+ 11 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java

@@ -64,6 +64,8 @@ public class DingDingServiceImpl implements DingDingService {
     private UserService userService;
     @Resource
     private ProjectMapper projectMapper;
+    @Resource
+    private ProjectBasecostSettingMapper projectBasecostSettingMapper;
 
     @Override
     @Async
@@ -94,6 +96,15 @@ public class DingDingServiceImpl implements DingDingService {
             TimeType timeType = new TimeType();
             timeType.setCompanyId(company.getId());
             timeTypeMapper.insert(timeType);
+
+            //生成项目的成本基线默认条目
+            String[] array = com.management.platform.util.Constant.DEFAULT_BASE_COST_ITEMS;
+            for (String baseItem : array) {
+                ProjectBasecostSetting setting = new ProjectBasecostSetting();
+                setting.setName(baseItem);
+                setting.setCompanyId(company.getId());
+                projectBasecostSettingMapper.insert(setting);
+            }
         }
 
 

+ 7 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceServiceImpl.java

@@ -359,7 +359,11 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                     medical = userFinance.getInsuranceMedical().multiply(new BigDecimal(workingTime)).divide(userTime.get(creatorId).workingTime, 4, BigDecimal.ROUND_HALF_UP);
                     loseJob = userFinance.getInsuranceLosejob().multiply(new BigDecimal(workingTime)).divide(userTime.get(creatorId).workingTime, 4, BigDecimal.ROUND_HALF_UP);
                     house = userFinance.getHouseFund().multiply(new BigDecimal(workingTime)).divide(userTime.get(creatorId).workingTime, 4, BigDecimal.ROUND_HALF_UP);
-                    other = userFinance.getOthers().multiply(new BigDecimal(workingTime)).divide(userTime.get(creatorId).workingTime, 4, BigDecimal.ROUND_HALF_UP);
+                    if (userFinance.getOthers() == null) {
+                        other = new BigDecimal(0);
+                    } else {
+                        other = userFinance.getOthers().multiply(new BigDecimal(workingTime)).divide(userTime.get(creatorId).workingTime, 4, BigDecimal.ROUND_HALF_UP);
+                    }
                 } else {
                     System.out.println("财务数据中未找到用户:"+creatorId);
 
@@ -463,7 +467,7 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                         BigDecimal medical = userFinance.getInsuranceMedical().multiply(new BigDecimal(workingTime)).divide(userTime.get(creatorId).workingTime, 4, BigDecimal.ROUND_HALF_UP);
                         BigDecimal loseJob = userFinance.getInsuranceLosejob().multiply(new BigDecimal(workingTime)).divide(userTime.get(creatorId).workingTime, 4, BigDecimal.ROUND_HALF_UP);
                         BigDecimal house = userFinance.getHouseFund().multiply(new BigDecimal(workingTime)).divide(userTime.get(creatorId).workingTime, 4, BigDecimal.ROUND_HALF_UP);
-                        BigDecimal other = userFinance.getOthers().multiply(new BigDecimal(workingTime)).divide(userTime.get(creatorId).workingTime, 4, BigDecimal.ROUND_HALF_UP);
+                        BigDecimal other = userFinance.getOthers() == null?new BigDecimal(0):userFinance.getOthers().multiply(new BigDecimal(workingTime)).divide(userTime.get(creatorId).workingTime, 4, BigDecimal.ROUND_HALF_UP);
 
                         membRowData.add(us.getName());
                         membRowData.add(workingTime+"");
@@ -504,6 +508,7 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
 
             httpRespMsg.data = resp;
         } catch (NullPointerException e) {
+            e.printStackTrace();
             httpRespMsg.setError("验证失败");
             return httpRespMsg;
         }

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.ProjectBasecost;
+import com.management.platform.mapper.ProjectBasecostMapper;
+import com.management.platform.service.ProjectBasecostService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-08-02
+ */
+@Service
+public class ProjectBasecostServiceImpl extends ServiceImpl<ProjectBasecostMapper, ProjectBasecost> implements ProjectBasecostService {
+
+}

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.ProjectBasecostSetting;
+import com.management.platform.mapper.ProjectBasecostSettingMapper;
+import com.management.platform.service.ProjectBasecostSettingService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-08-02
+ */
+@Service
+public class ProjectBasecostSettingServiceImpl extends ServiceImpl<ProjectBasecostSettingMapper, ProjectBasecostSetting> implements ProjectBasecostSettingService {
+
+}

+ 197 - 48
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -1,10 +1,13 @@
 package com.management.platform.service.impl;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.entity.*;
+import com.management.platform.entity.vo.CustomerProject;
 import com.management.platform.entity.vo.ProjectDataItem;
 import com.management.platform.entity.vo.ProjectVO;
 import com.management.platform.mapper.*;
@@ -74,6 +77,10 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     @Resource
     private TimeTypeMapper timeTypeMapper;
     @Resource
+    CustomerInfoMapper customerInfoMapper;
+    @Resource
+    ProjectBasecostMapper projectBasecostMapper;
+    @Resource
     private HttpServletResponse response;
 
     @Value(value = "${upload.path}")
@@ -98,7 +105,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     //分页获取项目列表
     @Override
     public HttpRespMsg getProjectPage(Integer pageIndex, Integer pageSize, String keyword, Integer searchField,
-                                      Integer status,HttpServletRequest request) {
+                                      Integer status, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             //通过公司id获取该公司所有的项目列表
@@ -170,12 +177,9 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                    String planEndDate,
                                    Integer level,
                                    Integer contractAmount,
-                                   Integer baseMan,
-                                   Integer baseFee,
-                                   Integer baseOutsourcing,
-                                   Integer baseRisk1,
-                                   Integer baseRisk2,
+                                   String projectBaseCostData,
                                    Integer budget,
+                                   Integer customerId,
                                    HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         User user = userMapper.selectById(request.getHeader("Token"));
@@ -200,44 +204,37 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                             .setCreateDate(LocalDate.now())
                             .setContractAmount(contractAmount)
                             .setBudget(budget)
-                            .setBaseFee(baseFee)
-                            .setBaseMan(baseMan)
-                            .setBaseOutsourcing(baseOutsourcing)
-                            .setBaseRisk1(baseRisk1)
-                            .setBaseRisk2(baseRisk2);
+                            .setCustomerId(customerId);
                     if (!StringUtils.isEmpty(planStartDate)) {
                         project.setPlanStartDate(LocalDate.parse(planStartDate));
                     }
                     if (!StringUtils.isEmpty(planEndDate)) {
                         project.setPlanEndDate(LocalDate.parse(planEndDate));
                     }
+                    if (customerId != null && customerId != 0) {
+                        project.setCustomerName(customerInfoMapper.selectById(customerId).getCustomerName());
+                    } else {
+                        project.setCustomerName("");
+                    }
                     if (projectMapper.insert(project) == 0) {
                         httpRespMsg.setError("操作失败");
                     } else {
+                        updateProjectBaseCostData(projectBaseCostData, project.getId());
+
                         //创建项目涉及到基线成本数据,要填写到快照表中
                         EarningSnapshot snapshot = new EarningSnapshot();
                         snapshot.setProjectId(project.getId());
                         snapshot.setContractAmount(project.getContractAmount());
-                        snapshot.setBaseMan(project.getBaseMan());
-                        snapshot.setBaseOutsourcing(project.getBaseOutsourcing());
-                        snapshot.setBaseFee(project.getBaseFee());
-                        snapshot.setBaseRisk1(project.getBaseRisk1());
-                        snapshot.setBaseRisk2(project.getBaseRisk2());
+                        snapshot.setCostData(projectBaseCostData);
                         snapshot.setCreatorId(user.getId());
                         snapshot.setCreatorName(user.getName());
+                        snapshot.setCostTotal(budget);
 
                         if (project.getContractAmount() == null || project.getContractAmount() == 0 ) {
                             //无需处理
                         } else {
-                            int bf = getNotNullInt(project.getBaseFee());
-                            int bm = getNotNullInt(project.getBaseMan());
-                            int bos = getNotNullInt(project.getBaseOutsourcing());
-                            int br1 = getNotNullInt(project.getBaseRisk1());
-                            int br2 = getNotNullInt(project.getBaseRisk2());
-                            int total = bf + +bm + bos +br1 + br2;
-                            snapshot.setProfitA(100.0*(project.getContractAmount() - total)/project.getContractAmount());
-                            snapshot.setProfitB(100.0*(project.getContractAmount() - total-br1)/project.getContractAmount());
-                            snapshot.setProfitC(100.0*(project.getContractAmount() - total-br1 - br2)/project.getContractAmount());
+                            snapshot.setProfit(project.getContractAmount() - budget);
+                            snapshot.setProfitPercent(100.0*(project.getContractAmount() - budget)/project.getContractAmount());
                             earningSnapshotMapper.insert(snapshot);
                         }
                     }
@@ -248,10 +245,9 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             //修改项目
             //检查项目编号不能重复
             Integer count = 0;
-            if (code != null) {
+            if (!StringUtils.isEmpty(code)) {
                 count = projectMapper.selectCount(new QueryWrapper<Project>().eq("company_id", companyId).eq("project_code", code).ne("id", id));
             }
-
             if (count > 0) {
                 httpRespMsg.setError("提交失败:项目编号已存在");
             } else {
@@ -260,17 +256,18 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                         .setLevel(level)
                         .setContractAmount(contractAmount)
                         .setBudget(budget)
-                        .setBaseFee(baseFee)
-                        .setBaseMan(baseMan)
-                        .setBaseOutsourcing(baseOutsourcing)
-                        .setBaseRisk1(baseRisk1)
-                        .setBaseRisk2(baseRisk2);;
+                        .setCustomerId(customerId);
                 if (!StringUtils.isEmpty(planStartDate)) {
                     p.setPlanStartDate(LocalDate.parse(planStartDate));
                 }
                 if (!StringUtils.isEmpty(planEndDate)) {
                     p.setPlanEndDate(LocalDate.parse(planEndDate));
                 }
+                if (customerId != null && customerId != 0) {
+                    p.setCustomerName(customerInfoMapper.selectById(customerId).getCustomerName());
+                } else {
+                    p.setCustomerName("");
+                }
                 if (projectMapper.updateById(p) == 0) {
                     httpRespMsg.setError("操作失败");
                 } else {
@@ -278,6 +275,57 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     ProjectTimer timer = new ProjectTimer();
                     timer.setProjectName(name);
                     projectTimerMapper.update(timer, new QueryWrapper<ProjectTimer>().eq("project_id", id));
+
+                    List<ProjectBasecost> costList = updateProjectBaseCostData(projectBaseCostData, p.getId());
+
+                    //如果不存在基线成本快照,则生成
+                    List<EarningSnapshot> earningSnapshots = earningSnapshotMapper.selectList(new QueryWrapper<EarningSnapshot>().eq("project_id", p.getId()).orderByDesc("id").last("limit 1"));
+                    boolean shouldAdd = false;
+                    if (earningSnapshots.size() == 0) {
+                        shouldAdd = true;
+                    } else {
+                        //检查是否发生变化
+                        String data = earningSnapshots.get(0).getCostData();
+                        if (data == null) {
+                            shouldAdd = true;
+                        } else {
+                            JSONArray oldArray = JSONArray.parseArray(data);
+                            if (oldArray.size() != costList.size()) {
+                                //条目数量有变化,需要新增
+                                shouldAdd = true;
+                            } else {
+                                for (int i=0; i<oldArray.size(); i++) {
+                                    JSONObject jsonObject = oldArray.getJSONObject(i);
+                                    ProjectBasecost projectBasecost = JSONObject.toJavaObject(jsonObject, ProjectBasecost.class);
+                                    Optional<ProjectBasecost> first = costList.stream().filter(cost -> cost.getBaseId().equals(projectBasecost.getBaseId())).findFirst();
+                                    if (first.isPresent()) {
+                                        if (!first.get().getBaseAmount().equals(projectBasecost.getBaseAmount())) {
+                                            shouldAdd = true;
+                                            break;
+                                        }
+                                    } else {
+                                        //有新增的条目,需要增加
+                                        shouldAdd = true;
+                                        break;
+                                    }
+                                }
+                            }
+
+                        }
+                    }
+                    if (shouldAdd) {
+                        EarningSnapshot record = new EarningSnapshot();
+                        record.setProjectId(p.getId());
+                        record.setCreatorId(user.getId());
+                        record.setCreatorName(user.getName());
+                        record.setContractAmount(p.getContractAmount());
+                        record.setCostData(projectBaseCostData);
+                        record.setCostTotal(p.getBudget());
+                        record.setProfit(p.getContractAmount() - p.getBudget());
+                        record.setProfitPercent(100.0*(p.getContractAmount() - p.getBudget())/p.getContractAmount());
+                        earningSnapshotMapper.insert(record);
+                    }
+
                 }
             }
         }
@@ -293,6 +341,20 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         return httpRespMsg;
     }
 
+    //更新项目的基线成本数据
+    private List<ProjectBasecost> updateProjectBaseCostData(String data, Integer projectId) {
+        JSONArray array = JSONArray.parseArray(data);
+        projectBasecostMapper.delete(new QueryWrapper<ProjectBasecost>().eq("project_id", projectId));
+        List<ProjectBasecost> costList = new ArrayList<>();
+        for (int i=0;i<array.size(); i++) {
+            ProjectBasecost projectBasecost = JSONObject.toJavaObject(array.getJSONObject(i), ProjectBasecost.class);
+            projectBasecost.setProjectId(projectId);
+            projectBasecostMapper.insert(projectBasecost);
+            costList.add(projectBasecost);
+        }
+        return costList;
+    }
+
     private int getNotNullInt(Integer integer) {
         return integer==null?0:integer.intValue();
     }
@@ -518,15 +580,24 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     }
 
     @Override
-    public HttpRespMsg adjustBase(Project project, HttpServletRequest request) {
+    public HttpRespMsg adjustBase(String baseCostData, Project project, HttpServletRequest request) {
         HttpRespMsg msg = new HttpRespMsg();
         if (project.getContractAmount() == 0) {
             msg.setError("项目金额不能为0");
             return msg;
         }
         //计算项目总成本
-        project.setBudget(project.getBaseFee()+project.getBaseMan()
-                    +project.getBaseOutsourcing()+project.getBaseRisk1()+project.getBaseRisk2());
+        projectBasecostMapper.delete(new QueryWrapper<ProjectBasecost>().eq("project_id", project.getId()));
+        JSONArray array = JSONArray.parseArray(baseCostData);
+        int totalBudget = 0;
+        for (int i=0;i<array.size(); i++) {
+            JSONObject obj = array.getJSONObject(i);
+            ProjectBasecost cost = JSONObject.toJavaObject(obj, ProjectBasecost.class);
+            cost.setProjectId(project.getId());
+            projectBasecostMapper.insert(cost);
+            totalBudget += cost.getBaseAmount();
+        }
+        project.setBudget(totalBudget);
         projectMapper.updateById(project);
         //增加基线快照
         User user = userMapper.selectById(request.getHeader("Token"));
@@ -535,18 +606,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         record.setCreatorId(user.getId());
         record.setCreatorName(user.getName());
         record.setContractAmount(project.getContractAmount());
-        record.setBaseFee(project.getBaseFee());
-        record.setBaseMan(project.getBaseMan());
-        record.setBaseOutsourcing(project.getBaseOutsourcing());
-        record.setBaseRisk1(project.getBaseRisk1());
-        record.setBaseRisk2(project.getBaseRisk2());
-        int total = project.getBaseFee()+project.getBaseMan()+project.getBaseOutsourcing()+project.getBaseRisk1()+project.getBaseRisk2();
-
-        record.setProfitA(100.0*(project.getContractAmount() - total)/project.getContractAmount());
-        record.setProfitB(100.0*(project.getContractAmount() - total-project.getBaseRisk1())/project.getContractAmount());
-        record.setProfitC(100.0*(project.getContractAmount() - total-project.getBaseRisk1() - project.getBaseRisk2())/project.getContractAmount());
+        record.setCostData(baseCostData);
+        record.setCostTotal(project.getBudget());
+        record.setProfit(project.getContractAmount() - totalBudget);
+        record.setProfitPercent(100.0*(project.getContractAmount() - totalBudget)/project.getContractAmount());
         earningSnapshotMapper.insert(record);
-
         return new HttpRespMsg();
     }
 
@@ -770,12 +834,10 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         User user = userMapper.selectById(request.getHeader("Token"));
         Integer companyId = user.getCompanyId();
         //撤销的项目不算
-        //撤销的项目不算
         QueryWrapper<Project> queryWrapper = new QueryWrapper<Project>().eq("company_id", companyId);
         queryWrapper.and(wrapper->wrapper.isNull("status").or().ne("status", 3));
         int total = projectMapper.selectCount(queryWrapper);
         int pageStart = (pageIndex -1) * pageSize;
-        System.out.println("companyId="+companyId+", pageStart="+pageStart+", pageSize="+pageSize);
         List projectTask = projectMapper.getProjectInAndOut(companyId, pageStart, pageSize);
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         Map<String, Object> map = new HashMap<>();
@@ -785,6 +847,26 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         return httpRespMsg;
     }
 
+    @Override
+    public HttpRespMsg getCustomerProjectInAndOut(Integer pageIndex, Integer pageSize, HttpServletRequest request) {
+        User user = userMapper.selectById(request.getHeader("Token"));
+        Integer companyId = user.getCompanyId();
+
+        int total = projectMapper.getCustomerProjectInAndOutCount(companyId);
+        int pageStart = (pageIndex -1) * pageSize;
+        List<CustomerProject> list = projectMapper.getCustomerProjectInAndOut(companyId, pageStart, pageSize);
+        list.forEach(data->{
+            List<Integer> integers = ListUtil.convertIntegerIdsArrayToList(data.getProjectIds());
+            data.setChildren(projectMapper.getProjectInAndOutByRange(companyId, integers));
+        });
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        Map<String, Object> map = new HashMap<>();
+        map.put("records", list);
+        map.put("total", total);
+        httpRespMsg.data = map;
+        return httpRespMsg;
+    }
+
     @Override
     public HttpRespMsg exportProjectInAndOut(HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
@@ -825,6 +907,73 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         return httpRespMsg;
     }
 
+    @Override
+    public HttpRespMsg exportCustomerProjectInAndOut(HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        //通过公司id获取该公司所有的项目列表
+        User user = userMapper.selectById(request.getHeader("Token"));
+        Integer companyId = user.getCompanyId();
+
+        List<CustomerProject> projectList = projectMapper.getCustomerProjectInAndOut(companyId, null, null);
+        List<List<String>> exportList = new ArrayList<>();
+        String[] titles = {"客户名称", "相关项目", "合同金额", "人工成本", "一般费用", "差旅费用","外包费用", "总费用", "利润", "利润率"};
+        exportList.add(Lists.list(titles));
+        for (CustomerProject project : projectList) {
+            List<String> data = new ArrayList<>();
+            data.add(project.getCustomerName());
+            //客户上把项目空着
+            data.add("");
+            data.add(project.getContractAmount() != null?project.getContractAmount().toString():"");
+            data.add(project.getFeeMan().toString());
+            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("");
+            }
+            exportList.add(data);
+
+            //查找项目,项目上把客户空着
+            List<CustomerProject> projectInAndOutByRange = projectMapper.getProjectInAndOutByRange(companyId, ListUtil.convertIntegerIdsArrayToList(project.getProjectIds()));
+            projectInAndOutByRange.forEach(child->{
+                List<String> dataChild = new ArrayList<>();
+                dataChild.add("");
+                //客户上把项目空着
+                dataChild.add(child.getProjectNames());
+                dataChild.add(child.getContractAmount() != null?child.getContractAmount().toString():"");
+                dataChild.add(child.getFeeMan().toString());
+                dataChild.add(child.getFeeNormal().toString());
+                dataChild.add(child.getFeeTravel().toString());
+                dataChild.add(child.getFeeOutsourcing().toString());
+                double totalFeeChild = child.getFeeMan() + child.getFeeNormal()+ child.getFeeTravel()+ child.getFeeOutsourcing();
+                dataChild.add(totalFeeChild+"");
+                if (child.getContractAmount() != null && child.getContractAmount() > 0) {
+                    double profitAmt = child.getContractAmount() - totalFeeChild;
+                    dataChild.add(profitAmt+"");
+                    dataChild.add(new java.text.DecimalFormat("#.0").format((100*profitAmt/project.getContractAmount()))+"%");
+                } else {
+                    double profitAmt = -totalFeeChild;
+                    dataChild.add(profitAmt+"");
+                    dataChild.add("");
+                }
+                exportList.add(dataChild);
+            });
+
+        }
+        String fileName = "客户项目利润报表_"+System.currentTimeMillis();
+        ExcelUtil.exportGeneralExcelByTitleAndList(fileName, exportList, path);
+        httpRespMsg.data =  pathPrefix + fileName+".xls";
+        return httpRespMsg;
+    }
+
     @Override
     public HttpRespMsg importData(String userId, MultipartFile multipartFile, HttpServletRequest request) {
         HttpRespMsg msg = new HttpRespMsg();

+ 0 - 778
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ScreenshotServiceImpl.java

@@ -1,778 +0,0 @@
-package com.management.platform.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.management.platform.constant.Constant;
-import com.management.platform.constant.Parameter;
-import com.management.platform.entity.PicContentKeywords;
-import com.management.platform.entity.Screenshot;
-import com.management.platform.entity.TimeCalculation;
-import com.management.platform.entity.TimeCalculationShow;
-import com.management.platform.entity.vo.ScreenshotVO;
-import com.management.platform.mapper.*;
-import com.management.platform.service.ScreenshotService;
-import com.management.platform.util.*;
-import org.apache.log4j.Logger;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.Resource;
-import javax.imageio.ImageIO;
-import javax.servlet.http.HttpServletRequest;
-import java.awt.image.BufferedImage;
-import java.io.*;
-import java.text.SimpleDateFormat;
-import java.time.LocalDate;
-import java.time.LocalTime;
-import java.time.format.DateTimeFormatter;
-import java.time.temporal.ChronoUnit;
-import java.util.*;
-import java.util.regex.Pattern;
-
-/**
- * <p>
- * 服务实现类
- * </p>
- *
- * @author 吴涛涛
- * @since 2020-01-02
- */
-@Service
-@Transactional
-public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screenshot> implements ScreenshotService {
-    public static List<String> nKeyWordsList = new ArrayList<String>();
-    public static Logger log = Logger.getLogger(ScreenshotServiceImpl.class);
-
-    //检测时间间隔秒数
-    private static Integer DETECTION_INTERVAL = 600;
-
-    @Value(value = "${upload.path}")
-    private String path;
-    @Value(value = "${picrecongnize.browser}")
-    private String browserFolder;
-    @Value(value = "${picrecongnize.develop}")
-    private String developFolder;
-    @Value(value = "${picrecongnize.im}")
-    private String imFolder;
-    @Value(value = "${picrecongnize.design}")
-    private String designFolder;
-
-    @Value("classpath:novel_words.data")
-    private org.springframework.core.io.Resource novelWords;
-    @Autowired
-    private RedisUtil redisUtil;
-
-    @Resource
-    private ScreenshotMapper screenshotMapper;
-    @Resource
-    private PicContentKeywordsMapper picContentKeywordsMapper;
-    @Resource
-    private TimeCalculationMapper timeCalculationMapper;
-    @Resource
-    private UserMapper userMapper;
-    @Resource
-    private TimeCalculationShowMapper timeCalculationShowMapper;
-
-    //每次获取到截屏后计算并处理
-    private void calculateTime(Screenshot screenshot) {
-        try {
-            //首先拿去处理show表
-            calculateShowTime(screenshot);
-
-            //如果图片类型为空 则认为是 -1 - 其他
-            if (null == screenshot.getPicType()) {
-                screenshot.setPicType(-1);
-            }
-            //默认状态为不连续 如果下面判断是连续才会修改为true
-            Boolean isConsecutive = false,
-                    isSameType = false;
-            //获取本人当天结束时间为准的最后一条记录
-            TimeCalculation latestRecord = timeCalculationMapper.selectOne(new QueryWrapper<TimeCalculation>()
-                    .eq("user_id", screenshot.getUid())
-                    .eq("date", screenshot.getIndate().toLocalDate())
-                    .orderByDesc("id")
-                    .last("LIMIT 1"));
-            //截图时间
-            LocalTime currentTime = screenshot.getIndate().toLocalTime();
-            //如果有上一条记录
-            if (latestRecord != null) {
-                //前后两张是否相同类型
-                isSameType = latestRecord.getActionType().equals(screenshot.getPicType());
-                //前后两张时间是否连续 这个目前为600秒
-                LocalTime estimatedTime = latestRecord.getEndTime();
-                Integer durationSecond = ((currentTime.getHour() - estimatedTime.getHour()) * 3600
-                        + (currentTime.getMinute() - estimatedTime.getMinute()) * 60
-                        + (currentTime.getSecond() - estimatedTime.getSecond()));
-                //断层不大于一定时间的话  用来判断是否连续
-                isConsecutive = durationSecond <= DETECTION_INTERVAL;
-            }
-            if (isConsecutive && isSameType) {
-                //如果时间连续 且是同一类型的话 修改上一条记录的最后时间和持续时间
-                LocalTime startTime = latestRecord.getStartTime();
-                //计算新的间隔
-                Integer duration = ((currentTime.getHour() - startTime.getHour()) * 3600
-                        + (currentTime.getMinute() - startTime.getMinute()) * 60
-                        + (currentTime.getSecond() - startTime.getSecond()));
-                //设置新的结束时间和持续时间 保存记录
-                latestRecord.setEndTime(currentTime).setDuration(duration);
-                timeCalculationMapper.updateById(latestRecord);
-            } else {
-                //如果不是连续的话 新增一个记录
-                TimeCalculation timeCalculation = new TimeCalculation();
-                timeCalculation
-                        .setUserId(screenshot.getUid())
-                        //根据截图种类设置行为代号
-                        .setActionType(screenshot.getPicType())
-                        .setDate(screenshot.getIndate().toLocalDate())
-                        //设置开始时间和结束时间都为当前时间
-                        .setStartTime(currentTime)
-                        .setEndTime(currentTime)
-                        //第一次的持续时间默认为最少单位1秒
-                        .setDuration(1)
-                        .setPicUrl(screenshot.getPicUrl());
-                timeCalculationMapper.insert(timeCalculation);
-                if (isConsecutive) {
-                    //然后如果只是类型不同但是能连上的话
-                    LocalTime startTime = latestRecord.getStartTime();
-                    //计算新的间隔
-                    Integer duration = ((currentTime.getHour() - startTime.getHour()) * 3600
-                            + (currentTime.getMinute() - startTime.getMinute()) * 60
-                            + (currentTime.getSecond() - startTime.getSecond()));
-                    //设置新的结束时间和持续时间 保存记录
-                    latestRecord.setEndTime(currentTime).setDuration(duration);
-                    timeCalculationMapper.updateById(latestRecord);
-                }
-            }
-            /*之后可能还需要处理跨越一天的情况*/
-        } catch (NullPointerException e) {
-            //凡是有空指针说明缺少用户id或者时间数据
-            log.info("工作时长统计失败 缺少用户或时间数据");
-        }
-    }
-
-    //每次获取到截屏后计算并处理
-    private void calculateShowTime(Screenshot screenshot) {
-        try {
-            //如果图片类型为空 则认为是 -1 - 其他
-            if (null == screenshot.getPicType()) {
-                screenshot.setPicType(-1);
-            }
-            //默认状态为不连续 如果下面判断是连续才会修改为true
-            Boolean isConsecutive = false;
-            //获取本人当天结束时间为准的最后一条记录
-            TimeCalculationShow latestRecord = timeCalculationShowMapper.selectOne(
-                    new QueryWrapper<TimeCalculationShow>()
-                            .eq("user_id", screenshot.getUid())
-                            .eq("date", screenshot.getIndate().toLocalDate())
-                            .orderByDesc("id")
-                            .last("LIMIT 1"));
-            //截图时间
-            LocalTime currentTime = screenshot.getIndate().toLocalTime();
-            //如果有上一条记录
-            if (latestRecord != null) {
-                //前后两张时间是否连续 这个目前为600秒
-                LocalTime estimatedTime = latestRecord.getEndTime();
-                Integer durationSecond = ((currentTime.getHour() - estimatedTime.getHour()) * 3600
-                        + (currentTime.getMinute() - estimatedTime.getMinute()) * 60
-                        + (currentTime.getSecond() - estimatedTime.getSecond()));
-                //断层不大于一定时间的话  用来判断是否连续
-                isConsecutive = durationSecond <= DETECTION_INTERVAL;
-            }
-
-            if (isConsecutive) {
-                //如果是连续的话 修改上一条记录的最后时间和持续时间
-                LocalTime startTime = latestRecord.getStartTime();
-                //计算新的间隔
-                Integer duration = ((currentTime.getHour() - startTime.getHour()) * 3600
-                        + (currentTime.getMinute() - startTime.getMinute()) * 60
-                        + (currentTime.getSecond() - startTime.getSecond()));
-                //设置新的结束时间和持续时间 保存记录
-                latestRecord.setEndTime(currentTime).setDuration(duration);
-                timeCalculationShowMapper.updateById(latestRecord);
-            } else {
-                //如果不是连续的话 新增一个记录
-                TimeCalculationShow timeCalculationShow = new TimeCalculationShow();
-                timeCalculationShow
-                        .setUserId(screenshot.getUid())
-                        .setDate(screenshot.getIndate().toLocalDate())
-                        //设置开始时间和结束时间都为当前时间
-                        .setStartTime(currentTime)
-                        .setEndTime(currentTime)
-                        //第一次的持续时间默认为最少单位1秒
-                        .setDuration(1);
-                timeCalculationShowMapper.insert(timeCalculationShow);
-            }
-            /*之后可能还需要处理跨越一天的情况*/
-        } catch (NullPointerException e) {
-            //凡是有空指针说明缺少用户id或者时间数据
-            log.info("工作时长统计失败 缺少用户或时间数据");
-        }
-    }
-
-    //列表截图
-    @Override
-    public HttpRespMsg getLatestScreenshotList(String date, HttpServletRequest request) {
-        HttpRespMsg httpRespMsg = new HttpRespMsg();
-        //获取某天每一个人最后一张截图
-        try {
-            List<Map<String, Object>> dataMap = screenshotMapper
-                    .getLatestScreenshotList(userMapper.selectById(request.getHeader("Token")).getCompanyId(), date);
-            // LocalDate.now(ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd");
-            for (Map<String, Object> map : dataMap) {
-                //对于每一张图 将时间戳转换为时间
-                map.put("time", new SimpleDateFormat("HH:mm:ss").format(map.get("indate")));
-                map.remove("indate");
-            }
-            httpRespMsg.data = dataMap;
-        } catch (NullPointerException e) {
-            httpRespMsg.setError("验证失败");
-            return httpRespMsg;
-        }
-        return httpRespMsg;
-    }
-
-    //获取个人截图页
-    @Override
-    public HttpRespMsg getTodayScreenshotList(String userId, String date) {
-        HttpRespMsg httpRespMsg = new HttpRespMsg();
-        Map<String, Object> resultMap = new HashMap<>();
-        List<String> srcList = new ArrayList<>();
-        List<Object> dataList = new ArrayList<>();
-        List<Screenshot> screenshotList = screenshotMapper.selectList(new QueryWrapper<Screenshot>()
-                .eq("date_str", date)
-                .eq("uid", userId)
-                .orderByDesc("indate"));
-        for (Screenshot screenshot : screenshotList) {
-            srcList.add(screenshot.getPicUrl());
-            Map<String, Object> map = new HashMap<>();
-            map.put("time", screenshot.getIndate().toLocalTime());
-            map.put("type", screenshot.getPicType() == null ? 0 : screenshot.getPicType());
-            dataList.add(map);
-        }
-        resultMap.put("srcList", srcList);
-        resultMap.put("data", dataList);
-        httpRespMsg.data = resultMap;
-        return httpRespMsg;
-    }
-
-    @Override
-    public HttpRespMsg getScreenshotDate(String date, HttpServletRequest request) {
-        HttpRespMsg httpRespMsg = new HttpRespMsg();
-        try {
-            List<Integer> userIdList = screenshotMapper.getCompanyUserId(request.getHeader("Token"));
-            if (screenshotMapper.selectCount(new QueryWrapper<Screenshot>()
-                    .eq("date_str", date)
-                    .in("uid", userIdList)) > 0) {
-                //当天有截图
-                httpRespMsg.data = date;
-            } else {
-                Screenshot futureScreenshot = screenshotMapper.selectOne(new QueryWrapper<Screenshot>()
-                        .gt("date_str", date)
-                        .in("uid", userIdList)
-                        .orderByAsc("date_str")
-                        .last("LIMIT 1"));
-                Screenshot historyScreenshot = screenshotMapper.selectOne(new QueryWrapper<Screenshot>()
-                        .lt("date_str", date)
-                        .in("uid", userIdList)
-                        .orderByDesc("date_str")
-                        .last("LIMIT 1"));
-                String futureDateString = futureScreenshot != null ? futureScreenshot.getDateStr() : null;
-                String historyDateString = historyScreenshot != null ? historyScreenshot.getDateStr() : null;
-                if (futureDateString == null && historyDateString == null) {
-                    httpRespMsg.data = null;
-                } else if (futureDateString == null) {
-                    httpRespMsg.data = historyDateString;
-                } else if (historyDateString == null) {
-                    httpRespMsg.data = futureDateString;
-                } else {
-                    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-                    LocalDate localDate = LocalDate.parse(date, dateTimeFormatter);
-                    LocalDate futureDate = LocalDate.parse(futureDateString, dateTimeFormatter);
-                    LocalDate historyDate = LocalDate.parse(historyDateString, dateTimeFormatter);
-                    Long future = ChronoUnit.DAYS.between(localDate, futureDate);
-                    Long history = ChronoUnit.DAYS.between(historyDate, localDate);
-                    if (future >= history) {
-                        httpRespMsg.data = historyDateString;
-                    } else {
-                        httpRespMsg.data = futureDateString;
-                    }
-                }
-            }
-        } catch (NullPointerException e) {
-            httpRespMsg.setError("验证失败");
-            return httpRespMsg;
-        }
-        return httpRespMsg;
-    }
-
-    @Override
-    public HttpRespMsg saveAndProcessImage(ScreenshotVO screenshotvo) {
-        Map<String, Object> fileMap = UploadFileToFileNameUtil.uploadFile(screenshotvo.getFile(), path);
-        String filePath = (String) fileMap.get("sqlFilePath");
-        Screenshot screenshot = new Screenshot();
-        BeanUtils.copyProperties(screenshotvo, screenshot);
-        screenshot.setPicUrl(filePath);
-        screenshot.setDateStr(DateTimeFormatter.ofPattern("yyyy-MM-dd").format(screenshotvo.getIndate()));
-        String accessToken = "";
-        if (redisUtil.existsKey(Parameter.ACCESS_TOKEN.getName())) {
-            accessToken = redisUtil.getKey(Parameter.ACCESS_TOKEN.getName());
-        } else {
-            Map<String, Object> map = AuthService.getAuth(Constant.API_KEY, Constant.SECRET_KEY);
-            accessToken = (String) map.get(Parameter.ACCESS_TOKEN.getName());
-            System.out.println(accessToken);
-            redisUtil.setKeyWithExpireTime(Parameter.ACCESS_TOKEN.getName(), accessToken, (Long) map.get(Parameter.EXPIRES_IN.getName()));
-        }
-        log.info("accessToken-->" + accessToken);
-        //利用token去检测
-//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-//        LocalDateTime l = LocalDateTime.parse("2019-02-03",dateTimeFormatter);
-//        Set<Object> members = new HashSet<>();
-//        if (redisUtil.existsKey(Constant.COMMON_SOFTWARE_KEYWORDS)) {
-//            members = redisUtil.members(Constant.COMMON_SOFTWARE_KEYWORDS);
-//        } else {
-//            List<PicContentKeywords> picContentKeywords = picContentKeywordsMapper.selectList(null);
-//            for (PicContentKeywords keyWord : picContentKeywords) {
-//                redisUtil.sSetJsonString("keyWords", keyWord);
-//            }
-//            //由于存入数据库的对象被序列化成了json字符串,所以从redis里拿方便
-//            members = redisUtil.members(Constant.COMMON_SOFTWARE_KEYWORDS);
-//        }
-        File picFile = new File((String) fileMap.get("newFile"));
-        System.out.println("File:" + picFile.getAbsolutePath());
-
-        List<String> textContents = new ArrayList<String>();
-
-        if (isIM(picFile) != null) {
-            screenshot.setPicType(9);//聊天
-        } else {
-            Map<String, Object> picResultMap = CheckPicUtil.generalPicTextContentMap(path + filePath.substring("/upload/".length()), accessToken);
-            if (picResultMap != null) {
-                textContents = (List<String>) picResultMap.get("wordsList");
-                screenshot.setPicContext((String) picResultMap.get("picContent"));
-            }
-            if (isNovel(textContents)) {
-                screenshot.setPicType(6);
-            } else if (isDocument(textContents)) {
-                screenshot.setPicType(2);//看文档
-            } else if (isDevelop(picFile) != null) {//开发
-                screenshot.setPicType(0);
-            } else if (isDesign(picFile) != null) {//设计
-                screenshot.setPicType(3);
-            }
-            screenshot.setIsHandle(1);
-            if (screenshot.getPicType() == null && isEntertainmentColorMode(picFile)) {
-                //判断是否是娱乐:看电影, 打游戏
-                String uid = screenshotvo.getUid();
-                Screenshot preShot = screenshotMapper.selectOne(new QueryWrapper<Screenshot>().eq("uid", uid).orderByDesc("indate").last("limit 1"));
-                if (preShot != null) {
-                    String prePath = path + preShot.getPicUrl().substring(preShot.getPicUrl().lastIndexOf("/"));
-                    File f = new File(prePath);
-                    if (f.exists()) {
-                        ImageCompare comp = new ImageCompare();
-                        if (comp.isMoviePlay((String) fileMap.get("newFile"), prePath)) {
-                            screenshot.setPicType(7);
-                            //前面那条也更新
-                            if (preShot.getPicType() != null && preShot.getPicType() != 7) {
-                                preShot.setPicType(7);
-                                screenshotMapper.updateById(preShot);
-                            }
-                        }
-                    }
-                }
-            }
-            if (screenshot.getPicType() == null) {
-                try {
-                    String browserName = isBrowser(picFile);
-                    if (browserName != null) {
-                        screenshot.setPicType(1);
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-
-        //将获取到的截图进行时间计算
-        calculateTime(screenshot);
-        screenshotMapper.insert(screenshot);
-        return new HttpRespMsg();
-    }
-
-    @Override
-    public HttpRespMsg reTestPicMatch(int id) {
-        Screenshot item = screenshotMapper.selectById(id);
-        String fileName = item.getPicUrl().replaceAll("/upload/", "");
-        String filePath = path + fileName;
-        File pic = new File(filePath);
-        String imName = isIM(pic);
-        HttpRespMsg msg = new HttpRespMsg();
-        if (imName != null) {
-            msg.data = imName;
-        } else {
-            String devName = isDevelop(pic);
-            if (devName != null) {
-                msg.data = devName;
-            } else {
-                try {
-                    String browserName = isBrowser(pic);
-                    if (browserName != null) {
-                        msg.data = browserName;
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-        return msg;
-    }
-
-    @Override
-    public HttpRespMsg updateRedisPicContentKeywords() {
-        List<PicContentKeywords> picContentKeywords = picContentKeywordsMapper.selectList(null);
-        for (PicContentKeywords keyWord : picContentKeywords) {
-            redisUtil.sSetJsonString("keyWords", keyWord);
-        }
-        HttpRespMsg msg = new HttpRespMsg();
-        msg.data = redisUtil.members("keyWords");
-        return msg;
-    }
-
-    //判断文字内容是否是小说
-    private boolean isNovel(List<String> textContents) {
-        /**先粗糙地比较一下, 小说常规包含的词库,匹配频率高,则认为是小说。
-         * 第一步, 90%应该都是中文
-         */
-        int total = 0;
-        int chWNum = 0;
-        for (String w : textContents) {
-            char[] ch = w.toCharArray();
-            for (char c : ch) {
-                total++;
-                if (c >= 0x4E00 && c <= 0x9FBF) {
-                    chWNum++;
-                }
-            }
-        }
-        //小说一页中文字至少200个
-        if (chWNum < 200) {
-            return false;
-        }
-        int percent = chWNum * 100 / total;
-        log.info("中文比例:" + percent);
-        if (percent < 60) {
-            //英文太多,不是小说; 不考虑英文小说。
-            return false;
-        }
-
-        //第二步,匹配小说常见词汇,超过5次,认为是小说
-        try {
-            //填充小说关键字到内存,减少重复读取
-            if (nKeyWordsList.size() == 0) {
-                InputStream ins = novelWords.getInputStream();
-                BufferedReader br = new BufferedReader(new InputStreamReader(ins));
-                String line = br.readLine();
-                while (line != null) {
-                    nKeyWordsList.add(line);
-                    line = br.readLine();
-                    System.out.println(line);
-                }
-            }
-            int totalKNum = 0;
-            for (String k : textContents) {
-                int kNum = 0;
-                for (String nk : nKeyWordsList) {
-                    if (k.contains(nk)) {
-                        kNum++;
-                    }
-                }
-                totalKNum += kNum;
-                //存在第几章这样的关键字, +1分
-                if (matchCategory(k)) {
-                    totalKNum += 1;
-                }
-            }
-            log.info("文章小说匹配得分为==" + totalKNum);
-            if (totalKNum >= 5) {
-                return true;
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return false;
-    }
-
-    public static boolean matchCategory(String str) {
-        String pattern = "^第(.*)章(.*)";
-        // 创建 Pattern 对象
-        return Pattern.matches(pattern, str.trim());
-    }
-
-    public static void main(String[] args) throws Exception {
-//        String b = isDesign(new File("C:\\Users\\seya\\Desktop\\mock.jpg"));
-//        System.out.println("结果:"+b);
-    }
-
-
-    private static boolean isPureColor(BufferedImage img, int colorPixel) {
-        int with = img.getWidth();
-        int height = img.getHeight();
-        boolean hasDifferent = false;
-        for (int i = 0; i < with; i++) {
-            for (int y = 0; y < height; y++) {
-                int pixel = img.getRGB(i, y); // 下面三行代码将一个数字转换为RGB数字
-                if (pixel != colorPixel) {
-                    hasDifferent = true;
-                    break;
-                }
-            }
-            if (hasDifferent) {
-                break;
-            }
-        }
-        return !hasDifferent;
-    }
-
-    /**
-     * 是否全是汉字<br>
-     * 根据汉字编码范围进行判断<br>
-     * CJK统一汉字(不包含中文的,。《》()“‘'”、!¥等符号)<br>
-     *
-     * @param str
-     * @return
-     */
-    public static boolean isChineseByReg(String str) {
-        if (str == null) {
-            return false;
-        }
-        Pattern pattern = Pattern.compile("[\\u4E00-\\u9FBF]+");
-        return pattern.matcher(str).matches();
-    }
-
-    //判断是否是浏览器
-    private String isBrowser(File pic) throws Exception {
-//        System.out.println("picrecongnizeFolder=="+browserFolder);
-        File folder = new File(browserFolder);
-//        File folder = new File("C:/picrecongnize/browser/");
-        if (!folder.exists()) {
-            throw new Exception("没有设置图片上传的浏览器比对模板库");
-        } else {
-            File[] files = folder.listFiles();
-            String browserName = null;
-            for (File subFolder : files) {
-                File[] targetFile = subFolder.listFiles();
-                boolean isMatch = false;
-                for (File targetPic : targetFile) {
-                    boolean matchPic = ImageReconizeUtil.isTemplateMatch(pic.getAbsolutePath(), targetPic.getAbsolutePath());
-                    if (matchPic) {
-                        isMatch = true;
-                        break;
-                    }
-                }
-                if (isMatch) {
-                    browserName = subFolder.getName();
-                    break;
-                }
-            }
-            return browserName;
-        }
-    }
-
-    //判断是否是开发
-    private String isDevelop(File pic) {
-        File folder = new File(developFolder);
-//        File folder = new File("C:\\picrecongnize\\develop\\");
-        if (!folder.exists()) {
-            try {
-                throw new Exception("没有设置图片上传的开发工具比对模板库");
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        } else {
-            File[] files = folder.listFiles();
-            String toolName = null;
-            boolean isMatch = false;
-            for (File targetPic : files) {
-//                System.out.println("targetPic==" + targetPic.getAbsolutePath());
-                boolean matchPic = ImageReconizeUtil.isTemplateMatch(pic.getAbsolutePath(), targetPic.getAbsolutePath());
-                if (matchPic) {
-                    toolName = targetPic.getName();
-                    break;
-                }
-            }
-            return toolName;
-        }
-        return null;
-    }
-
-    private String isDesign(File pic) {
-        File folder = new File(designFolder);
-//        File folder = new File("C:\\picrecongnize\\design\\");
-        if (!folder.exists()) {
-            try {
-                throw new Exception("没有设置图片上传的设计工具比对模板库");
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        } else {
-            File[] files = folder.listFiles();
-            String toolName = null;
-            boolean isMatch = false;
-            for (File targetPic : files) {
-//                System.out.println("targetPic==" + targetPic.getAbsolutePath());
-                boolean matchPic = ImageReconizeUtil.isTemplateMatch(pic.getAbsolutePath(), targetPic.getAbsolutePath());
-                if (matchPic) {
-                    toolName = targetPic.getName();
-                    break;
-                }
-            }
-            return toolName;
-        }
-        return null;
-    }
-
-    //判断是否是聊天
-    private String isIM(File pic) {
-        File folder = new File(imFolder);
-//        File folder = new File("C:\\picrecongnize\\im\\");
-        if (!folder.exists()) {
-            try {
-                throw new Exception("没有设置图片上传的聊天比对模板库");
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        } else {
-            File[] files = folder.listFiles();
-            String toolName = null;
-            boolean isMatch = false;
-            for (File targetPic : files) {
-//                System.out.println("targetPic==" + targetPic.getAbsolutePath());
-                boolean matchPic = ImageReconizeUtil.isWholeTemplateMatch(pic.getAbsolutePath(), targetPic.getAbsolutePath());
-                if (matchPic) {
-                    toolName = targetPic.getName();
-                    break;
-                }
-            }
-            return toolName;
-        }
-        return null;
-    }
-
-    /**
-     * 判断是否是看文档, 具体类型为word, excel, pdf, ppt
-     *
-     * @param textContents
-     * @return
-     */
-    public static boolean isDocument(List<String> textContents) {
-        boolean find = false;
-        for (int i = 0; i < textContents.size() && i <= 2; i++) {//出现在前三行
-            String text = textContents.get(i).trim();
-            if (text.contains("Word")
-                    || text.contains("Excel")
-                    || text.contains("Ecel")
-                    || text.contains("Power Point")
-                    || text.contains("Adobe Reader")) {
-                find = true;
-                break;
-            }
-        }
-        return find;
-    }
-
-    //娱乐类: 电影+游戏; 画面比较丰富的
-    public static boolean isEntertainmentColorMode(File pic) {
-        try {
-            int[] rgb = new int[3];
-            if (!pic.exists()) {
-                System.err.println("文件不存在" + pic.getAbsolutePath());
-            } else {
-                System.out.println("找到文件" + pic.getAbsolutePath());
-            }
-            BufferedImage img = ImageIO.read(pic);
-            int width = img.getWidth();
-            int height = img.getHeight();
-            int minx = img.getMinX();
-            int miny = img.getMinY();
-//            System.out.println("width=" + width + ",height=" + height + ".");
-//            System.out.println("minx=" + minx + ",miniy=" + miny + ".");
-            //统计出现最多的一个色值,计算所占比重
-            int totalPixl = 0;
-            HashMap<Integer, Integer> colorCntMap = new HashMap<Integer, Integer>();
-            for (int i = minx; i < width; i++) {
-                for (int j = miny; j < height; j++) {
-                    totalPixl++;
-                    int pixel = img.getRGB(i, j); // 下面三行代码将一个数字转换为RGB数字
-                    if (colorCntMap.get(pixel) == null) {
-                        colorCntMap.put(pixel, 1);
-                    } else {
-                        colorCntMap.put(pixel, colorCntMap.get(pixel) + 1);
-                    }
-                }
-            }
-
-            Map<Integer, Integer> sMap = new TreeMap<Integer, Integer>();
-            int maxCnt = 0;
-            int key = 0;
-            Set<Map.Entry<Integer, Integer>> entry2 = colorCntMap.entrySet();
-            for (Map.Entry<Integer, Integer> temp : entry2) {
-//                System.out.println("sortedMap:"+temp.getKey()+" 值"+temp.getValue());
-                if (temp.getValue() > maxCnt) {
-                    maxCnt = temp.getValue();
-                    key = temp.getKey();
-                }
-                sMap.put(temp.getValue(), temp.getKey());
-            }
-            sMap = ((TreeMap) sMap).descendingMap();
-            Iterator it = sMap.keySet().iterator();
-            Integer k1 = (Integer) it.next();
-            Integer k2 = (Integer) it.next();
-            Integer color1 = sMap.get(k1);
-            Integer color2 = sMap.get(k2);
-//            System.out.println("kkkk==" + k1 + "," + color1 + "," + k2 + "," + color2);
-//            System.out.println("最.." + maxCnt + ", key=" + key);
-            rgb[0] = (key & 0xff0000) >> 16;
-            rgb[1] = (key & 0xff00) >> 8;
-            rgb[2] = (key & 0xff);
-//            System.out.println("色值为: " + rgb[0] + ", " + rgb[1] + ", " + rgb[2]);
-            //计算比例, 应该不低于50%
-            int colorPercent = maxCnt * 100 / totalPixl;
-            if (colorPercent < 50) {
-                //可能存在2中底色, 大布局的底色和小模块的底色,都算底色。
-                int secPercent = k2 * 100 / totalPixl;
-                rgb[0] = (color2 & 0xff0000) >> 16;
-                rgb[1] = (color2 & 0xff00) >> 8;
-                rgb[2] = (color2 & 0xff);
-//                System.out.println("二级底色色值为: " + rgb[0] + ", " + rgb[1] + ", " + rgb[2]);
-//                System.out.println("二级底色比例==" + secPercent);
-                colorPercent = (k1 + k2) * 100 / totalPixl;
-            }
-            System.out.println("总底色比例==" + colorPercent);
-            //计算底色是否是连续分布的
-            int windowSize = 50;
-            int pureColorBlockCnt = 0;
-            int totalBlockCnt = 0;
-            for (int i = minx; i < width - windowSize; i += windowSize) {
-                for (int j = miny; j < height - windowSize; j += windowSize) {
-                    totalBlockCnt++;
-                    BufferedImage rect = img.getSubimage(i, j, windowSize, windowSize);
-                    if (isPureColor(rect, key)) {
-                        pureColorBlockCnt++;
-                    }
-                }
-            }
-//            log.info("pureColorBlockCnt===" + pureColorBlockCnt);
-            int pureColorBlackPercent = pureColorBlockCnt * 100 / totalBlockCnt;
-//            log.info("pureColorBlackPercent===" + pureColorBlackPercent);
-            if (colorPercent < 50 && pureColorBlackPercent < 30) {
-                return true;
-            }
-        } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        return false;
-    }
-}

+ 148 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java

@@ -12,6 +12,11 @@ import com.management.platform.mapper.*;
 import com.management.platform.service.ReportService;
 import com.management.platform.service.UserService;
 import com.management.platform.util.*;
+import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
 import org.apache.poi.hssf.usermodel.*;
 import org.apache.poi.ss.usermodel.CellType;
 import org.apache.poi.xssf.usermodel.XSSFCell;
@@ -90,6 +95,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
     private UserSalaryMapper userSalaryMapper;
     @Resource
     private UserVcodeMapper userVcodeMapper;
+    @Resource
+    private ProjectBasecostSettingMapper projectBasecostSettingMapper;
     //登录网页端
     @Override
     public HttpRespMsg loginAdmin(String username, String password) {
@@ -348,6 +355,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
                     .setRole(1)
                     .setColor(ColorUtil.randomColor())
                     .setCompanyId(company.getId());
+            //生成项目的成本基线默认条目
+            String[] array = com.management.platform.util.Constant.DEFAULT_BASE_COST_ITEMS;
+            for (String baseItem : array) {
+                ProjectBasecostSetting setting = new ProjectBasecostSetting();
+                setting.setName(baseItem);
+                setting.setCompanyId(company.getId());
+                projectBasecostSettingMapper.insert(setting);
+            }
 
             if (userMapper.insert(user) == 0) {
                 httpRespMsg.setError("操作失败");
@@ -958,4 +973,137 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         }
         return msg;
     }
+
+    @Override
+    public HttpRespMsg pushFillReport(String ids, HttpServletRequest request, String date) {
+        List<String> strings = ListUtil.convertLongIdsArrayToList(ids);
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        List<Department> deptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", user.getCompanyId()));
+        List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", strings));
+        HttpRespMsg msg = new HttpRespMsg();
+        for (User u : userList) {
+            if (!StringUtils.isEmpty(u.getWxOpenid())) {
+                Optional<Department> first = deptList.stream().filter(d -> d.getDepartmentId().equals(u.getDepartmentId())).findFirst();
+                if (first.isPresent()) {
+                    u.setDepartmentName(first.get().getDepartmentName());
+                }
+                boolean result = push(u, date);
+                if (!result) {
+                    System.out.println("!!!!!!!!!!!==================");
+                    msg.setError("推送失败,请检查日志");
+                }
+            }
+        }
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg exportMembList(boolean isFill, String ids, HttpServletRequest request, String date) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            String userId = request.getHeader("Token");
+            User user = userMapper.selectById(userId);
+            List<String> strings = ListUtil.convertLongIdsArrayToList(ids);
+            List<Department> deptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", user.getCompanyId()));
+            List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", strings));
+            userList.forEach(u->{
+                Optional<Department> first = deptList.stream().filter(d -> d.getDepartmentId().equals(u.getDepartmentId())).findFirst();
+                if (first.isPresent()) {
+                    u.setDepartmentName(first.get().getDepartmentName());
+                }
+            });
+            //准备导出
+            HSSFWorkbook workbook = new HSSFWorkbook();
+            HSSFSheet sheet = workbook.createSheet("人员列表");
+            //创建表头
+            HSSFRow headRow = sheet.createRow(0);
+            //设置列宽 setColumnWidth的第二个参数要乘以256 这个参数的单位是1/256个字符宽度
+            sheet.setColumnWidth(0, 5 * 256);
+            sheet.setColumnWidth(1, 10 * 256);
+            sheet.setColumnWidth(2, 20 * 256);
+            //设置为居中加粗
+            HSSFCellStyle headStyle = workbook.createCellStyle();
+            HSSFFont font = workbook.createFont();
+            font.setBold(true);
+            headStyle.setFont(font);
+            //表头
+            HSSFCell headCell;
+            headCell = headRow.createCell(0);
+            headCell.setCellValue("序号");
+            headCell.setCellStyle(headStyle);
+            headCell = headRow.createCell(1);
+            headCell.setCellValue("姓名");
+            headCell.setCellStyle(headStyle);
+            headCell = headRow.createCell(2);
+            headCell.setCellValue("部门");
+            headCell.setCellStyle(headStyle);
+
+            //新增数据行 并且装填数据
+            int rowNum = 1;
+            for (User item : userList) {
+                HSSFRow row = sheet.createRow(rowNum);
+                row.createCell(0).setCellValue(rowNum);
+                row.createCell(1).setCellValue(item.getName());
+                row.createCell(2).setCellValue(item.getDepartmentName());
+                rowNum++;
+            }
+            //生成Excel文件
+            String fileUrlSuffix = date+(isFill?"已填":"未填")+"人员列表" + System.currentTimeMillis() + ".xls";
+            FileOutputStream fos = new FileOutputStream(path + fileUrlSuffix);
+            workbook.write(fos);
+            fos.flush();
+            fos.close();
+            //返回生成的文件地址/upload文件夹下
+            httpRespMsg.data = "/upload/" + fileUrlSuffix;
+        } catch (NullPointerException e) {
+            httpRespMsg.setError("验证失败或缺少数据");
+            return httpRespMsg;
+        } catch (IOException e) {
+            httpRespMsg.setError("文件生成错误");
+            return httpRespMsg;
+        }
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg getHRList(HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        int companyId = userMapper.selectById(token).getCompanyId();
+        List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).eq("role", 4));
+        msg.data = userList;
+        return msg;
+    }
+
+
+    public boolean push(User user, String date) {
+        //1,配置
+        WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
+        wxStorage.setAppId(appId);
+        wxStorage.setSecret(appSecret);
+        WxMpService wxMpService = new WxMpServiceImpl();
+        wxMpService.setWxMpConfigStorage(wxStorage);
+
+        //2,推送消息
+        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
+                .toUser(user.getWxOpenid())//要推送的用户openid
+                .templateId(TEMPLATE_REPORT_FILL)//模版id
+                .url("http://mobworktime.ttkuaiban.com/#/edit")//点击模版消息要访问的网址
+                .build();
+        //3,如果是正式版发送模版消息,这里需要配置你的信息
+        templateMessage.addData(new WxMpTemplateData("first", "您"+date+"的工时报告还未填写", "#FF00FF"));
+        templateMessage.addData(new WxMpTemplateData("keyword1", user.getName(), "#000000"));
+        templateMessage.addData(new WxMpTemplateData("keyword2", user.getDepartmentName(), "#000000"));
+        templateMessage.addData(new WxMpTemplateData("remark", "请尽快填报", "#000000"));
+        //                templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
+        try {
+            wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
+        } catch (Exception e) {
+            System.out.println("推送失败:" + e.getMessage());
+            e.printStackTrace();
+            return false;
+        }
+        return true;
+    }
 }

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

@@ -1,15 +1,11 @@
 package com.management.platform.task;
 
-import java.time.LocalDate;
-import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.constant.Constant;
 import com.management.platform.entity.*;
 import com.management.platform.mapper.*;
-import com.management.platform.service.ScreenshotService;
 import com.management.platform.util.AuthService;
 import com.management.platform.util.CheckPicUtil;
 import com.management.platform.util.RedisUtil;
@@ -20,16 +16,12 @@ import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.format.annotation.DateTimeFormat;
-import org.springframework.http.*;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.temporal.TemporalAccessor;
 import java.util.*;
 
 /**
@@ -65,39 +57,6 @@ public class TimingTask {
     @Value(value = "${upload.path}")
     private String path;
 
-    //    @Scheduled(cron = "0 */5 * * * ?")//配置时间段触发(每五分钟触发一次)
-    public void pictureDetectionTask() {
-        String accessToken = "";
-
-        if (redisUtil.existsKey("accessToken")) {
-            accessToken = redisUtil.getKey("accessToken");
-        } else {
-            Map<String, Object> map = AuthService.getAuth(Constant.API_KEY, Constant.SECRET_KEY);
-            accessToken = (String) map.get("access_token");
-            Long expiresTimeOut = (Long) map.get("expires_in");
-            redisUtil.setKeyWithExpireTime("accessToken", accessToken, expiresTimeOut);
-        }
-        //利用token去检测
-//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-//        LocalDateTime l = LocalDateTime.parse("2019-02-03",dateTimeFormatter);
-        List<Screenshot> screenshots = screenshotMapper.selectList(new QueryWrapper<Screenshot>()
-                .eq("date_str", DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()))
-                .eq("is_handle", Constant.UN_HANDLE));
-        for (Screenshot screenshot : screenshots) {
-            List<String> textContents = CheckPicUtil.generalPicTextContent(path + screenshot.getPicUrl().substring("/upload/".length()), accessToken);
-            Set<Object> members = redisUtil.members(Constant.COMMON_SOFTWARE_KEYWORDS);
-            for (String textContent : textContents) {
-                for (Object member : members) {
-                    if (textContent.contains((String) member)) {
-                        //包含关键字们可以简单认为是在用常用开发软件
-                        //to do 确定图片是哪个类型的图片
-                    }
-                }
-            }
-        }
-    }
-
-
 
     //每分钟校验是否有需要提醒的填报
     @Scheduled(fixedRate = 60 * 1000)
@@ -139,7 +98,7 @@ public class TimingTask {
                 .url("http://mobworktime.ttkuaiban.com/#/edit")//点击模版消息要访问的网址
                 .build();
         //3,如果是正式版发送模版消息,这里需要配置你的信息
-        templateMessage.addData(new WxMpTemplateData("first", "您今天的工时填报还未完成", "#FF00FF"));
+        templateMessage.addData(new WxMpTemplateData("first", "您今天的工时报告还未填写", "#FF00FF"));
         templateMessage.addData(new WxMpTemplateData("keyword1", (String)user.get("name"), "#000000"));
         templateMessage.addData(new WxMpTemplateData("keyword2", (String)user.get("departmentName"), "#000000"));
         templateMessage.addData(new WxMpTemplateData("remark", "请尽快填报", "#000000"));

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

@@ -96,7 +96,7 @@ public class CodeGenerator {
 //        dsc.setSchemaName("public");
         dsc.setDriverName("com.mysql.cj.jdbc.Driver");
         dsc.setUsername("root");
-        dsc.setPassword("Ziyu1026!@");
+        dsc.setPassword("Ziyu20141026!@");
         mpg.setDataSource(dsc);
 
         // 包配置

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/Constant.java

@@ -7,4 +7,6 @@ public class Constant {
     public static final int ROLE_SENIOR = 3;
     public static final int ROLE_HR = 4;
     public static final int ROLE_PMP = 5;
+
+    public static String[] DEFAULT_BASE_COST_ITEMS = {"人工成本","一般费用","外包费用","其他"};
 }

+ 36 - 36
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/OpenOfficeService.java

@@ -17,16 +17,16 @@ public class OpenOfficeService {
 	//32位windows系统默认安装路径
 	public static String OpenOffice_HOME_32 = "C://Program Files/OpenOffice 4/";
 	public static String OpenOffice_HOME_UNIX = "/opt/openoffice4/";
-
+	public static int PORT = 12312;
 	private static OfficeManager officeManager;
 
 	public static boolean canTransferToPdf(String suffix) {
 		if (".doc".equals(suffix) || ".docx".equals(suffix)
-		|| ".xls".equals(suffix) || ".xlsx".equals(suffix)
-		|| ".ppt".equals(suffix) || ".pptx".equals(suffix)
-		|| ".jpg".equals(suffix) || ".png".equals(suffix)
-		|| ".bmp".equals(suffix) || ".jpeg".equals(suffix)
-		|| ".txt".equals(suffix)) {
+				|| ".xls".equals(suffix) || ".xlsx".equals(suffix)
+				|| ".ppt".equals(suffix) || ".pptx".equals(suffix)
+				|| ".jpg".equals(suffix) || ".png".equals(suffix)
+				|| ".bmp".equals(suffix) || ".jpeg".equals(suffix)
+				|| ".txt".equals(suffix)) {
 			return true;
 		} else {
 			return false;
@@ -39,14 +39,14 @@ public class OpenOfficeService {
 		try {
 			log.info("===Openoffice实例启动中...");
 			DefaultOfficeManagerConfiguration config = new DefaultOfficeManagerConfiguration();
-	        String officeHome = getOfficeHome();
+			String officeHome = getOfficeHome();
 			log.info("officeHome====="+officeHome);
-	        config.setOfficeHome(officeHome);
-	        int randomPort = new Random().nextInt(1000);
-	        randomPort += 8000;
-	        config.setPortNumber(randomPort);
-	        officeManager = config.buildOfficeManager();
-	        officeManager.start();
+			config.setOfficeHome(officeHome);
+//	        int randomPort = new Random().nextInt(1000);
+//	        randomPort += 8000;
+			config.setPortNumber(PORT);
+			officeManager = config.buildOfficeManager();
+			officeManager.start();
 			log.info("Openoffice实例启动成功!");
 		} catch (Exception e) {
 			e.printStackTrace();
@@ -55,22 +55,22 @@ public class OpenOfficeService {
 	}
 
 	public static String getOfficeHome() {
-        String osName = System.getProperty("os.name");
-        if (Pattern.matches("Linux.*", osName)) {
-            return OpenOffice_HOME_UNIX;
-        } else if (Pattern.matches("Windows.*", osName)) {
-        	String arch = System.getProperty("os.arch");
-        	boolean is64bit = (System.getenv("ProgramFiles(x86)") != null);
-        	if (is64bit) {
-        		return OpenOffice_HOME_64;
-        	} else {
-        		return OpenOffice_HOME_32;
-        	}
-        } else if (Pattern.matches("Mac.*", osName)) {
-            return "/Application/OpenOffice.org.app/Contents";
-        }
-        return null;
-    }
+		String osName = System.getProperty("os.name");
+		if (Pattern.matches("Linux.*", osName)) {
+			return OpenOffice_HOME_UNIX;
+		} else if (Pattern.matches("Windows.*", osName)) {
+			String arch = System.getProperty("os.arch");
+			boolean is64bit = (System.getenv("ProgramFiles(x86)") != null);
+			if (is64bit) {
+				return OpenOffice_HOME_64;
+			} else {
+				return OpenOffice_HOME_32;
+			}
+		} else if (Pattern.matches("Mac.*", osName)) {
+			return "/Application/OpenOffice.org.app/Contents";
+		}
+		return null;
+	}
 
 	/**
 	 * 文档转换
@@ -94,13 +94,13 @@ public class OpenOfficeService {
 		if (!outputFile.getParentFile().exists()) {
 			outputFile.getParentFile().mkdirs();
 		}
-        File inputFile = new File(inputFilePath);
-        if (inputFile.exists()) {// 找不到源文件, 则返回
-            converter.convert(inputFile, outputFile);
-        } else {
-        	return -1;
-        }
-        return 0;
+		File inputFile = new File(inputFilePath);
+		if (inputFile.exists()) {// 找不到源文件, 则返回
+			converter.convert(inputFile, outputFile);
+		} else {
+			return -1;
+		}
+		return 0;
 	}
 
 	/**

+ 5 - 9
fhKeeper/formulahousekeeper/management-platform/src/main/resources/application-prod.yml

@@ -15,7 +15,7 @@ spring:
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://47.100.37.243:7644/man_hour_manager?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
     username: root
-    password: Ziyu1026!@
+    password: Ziyu20141026!@
     hikari:
       maximum-pool-size: 10
       minimum-idle: 3
@@ -48,11 +48,11 @@ spring:
 logging:
   level:
     root: info
-    org.mybatis: debug
-    java.sql: debug
+    org.mybatis: info
+    java.sql: info
     org.springframework.web: trace
     #打印sql语句
-    com.management.platform.mapper: debug
+    com.management.platform.mapper: info
   path: /log/
   file: worktime.log
 ##########
@@ -81,11 +81,7 @@ mybatis:
 #####配置图片上传路径####
 upload:
   path: /www/staticproject/timesheet/upload/
-picrecongnize:
-  browser: /www/webapps/worktime/picrecongnize/browser/
-  develop: /www/webapps/worktime/picrecongnize/develop/
-  im: /www/webapps/worktime/picrecongnize/im/
-  design: /www/webapps/worktime/picrecongnize/design/
+
 
 
 

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

@@ -16,7 +16,7 @@ spring:
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://47.100.37.243:7644/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
     username: root
-    password: Ziyu1026!@
+    password: Ziyu20141026!@
     hikari:
       maximum-pool-size: 10
       minimum-idle: 3

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/AuditWorkflowTimeSettingMapper.xml

@@ -0,0 +1,21 @@
+<?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.AuditWorkflowTimeSettingMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.AuditWorkflowTimeSetting">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="role_id" property="roleId" />
+        <result column="role_name" property="roleName" />
+        <result column="seq" property="seq" />
+        <result column="user_id" property="userId" />
+        <result column="user_name" property="userName" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, role_id, role_name, seq, user_id, user_name
+    </sql>
+
+</mapper>

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

@@ -15,11 +15,12 @@
         <result column="package_oa" property="packageOa" />
         <result column="package_etimecard" property="packageEtimecard" />
         <result column="package_expense" property="packageExpense" />
+        <result column="package_customer" property="packageCustomer" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, company_name, staff_count_max, expiration_date, set_meal, package_worktime, package_project, package_contract, package_oa, package_etimecard, package_expense
+        id, company_name, staff_count_max, expiration_date, set_meal, package_worktime, package_project, package_contract, package_oa, package_etimecard, package_expense, package_customer
     </sql>
 
 </mapper>

+ 26 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CustomerInfoMapper.xml

@@ -0,0 +1,26 @@
+<?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.CustomerInfoMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.CustomerInfo">
+        <id column="id" property="id" />
+        <result column="customer_code" property="customerCode" />
+        <result column="customer_name" property="customerName" />
+        <result column="contact_name" property="contactName" />
+        <result column="contact_phone" property="contactPhone" />
+        <result column="email" property="email" />
+        <result column="address" property="address" />
+        <result column="company_id" property="companyId" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, customer_code, customer_name, contact_name, contact_phone, email, address, company_id
+    </sql>
+    <select id="getAll" resultMap="BaseResultMap">
+        select id, customer_name from customer_info where company_id = #{companyId}
+        ORDER BY id DESC
+    </select>
+
+</mapper>

+ 5 - 9
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/EarningSnapshotMapper.xml

@@ -10,19 +10,15 @@
         <result column="creator_id" property="creatorId" />
         <result column="creator_name" property="creatorName" />
         <result column="contract_amount" property="contractAmount" />
-        <result column="base_man" property="baseMan" />
-        <result column="base_fee" property="baseFee" />
-        <result column="base_outsourcing" property="baseOutsourcing" />
-        <result column="base_risk1" property="baseRisk1" />
-        <result column="base_risk2" property="baseRisk2" />
-        <result column="profit_a" property="profitA" />
-        <result column="profit_b" property="profitB" />
-        <result column="profit_c" property="profitC" />
+        <result column="profit" property="profit" />
+        <result column="profit_percent" property="profitPercent" />
+        <result column="cost_total" property="costTotal" />
+        <result column="cost_data" property="costData" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, project_id, indate, creator_id, creator_name, contract_amount, base_man, base_fee, base_outsourcing, base_risk1, base_risk2, profit_a, profit_b, profit_c
+        id, project_id, indate, creator_id, creator_name, contract_amount, profit, profit_percent, cost_total, cost_data
     </sql>
 
 </mapper>

+ 19 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectBasecostMapper.xml

@@ -0,0 +1,19 @@
+<?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.ProjectBasecostMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ProjectBasecost">
+        <id column="id" property="id" />
+        <result column="project_id" property="projectId" />
+        <result column="base_id" property="baseId" />
+        <result column="base_name" property="baseName" />
+        <result column="base_amount" property="baseAmount" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, project_id, base_id, base_name, base_amount
+    </sql>
+
+</mapper>

+ 17 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectBasecostSettingMapper.xml

@@ -0,0 +1,17 @@
+<?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.ProjectBasecostSettingMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ProjectBasecostSetting">
+        <id column="id" property="id" />
+        <result column="name" property="name" />
+        <result column="company_id" property="companyId" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, name, company_id
+    </sql>
+
+</mapper>

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

@@ -29,11 +29,25 @@
         <result column="fee_travel" property="feeTravel" />
         <result column="fee_outsourcing" property="feeOutsourcing" />
         <result column="fee_man" property="feeMan" />
+        <result column="customer_id" property="customerId" />
+        <result column="customer_name" property="customerName" />
     </resultMap>
 
+    <resultMap id="CustomerResultMap" type="com.management.platform.entity.vo.CustomerProject" >
+        <result column="customer_id" property="customerId" />
+        <result column="customer_name" property="customerName" />
+        <result column="contract_amount" property="contractAmount" />
+        <result column="fee_normal" property="feeNormal" />
+        <result column="fee_travel" property="feeTravel" />
+        <result column="fee_outsourcing" property="feeOutsourcing" />
+        <result column="fee_man" property="feeMan" />
+        <result column="project_num" property="projectNum" />
+        <result column="project_ids" property="projectIds" />
+        <result column="project_names" property="projectNames" />
+    </resultMap>
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, project_name, company_id, project_code, incharger_id, plan_start_date, plan_end_date, progress, level, status, finish_date, creator_id, creator_name, create_date, contract_amount, budget, base_man, base_outsourcing, base_risk1, base_risk2, base_fee, fee_normal, fee_travel, fee_outsourcing, fee_man
+        id, project_name, company_id, project_code, incharger_id, plan_start_date, plan_end_date, progress, level, status, finish_date, creator_id, creator_name, create_date, contract_amount, budget, base_man, base_outsourcing, base_risk1, base_risk2, base_fee, fee_normal, fee_travel, fee_outsourcing, fee_man, customer_id, customer_name
     </sql>
 
     <!--获取查询者所在公司每个项目的工时成本-->
@@ -124,4 +138,38 @@
             LIMIT #{pageStart},#{pageSize}
         </if>
     </select>
+
+    <!--分页获取客户项目的成本利润报表 -->
+    <select id="getCustomerProjectInAndOut" resultMap="CustomerResultMap">
+        SELECT customer_id, customer_name, COUNT(1) AS project_num, GROUP_CONCAT( project.id) AS project_ids, GROUP_CONCAT( project_name) AS project_names,
+        SUM(contract_amount) AS contract_amount ,
+        SUM((SELECT IFNULL(SUM(cost),0) FROM report WHERE state = 1 AND project_id = project.id)) AS fee_man,
+        SUM((SELECT IFNULL(SUM(amount),0) FROM expense_item , expense_sheet WHERE project_id = project.id AND  expense_sheet.id = expense_item.`expense_id` AND expense_sheet.type = 0)) AS fee_normal,
+        SUM((SELECT IFNULL(SUM(amount),0) FROM expense_item , expense_sheet WHERE project_id = project.id AND  expense_sheet.id = expense_item.`expense_id` AND expense_sheet.type = 1)) AS fee_travel,
+        SUM((SELECT IFNULL(SUM(amount),0) FROM expense_item , expense_sheet WHERE project_id = project.id AND  expense_sheet.id = expense_item.`expense_id` AND expense_sheet.type = 2)) AS fee_outsourcing
+        FROM project WHERE project.`company_id` = #{companyId} AND customer_id > 0
+        AND (project.status &lt;&gt; 3 OR project.status IS NULL)
+        GROUP BY customer_id
+        <if test="pageStart != null and pageSize != null">
+            LIMIT #{pageStart},#{pageSize}
+        </if>
+    </select>
+
+    <select id="getCustomerProjectInAndOutCount" resultType="java.lang.Integer">
+        SELECT COUNT(DISTINCT customer_id) FROM project WHERE project.`company_id` = #{companyId} AND customer_id > 0
+        AND (project.status &lt;&gt; 3 OR project.status IS NULL)
+    </select>
+
+    <!--分页获取项目收支平衡 -->
+    <select id="getProjectInAndOutByRange" resultMap="CustomerResultMap">
+        SELECT project.id as id, project.id as project_ids, project_code, project_name as project_names,contract_amount,
+        (SELECT IFNULL(SUM(cost),0) FROM report WHERE state = 1 AND project_id = project.id) AS fee_man,
+        (SELECT IFNULL(SUM(amount),0) FROM expense_item , expense_sheet WHERE project_id = project.id AND  expense_sheet.id = expense_item.`expense_id` AND expense_sheet.type = 0) AS fee_normal,
+        (SELECT IFNULL(SUM(amount),0) FROM expense_item , expense_sheet WHERE project_id = project.id AND  expense_sheet.id = expense_item.`expense_id` AND expense_sheet.type = 1) AS fee_travel,
+        (SELECT IFNULL(SUM(amount),0) FROM expense_item , expense_sheet WHERE project_id = project.id AND  expense_sheet.id = expense_item.`expense_id` AND expense_sheet.type = 2) AS fee_outsourcing
+        FROM project WHERE project.`company_id` = #{companyId}
+        and id IN <foreach collection="ids" close=")" open="(" separator="," index="" item="item">
+        #{item}
+        </foreach>
+    </select>
 </mapper>

二進制
fhKeeper/formulahousekeeper/management-platform/财务人员成本模板_已填写.xlsx