瀏覽代碼

Excel简易版

seyason 3 年之前
父節點
當前提交
9e050164e4
共有 36 個文件被更改,包括 2172 次插入71 次删除
  1. 29 4
      fhKeeper/formulahousekeeper/inva_4_tivo/index.html
  2. 9 0
      fhKeeper/formulahousekeeper/management-platform/pom.xml
  3. 47 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AuthRedirectController.java
  4. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SimpleFinanceController.java
  5. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SimpleProjectimeController.java
  6. 71 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SimpleReportController.java
  7. 3 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java
  8. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Company.java
  9. 118 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SimpleFinance.java
  10. 45 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SimpleProjectime.java
  11. 105 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SimpleReport.java
  12. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/SimpleFinanceMapper.java
  13. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/SimpleProjectimeMapper.java
  14. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/SimpleReportMapper.java
  15. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/SimpleFinanceService.java
  16. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/SimpleProjectimeService.java
  17. 29 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/SimpleReportService.java
  18. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserService.java
  19. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/SimpleFinanceServiceImpl.java
  20. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/SimpleProjectimeServiceImpl.java
  21. 552 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/SimpleReportServiceImpl.java
  22. 21 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  23. 361 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/UserAgentUtils.java
  24. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  25. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CompanyMapper.xml
  26. 28 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SimpleFinanceMapper.xml
  27. 18 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SimpleProjectimeMapper.xml
  28. 24 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SimpleReportMapper.xml
  29. 二進制
      fhKeeper/formulahousekeeper/management-platform/工时统计表示例.xlsx
  30. 二進制
      fhKeeper/formulahousekeeper/management-platform/项目工时统计表.xlsx
  31. 39 27
      fhKeeper/formulahousekeeper/timesheet/src/main.js
  32. 30 21
      fhKeeper/formulahousekeeper/timesheet/src/routes.js
  33. 4 1
      fhKeeper/formulahousekeeper/timesheet/src/views/Login.vue
  34. 14 4
      fhKeeper/formulahousekeeper/timesheet/src/views/Register.vue
  35. 436 0
      fhKeeper/formulahousekeeper/timesheet/src/views/simplereport/list.vue
  36. 16 5
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

+ 29 - 4
fhKeeper/formulahousekeeper/inva_4_tivo/index.html

@@ -3,9 +3,9 @@
 <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
-    <meta name="keywords" content="工时管理,项目成本管理,工时统计,项目成本统计" />
+    <meta name="keywords" content="工时管理,项目成本管理,工时统计,项目成本统计,工时记录表,工时统计表," />
     <meta name="description" content="工时管家是专业的工时管理软件,提供专业的工时填报,审核和统计功能。引进现代工时管理和项目管理的理念,核算项目投入成本准确便捷,企业IPO利器"/>
-    <title>工时管理|工时记录|项目成本管理-工时管家是专业便捷的工时管理系统。 手机移动填报|核算项目成本|企业IPO利器!</title>
+    <title>工时管理|工时记录|项目成本管理-工时管家是专业便捷的工时管理系统。支持员工工时统计表上传汇总。 手机移动填报|核算项目成本|企业IPO利器!</title>
     <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700&display=swap&subset=latin-ext" rel="stylesheet">
     <link href="css/bootstrap.css" rel="stylesheet">
     <!-- <link href="css/fontawesome-all.css" rel="stylesheet"> -->
@@ -108,11 +108,11 @@
                     <div class="row">
                         <div class="col-lg-12 col-xl-12">
                             <div class="text-container">
-                                <p class="indx">为工时填报、审核和统计提供专业解决方案,支持PC端、微信和钉钉。基于项目/部门/人员多维度统计工时,可导出报表对接其他系统。</p>
+                                <p class="indx">为工时填报、工时统计提供专业解决方案。提供简易的<a href='http://worktime.ttkuaiban.com/upload/员工工时统计模板.xlsx' style="color:#ffcc66;">员工工时记录表Excel</a>,上传后自动分析统计;也能提供丰富完善的个性化功能,适用于智能科技,项目研发管理,广告设计和工程项目等多种领域。</p>
                                 <div class="col-lg-9 col-md-9 col-xl-9" style="margin: 0 auto;display: flex;justify-content: space-around;flex-wrap: wrap;margin-left: 27.5rem;">
                                     <div style="width: 100%;" class="ald">
                                         <!-- <a class="btn-solid-lg btn-solid-lg-white page-scroll overload">软件演示 -->
-                                        <a class="page-scroll overload allsal">软&nbsp件&nbsp演&nbsp示
+                                        <a class="page-scroll overload allsal">演&nbsp示&nbsp咨&nbsp询
                                             <div class="service2">
                                                 <p style="color: #333">微信扫码</p>
                                                 <img src="./images/code.jpg">
@@ -322,6 +322,31 @@
                 <p>PRICE PLAN</p>
             </div>
             <div class="pri">
+                <div class="li">
+                    <div class="li_con">
+                        <div>Excel简易版</div>
+                        <div>¥<span>50</span>/人/年</div>
+                    </div>
+                    <div>
+                        <ul style="padding: 0;">
+                            <li>技术支持: 7X24小时</li>
+                            <li>工时记录表下载</li>
+                            <li>工时数据上传计算</li>
+                            <li>图形化报表展示</li>
+                            <li>按项目汇总导出</li>
+                            <li>按岗位汇总导出</li>
+                            <li>按部门汇总导出</li>
+                            <li>不限项目数量</li>
+                            <li>支持PC端,企业微信端和钉钉使用</li>
+                            <li></li>
+                            <li></li>
+                            <li></li>
+                            <li></li>
+                        </ul>
+                    </div>
+                    <div class="btn"><a href="http://worktime.ttkuaiban.com/#/login"></a></div>
+                </div>
+
                 <div class="li">
                     <div class="li_con">
                         <div>基础版</div>

+ 9 - 0
fhKeeper/formulahousekeeper/management-platform/pom.xml

@@ -159,6 +159,15 @@
             <artifactId>spring-boot-configuration-processor</artifactId>
             <optional>true</optional>
         </dependency>
+
+        <!-- 获取客户端信息 -->
+        <!-- https://mvnrepository.com/artifact/eu.bitwalker/UserAgentUtils -->
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+            <version>1.21</version>
+        </dependency>
+
     </dependencies>
 
     <build>

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

@@ -11,17 +11,21 @@ import com.management.platform.mapper.CompanyMapper;
 import com.management.platform.mapper.SysConfigMapper;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.UserAgentUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.*;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.client.RestTemplate;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.view.RedirectView;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 import java.util.HashMap;
@@ -30,7 +34,8 @@ import java.util.Map;
 
 @Controller
 public class AuthRedirectController {
-
+    @Resource
+    HttpServletRequest request;
     @Value("${suitId}")
     private String suitId;
     @Value("${suitSecret}")
@@ -52,7 +57,14 @@ public class AuthRedirectController {
     @RequestMapping("/corpWXAuth")
     public ModelAndView auth(String code, int state) {
         Map<String,Object> reqParam = new HashMap<String,Object>(16);
-
+        String userAgent = request.getHeader("User-Agent");
+        //获取设备类型
+        String deviceType = UserAgentUtils.getDeviceType(userAgent);
+        if ("MOBILE".equals(deviceType)) {
+            state = 0;
+        } else {
+            state = 1;
+        }
         String url = WeiXinCorpController.GET_CORP_USERINFO_URL.replace("SUITE_ACCESS_TOKEN", getSuiteAccessToken()).replace("CODE", code);
         String forObject = this.restTemplate.getForObject(url, String.class);
         JSONObject obj = JSONObject.parseObject(forObject);
@@ -76,6 +88,39 @@ public class AuthRedirectController {
         return modelAndView;
     }
 
+    @GetMapping("testClient")
+    @ResponseBody
+    public String test(HttpServletRequest request) {
+        String userAgent = request.getHeader("user-agent");
+        System.out.println("agent: " + userAgent);
+        if (userAgent.toLowerCase().contains("micromessenger")) {
+            System.out.println("===微信平台");
+        } else if (userAgent.toLowerCase().contains("wxwork")) {
+            System.out.println("===企业微信平台");
+        }
+        System.out.println("浏览器组:" + UserAgentUtils.getBorderGroup(userAgent));
+        System.out.println("浏览器名字:" + UserAgentUtils.getBorderName(userAgent));
+        System.out.println("浏览器类型" + UserAgentUtils.getBorderType(userAgent));
+        System.out.println("浏览器生产商:" + UserAgentUtils.getBrowserManufacturer(userAgent));
+        System.out.println("浏览器版本:" + UserAgentUtils.getBrowserVersion(userAgent));
+        System.out.println("设备生产厂商:" + UserAgentUtils.getDeviceManufacturer(userAgent));
+        System.out.println("设备类型:" + UserAgentUtils.getDeviceType(userAgent));
+        System.out.println("设备操作系统:" + UserAgentUtils.getOs(userAgent));
+        System.out.println("操作系统的名字:" + UserAgentUtils.getOsName(userAgent));
+        System.out.println("操作系统的版本号:" + UserAgentUtils.getOsVersion(userAgent));
+        System.out.println("操作系统浏览器的渲染引擎:" + UserAgentUtils.getBorderRenderingEngine(userAgent));
+        String os = UserAgentUtils.getOs(userAgent);
+        if (os.contains("Windows")) {
+            System.out.println("是Windows");
+        } else if (os.contains("Linux")) {
+            System.out.println("是Linux");
+        } else {
+            System.out.println("无法匹配: {" + os + "}");
+        }
+
+        return "Success";
+    }
+
     //获取第三方应用临时凭证
     private String getSuiteAccessToken() {
         if (WeiXinCorpController.SUITE_ACCESS_TOKEN == null || WeiXinCorpController.suiteTokenExpireTime < System.currentTimeMillis()) {

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

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-10-22
+ */
+@RestController
+@RequestMapping("/simple-finance")
+public class SimpleFinanceController {
+
+}
+

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

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-10-22
+ */
+@RestController
+@RequestMapping("/simple-projectime")
+public class SimpleProjectimeController {
+
+}
+

+ 71 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SimpleReportController.java

@@ -0,0 +1,71 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.SimpleReport;
+import com.management.platform.service.FinanceService;
+import com.management.platform.service.SimpleReportService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-10-22
+ */
+@RestController
+@RequestMapping("/simple-report")
+public class SimpleReportController {
+
+    @Resource
+    HttpServletRequest request;
+
+    @Resource
+    private SimpleReportService simpleReportService;
+
+    @RequestMapping("/getByMonth")
+    public HttpRespMsg getByMonth(Integer companyId, String yearMonth) {
+        return simpleReportService.getByMonth(companyId, yearMonth);
+    }
+
+    @RequestMapping("/getReportByMonth")
+    public HttpRespMsg getReportByMonth(Integer companyId, String yearMonth) {
+        return simpleReportService.getReportByMonth(companyId, yearMonth);
+    }
+
+    @RequestMapping("/importData")
+    public HttpRespMsg importData(Integer companyId, String yearMonth,
+                                  MultipartFile file, HttpServletRequest request) {
+        return simpleReportService.importData(companyId, yearMonth, file, request);
+    }
+
+    @RequestMapping("/exportData")
+    public HttpRespMsg exportData(String yearMonth, Integer companyId, String type, HttpServletRequest request) {
+        return simpleReportService.exportData(yearMonth, companyId, type, request);
+    }
+
+    //按照项目分配财务成本
+    @RequestMapping("/getTimeCost")
+    public HttpRespMsg getTimeCost(String yearMonth, Integer companyId, String type, HttpServletRequest request) {
+        return simpleReportService.getTimeCost(yearMonth, companyId, type, request);
+    }
+
+    public static void main(String[] args) {
+        LocalDate now = LocalDate.now();
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/M/d");
+        now = LocalDate.parse("2021/1/02",dateTimeFormatter);
+        System.out.println(dateTimeFormatter.format(now));
+    }
+}
+

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

@@ -112,12 +112,13 @@ public class UserController {
      * companyName 公司名
      * name 姓名
      * phone 电话号码
+     * type: 0-简易版,1-基础版,2-项目管理专业版,3-工程管理专业版
      */
     @RequestMapping("/insertCompany")
     public HttpRespMsg insertCompany(
             @RequestParam String companyName, @RequestParam String name, @RequestParam String phone,
-            String vcode, String password) {
-        return userService.insertCompany(companyName, name, phone, vcode, password);
+            String vcode, String password, @RequestParam(required = false, defaultValue = "2") Integer type) {
+        return userService.insertCompany(companyName, name, phone, vcode, password, type);
     }
 
     /**

+ 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-08-28
+ * @since 2021-10-22
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -103,6 +103,12 @@ public class Company extends Model<Company> {
     @TableField("package_engineering")
     private Integer packageEngineering;
 
+    /**
+     * 简单表格版本
+     */
+    @TableField("package_simple")
+    private Integer packageSimple;
+
 
     @Override
     protected Serializable pkVal() {

+ 118 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SimpleFinance.java

@@ -0,0 +1,118 @@
+package com.management.platform.entity;
+
+import java.math.BigDecimal;
+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-10-22
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SimpleFinance extends Model<SimpleFinance> {
+
+    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;
+
+    /**
+     * 工资
+     */
+    @TableField("month_cost")
+    private BigDecimal monthCost;
+
+    /**
+     * 奖金
+     */
+    @TableField("bonus")
+    private BigDecimal bonus;
+
+    /**
+     * 津贴
+     */
+    @TableField("allowance")
+    private BigDecimal allowance;
+
+    /**
+     * 养老保险
+     */
+    @TableField("insurance_old")
+    private BigDecimal insuranceOld;
+
+    /**
+     * 医疗保险
+     */
+    @TableField("insurance_medical")
+    private BigDecimal insuranceMedical;
+
+    /**
+     * 失业保险
+     */
+    @TableField("insurance_losejob")
+    private BigDecimal insuranceLosejob;
+
+    /**
+     * 住房公积金
+     */
+    @TableField("house_fund")
+    private BigDecimal houseFund;
+
+    /**
+     * 其他
+     */
+    @TableField("others")
+    private BigDecimal others;
+
+    /**
+     * 总成本
+     */
+    @TableField("total_cost")
+    private BigDecimal totalCost;
+
+    /**
+     * 年月
+     */
+    @TableField("ymonth")
+    private String ymonth;
+
+    /**
+     * 该月的时薪
+     */
+    @TableField("hour_cost")
+    private BigDecimal hourCost;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 45 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SimpleProjectime.java

@@ -0,0 +1,45 @@
+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-10-22
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SimpleProjectime extends Model<SimpleProjectime> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @TableField("simple_id")
+    private Integer simpleId;
+
+    @TableField("project_name")
+    private String projectName;
+
+    @TableField("time_cost")
+    private Double timeCost;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 105 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SimpleReport.java

@@ -0,0 +1,105 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import java.time.LocalDate;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-10-22
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SimpleReport extends Model<SimpleReport> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 公司id
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 年月
+     */
+    @TableField("ymonth")
+    private String ymonth;
+
+    /**
+     * 日期
+     */
+    @TableField("report_date")
+    @JsonFormat(pattern = "MM/dd")
+    @DateTimeFormat(pattern = "MM/dd")
+    private LocalDate reportDate;
+
+    /**
+     * 姓名
+     */
+    @TableField("username")
+    private String username;
+
+    /**
+     * 工作岗位
+     */
+    @TableField("position")
+    private String position;
+
+    /**
+     * 部门
+     */
+    @TableField("department")
+    private String department;
+
+    /**
+     * 该日累计时长
+     */
+    @TableField("time_cost")
+    private Double timeCost;
+
+    /**
+     * 创建时间
+     */
+    @TableField("indate")
+    private LocalDateTime indate;
+
+    /**
+     * 上传人id
+     */
+    @TableField("creator_id")
+    private String creatorId;
+
+
+    /**
+     * 报告相关的项目时间表
+     */
+    @TableField(exist = false)
+    private List<SimpleProjectime> projectimeList;
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

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

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

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

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

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

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

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

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

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

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

+ 29 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/SimpleReportService.java

@@ -0,0 +1,29 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.SimpleReport;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-10-22
+ */
+public interface SimpleReportService extends IService<SimpleReport> {
+
+    HttpRespMsg getByMonth(Integer companyId, String yearMonth);
+
+    HttpRespMsg importData(Integer companyId, String yearMonth, MultipartFile file, HttpServletRequest request);
+
+    HttpRespMsg exportData(String yearMonth, Integer companyId, String type, HttpServletRequest request);
+
+    HttpRespMsg getTimeCost(String yearMonth, Integer companyId, String type, HttpServletRequest request);
+
+    HttpRespMsg getReportByMonth(Integer companyId, String yearMonth);
+}

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

@@ -28,7 +28,7 @@ public interface UserService extends IService<User> {
 
     HttpRespMsg editPassword(String originPassword, String newPassword, HttpServletRequest request);
 
-    HttpRespMsg insertCompany(String companyName, String name, String phone, String vcode, String pwd);
+    HttpRespMsg insertCompany(String companyName, String name, String phone, String vcode, String pwd, Integer type);
 
     HttpRespMsg insertUser(String id, String name, String phone, Integer role, Double monthCost, Double cost, Integer departmentId,
                            Integer salaryType, String costApplyDate,

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.SimpleFinance;
+import com.management.platform.mapper.SimpleFinanceMapper;
+import com.management.platform.service.SimpleFinanceService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-10-22
+ */
+@Service
+public class SimpleFinanceServiceImpl extends ServiceImpl<SimpleFinanceMapper, SimpleFinance> implements SimpleFinanceService {
+
+}

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.SimpleProjectime;
+import com.management.platform.mapper.SimpleProjectimeMapper;
+import com.management.platform.service.SimpleProjectimeService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-10-22
+ */
+@Service
+public class SimpleProjectimeServiceImpl extends ServiceImpl<SimpleProjectimeMapper, SimpleProjectime> implements SimpleProjectimeService {
+
+}

+ 552 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/SimpleReportServiceImpl.java

@@ -0,0 +1,552 @@
+package com.management.platform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.SimpleFinanceMapper;
+import com.management.platform.mapper.SimpleProjectimeMapper;
+import com.management.platform.mapper.SimpleReportMapper;
+import com.management.platform.service.SimpleFinanceService;
+import com.management.platform.service.SimpleProjectimeService;
+import com.management.platform.service.SimpleReportService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.util.ExcelUtil;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.UserNotFoundException;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.io.*;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-10-22
+ */
+@Service
+@Transactional
+public class SimpleReportServiceImpl extends ServiceImpl<SimpleReportMapper, SimpleReport> implements SimpleReportService {
+    Logger logger = LogManager.getLogger(org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME);
+    @Resource
+    SimpleFinanceService simpleFinanceService;
+    @Resource
+    SimpleFinanceMapper simpleFinanceMapper;
+    @Resource
+    SimpleReportMapper simpleReportMapper;
+    @Resource
+    SimpleReportService simpleReportService;
+    @Resource
+    SimpleProjectimeMapper simpleProjectimeMapper;
+    @Resource
+    SimpleProjectimeService simpleProjectimeService;
+    @Value(value = "${upload.path}")
+    private String path;
+
+    @Override
+    public HttpRespMsg getByMonth(Integer companyId, String yearMonth) {
+        HttpRespMsg msg = new HttpRespMsg();
+        List<SimpleFinance> financeList = simpleFinanceMapper.selectList(new QueryWrapper<SimpleFinance>().eq("company_id", companyId).eq("ymonth", yearMonth));
+        msg.data = financeList;
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg importData(Integer companyId, String yearMonth, MultipartFile multipartFile, HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        //然后处理文件
+        String fileName = multipartFile.getOriginalFilename();
+        File file = new File(fileName == null ? "file" : fileName);
+        InputStream inputStream = null;
+        OutputStream outputStream = null;
+        try {
+            inputStream = multipartFile.getInputStream();
+            outputStream = new FileOutputStream(file);
+            byte[] buffer = new byte[4096];
+            int temp = 0;
+            while ((temp = inputStream.read(buffer, 0, 4096)) != -1) {
+                outputStream.write(buffer, 0, temp);
+            }
+            inputStream.close();
+            outputStream.close();
+            //然后解析表格
+            XSSFWorkbook workbook = new XSSFWorkbook(file);
+
+            //第二个表是员工薪资表
+
+            if (workbook.getNumberOfSheets() < 2) {
+                msg.setError("表格格式不正确,需要月度工时和月薪薪资两个sheet="+workbook.getNumberOfSheets());
+            } else {
+                //导入员工薪资表
+                XSSFSheet sheet = workbook.getSheetAt(1);
+                List<SimpleFinance> financeList = new ArrayList<SimpleFinance>();
+
+                //获取月成本列表
+                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+                String dateStr = yearMonth+"-01 00:00:00";
+                LocalDateTime startDate = LocalDateTime.parse(dateStr,df);
+                LocalDateTime endDate = LocalDateTime.parse(dateStr,df);
+                endDate = endDate.plusMonths(1);
+
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/M/d");
+
+                //需要更新成本的人员数据
+                List<User> updateUserList = new ArrayList<>();
+                LocalDate now = LocalDate.now();
+                String startStr = yearMonth + "-01";
+                String endStr = yearMonth + "-31";
+                //获取人员该月份填写的日报的总时长
+                List<Map<String, Object>> userTimeList = null;
+
+                //由于第一行需要指明列对应的标题
+                int rowNum = sheet.getLastRowNum();
+                for (int rowIndex = 0; rowIndex <= rowNum; rowIndex++) {
+
+                    XSSFRow row = sheet.getRow(rowIndex);
+                    if (row == null) {
+                        continue;
+                    }
+                    if (ExcelUtil.isRowEmpty(row)) {
+                        continue;
+                    }
+                    //姓名	工资	奖金	津贴	养老保险	医疗保险	失业保险	住房公积金	其他
+                    XSSFCell nameCell = row.getCell(0);
+                    XSSFCell salaryCell = row.getCell(1);
+                    XSSFCell bonusCell = row.getCell(2);
+                    XSSFCell allowanceCell = row.getCell(3);
+                    XSSFCell inOldCell = row.getCell(4);
+                    XSSFCell inMedicalCell = row.getCell(5);
+                    XSSFCell inJobCell = row.getCell(6);
+                    XSSFCell houseFundCell = row.getCell(7);
+                    XSSFCell otherCell = row.getCell(8);
+
+
+                    nameCell.setCellType(CellType.STRING);
+                    salaryCell.setCellType(CellType.STRING);
+                    bonusCell.setCellType(CellType.STRING);
+                    allowanceCell.setCellType(CellType.STRING);
+                    inOldCell.setCellType(CellType.STRING);
+                    inMedicalCell.setCellType(CellType.STRING);
+                    inJobCell.setCellType(CellType.STRING);
+                    houseFundCell.setCellType(CellType.STRING);
+                    if (otherCell != null)otherCell.setCellType(CellType.STRING);
+
+                    String name = nameCell.getStringCellValue().trim().replaceAll("\\u00a0", "");
+                    SimpleFinance finance = new SimpleFinance();
+                    if (name.equals("姓名") && rowIndex == 0) {
+                        //跳过第一行标题
+                        continue;
+                    }
+                    finance.setCompanyId(companyId);
+                    finance.setName(name);
+
+                    BigDecimal total = new BigDecimal(0);
+                    if (salaryCell != null) {
+                        salaryCell.setCellType(CellType.STRING);
+                        String item = salaryCell.getStringCellValue();
+                        BigDecimal value = item != null ? new BigDecimal(item.trim().replaceAll("\\u00a0", "")) : BigDecimal.valueOf(0);
+                        finance.setMonthCost(value);
+                        total = total.add(value);
+                    }
+
+                    if (bonusCell != null) {
+                        bonusCell.setCellType(CellType.STRING);
+                        String bonusString = bonusCell.getStringCellValue();
+                        BigDecimal bonus = bonusString != null ? new BigDecimal(bonusString.trim().replaceAll("\\u00a0", "")) : BigDecimal.valueOf(0);
+                        finance.setBonus(bonus);
+                        total = total.add(bonus);
+                    }
+                    if (allowanceCell != null) {
+                        allowanceCell.setCellType(CellType.STRING);
+                        String item = allowanceCell.getStringCellValue();
+                        BigDecimal value = item != null ? new BigDecimal(item.trim().replaceAll("\\u00a0", "")) : BigDecimal.valueOf(0);
+                        finance.setAllowance(value);
+                        total = total.add(value);
+                    }
+                    if (inJobCell != null) {
+                        inJobCell.setCellType(CellType.STRING);
+                        String item = inJobCell.getStringCellValue();
+                        BigDecimal value = item != null ? new BigDecimal(item.trim().replaceAll("\\u00a0", "")) : BigDecimal.valueOf(0);
+                        finance.setInsuranceLosejob(value);
+                        total = total.add(value);
+                    }
+                    if (inMedicalCell != null) {
+                        inMedicalCell.setCellType(CellType.STRING);
+                        String item = inMedicalCell.getStringCellValue();
+                        BigDecimal value = item != null ? new BigDecimal(item.trim().replaceAll("\\u00a0", "")) : BigDecimal.valueOf(0);
+                        finance.setInsuranceMedical(value);
+                        total = total.add(value);
+                    }
+                    if (inOldCell != null) {
+                        inOldCell.setCellType(CellType.STRING);
+                        String item = inOldCell.getStringCellValue();
+                        BigDecimal value = item != null ? new BigDecimal(item.trim().replaceAll("\\u00a0", "")) : BigDecimal.valueOf(0);
+                        finance.setInsuranceOld(value);
+                        total = total.add(value);
+                    }
+                    if (houseFundCell != null) {
+                        houseFundCell.setCellType(CellType.STRING);
+                        String item = houseFundCell.getStringCellValue();
+                        BigDecimal value = item != null ? new BigDecimal(item.trim().replaceAll("\\u00a0", "")) : BigDecimal.valueOf(0);
+                        finance.setHouseFund(value);
+                        total = total.add(value);
+                    }
+                    if (otherCell != null) {
+                        otherCell.setCellType(CellType.STRING);
+                        String item = otherCell.getStringCellValue();
+                        BigDecimal value = item != null ? new BigDecimal(item.trim().replaceAll("\\u00a0", "")) : BigDecimal.valueOf(0);
+                        finance.setOthers(value);
+                        total = total.add(value);
+                    }
+                    finance.setTotalCost(total);
+
+                    finance.setYmonth(yearMonth);
+                    financeList.add(finance);
+                }
+
+                //获取日报列表
+                sheet = workbook.getSheetAt(0);
+                //由于第一行需要指明列对应的标题
+                rowNum = sheet.getLastRowNum();
+                List<String> projectList = new ArrayList<>();
+                List<SimpleReport> reportList = new ArrayList<>();
+                int projectNameStartIndex = 4;
+                for (int rowIndex = 0; rowIndex <= rowNum; rowIndex++) {
+                    XSSFRow row = sheet.getRow(rowIndex);
+                    if (row == null) {
+                        continue;
+                    }
+                    if (ExcelUtil.isRowEmpty(row)) {
+                        continue;
+                    }
+                    if (rowIndex == 0) {
+                        //第一行是标题,获取项目名称
+                        int pIndex = projectNameStartIndex;
+                        while(pIndex < row.getLastCellNum() && row.getCell(pIndex).getCellTypeEnum() != CellType._NONE &&  row.getCell(pIndex).getCellTypeEnum() != CellType.BLANK) {
+                            row.getCell(pIndex).setCellType(CellType.STRING);
+                            String stringCellValue = row.getCell(pIndex).getStringCellValue();
+                            projectList.add(stringCellValue);
+                            pIndex++;
+                        }
+                    } else {
+                        //数据行
+                        for (int i=1;i<4+projectList.size(); i++) {
+                            row.getCell(i).setCellType(CellType.STRING);
+                        }
+                        String reportDate = sdf.format(row.getCell(0).getDateCellValue());
+                        String username = row.getCell(1).getStringCellValue();
+                        String position = row.getCell(2).getStringCellValue();
+                        String department = row.getCell(3).getStringCellValue();
+                        List<SimpleProjectime> timeCostList = new ArrayList<SimpleProjectime>();
+                        double totalTime = 0;
+                        for (int i=4; i < 4 + projectList.size(); i++) {
+                            String stringCellValue = row.getCell(i).getStringCellValue();
+                            double time = 0;
+                            if (!StringUtils.isEmpty(stringCellValue)) {
+                                time = Double.parseDouble(stringCellValue);
+                                totalTime += time;
+                                SimpleProjectime item = new SimpleProjectime();
+                                item.setProjectName(projectList.get(i-4));
+                                item.setTimeCost(time);
+                                timeCostList.add(item);
+                            }
+                        }
+                        SimpleReport report = new SimpleReport();
+                        report.setYmonth(yearMonth);
+                        report.setUsername(username);
+                        report.setCreatorId(token);
+                        report.setCompanyId(companyId);
+                        report.setDepartment(department);
+                        report.setPosition(position);
+                        report.setReportDate(LocalDate.parse(reportDate, DateTimeFormatter.ofPattern("yyyy/M/d")));
+                        report.setTimeCost(totalTime);
+                        //设置相关的项目时间表
+                        report.setProjectimeList(timeCostList);
+                        //添加到报告列表
+                        reportList.add(report);
+                    }
+                }
+                String[] notFoundNames = reportList.stream().filter(r->{
+                    return !financeList.stream().filter(f->f.getName().equals(r.getUsername())).findAny().isPresent();
+                }).map(SimpleReport::getUsername).collect(Collectors.toList()).toArray(new String[0]);
+                if (notFoundNames.length > 0) {
+                    msg.setError(convertNameArray(notFoundNames)+" 不存在于薪资表中,请检查后提交");
+                } else {
+                    notFoundNames = financeList.stream().filter(r->{
+                        return !reportList.stream().filter(f->f.getUsername().equals(r.getName())).findAny().isPresent();
+                    }).map(SimpleFinance::getName).collect(Collectors.toList()).toArray(new String[0]);
+                    if (notFoundNames.length > 0) {
+                        msg.setError(convertNameArray(notFoundNames)+" 不存在于工时表中,请检查后提交");
+                    } else {
+                        //每个人的总工时不能为零
+                        String[] names = reportList.stream().filter(r->r.getTimeCost() == 0).map(SimpleReport::getUsername).collect(Collectors.toList()).toArray(new String[0]);
+                        if (names.length > 0) {
+                            msg.setError(convertNameArray(names)+" 工时为零,请检查");
+                        } else {
+                            //人员检查通过,更新finance表中的时薪,方便后续计算
+                            financeList.forEach(f->{
+                                double userTotalTime = reportList.stream().filter(r->r.getUsername().equals(f.getName())).mapToDouble(SimpleReport::getTimeCost).sum();
+                                f.setHourCost(f.getTotalCost().divide(new BigDecimal(userTotalTime), 2, BigDecimal.ROUND_UP));
+                            });
+
+                            //批量插入
+                            simpleFinanceService.remove(new QueryWrapper<SimpleFinance>().eq("company_id", companyId).eq("ymonth", yearMonth));
+                            simpleFinanceService.saveBatch(financeList);
+                            //插入工时报告表,先删除旧数据
+                            QueryWrapper<SimpleReport> queryWrapper = new QueryWrapper<SimpleReport>().eq("company_id", companyId).eq("ymonth", yearMonth);
+                            simpleReportMapper.delete(queryWrapper);
+                            simpleReportService.saveBatch(reportList);
+                            //再查询出来,进行项目工时存储
+                            List<SimpleReport> queryList = simpleReportMapper.selectList(queryWrapper);
+                            System.out.println("queryList size=="+queryList.size());
+                            List<SimpleProjectime> allTimeList = new ArrayList<>();
+                            reportList.forEach(r->{
+                                Integer id = queryList.stream().filter(q -> q.getUsername().equals(r.getUsername())).findFirst().get().getId();
+                                List<SimpleProjectime> timeList = r.getProjectimeList();
+                                timeList.forEach(t->t.setSimpleId(id));
+                                allTimeList.addAll(timeList);
+                            });
+                            simpleProjectimeService.saveBatch(allTimeList);
+                        }
+                    }
+                }
+
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            msg.setError("文件处理出错");
+            return msg;
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+            msg.setError("数据格式有误或存在空数据 导入失败");
+            return msg;
+        } catch (Exception e) {
+            e.printStackTrace();
+            msg.setError("发生其他错误");
+            return msg;
+        } finally {
+            //关闭流
+            try {
+                if (outputStream != null && inputStream != null) {
+                    outputStream.close();
+                    inputStream.close();
+                    System.out.println("流已关闭");
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+//            file.deleteOnExit();//程序退出时删除临时文件
+            System.out.println(file.delete());
+        }
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg exportData(String yearMonth, Integer companyId, String type, HttpServletRequest request) {
+        HttpRespMsg timeCost = getTimeCost(yearMonth, companyId, type, request);
+        HashMap map = (HashMap)timeCost.data;
+        List<HashMap> costList = (List<HashMap>)map.get("costList");
+        List<List<String>> dataList = new ArrayList<>();
+        List<String> titleList = new ArrayList<>();
+        if ("按项目".equals(type)) {
+            titleList.add("项目");
+        } else if ("按岗位".equals(type)) {
+            titleList.add("岗位");
+        } else {
+            titleList.add("部门");
+        }
+        titleList.add("工时(h)");
+        titleList.add("成本(元)");
+        dataList.add(titleList);
+        //数据
+        double time = 0;
+        BigDecimal cost = new BigDecimal(0);
+        DecimalFormat df = new DecimalFormat("#.0");
+
+        for (HashMap item : costList) {
+            List<String> data = new ArrayList<>();
+            data.add((String)item.get("name"));
+            data.add(df.format((Double)item.get("workingTime")));
+            time += (double)item.get("workingTime");
+            BigDecimal costItem = (BigDecimal)item.get("cost");
+            costItem.setScale(2, BigDecimal.ROUND_HALF_UP);
+            data.add(costItem.toString());
+            cost = cost.add(costItem);
+            dataList.add(data);
+        }
+        //合计
+        List<String> sumRow = new ArrayList<String>();
+        sumRow.add("合计");
+
+        sumRow.add(df.format(time));
+        cost.setScale(2, BigDecimal.ROUND_HALF_UP);
+        sumRow.add(cost.toString());
+
+        dataList.add(sumRow);
+        //生成excel文件导出
+        String fileName = yearMonth+"_"+type+"报表_"+System.currentTimeMillis();
+        String resp = ExcelUtil.exportGeneralExcelByTitleAndList(fileName , dataList, path);
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg.data = resp;
+        return  httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg getTimeCost(String yearMonth, Integer companyId, String type, HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        List<SimpleReport> list = simpleReportService.list(new QueryWrapper<SimpleReport>().eq("company_id", companyId).eq("ymonth", yearMonth));
+        if (list.size() == 0) {
+            HashMap map = new HashMap();
+            map.put("costList", new ArrayList<>());
+            map.put("totalMoneyCost", 0);
+            msg.data = map;
+            return msg;
+        }
+        List<Integer> collect = list.stream().map(SimpleReport::getId).collect(Collectors.toList());
+        List<SimpleProjectime> projectimeList = simpleProjectimeMapper.selectList(new QueryWrapper<SimpleProjectime>().in("simple_id", collect));
+        List<String> projectList = projectimeList.stream().map(SimpleProjectime::getProjectName).distinct().collect(Collectors.toList());
+        for (SimpleReport simpleReport : list) {
+            simpleReport.setProjectimeList(projectimeList.stream().filter(p->p.getSimpleId().equals(simpleReport.getId())).collect(Collectors.toList()));
+        }
+        BigDecimal totalMoneyCost = new BigDecimal(0);
+        //按项目核算工时和成本
+        List<SimpleFinance> financeList = simpleFinanceMapper.selectList(new QueryWrapper<SimpleFinance>().eq("company_id", companyId).eq("ymonth", yearMonth));
+
+        int i=1;
+        List<HashMap> resultList = new ArrayList<>();
+        if ("按项目".equals(type)) {
+            //按项目分组
+            for (String name : projectList) {
+                HashMap<String, Object> item = new HashMap<>();
+                item.put("id", i);
+                item.put("name", name);
+                //工时
+                double workingTime = projectimeList.stream().filter(p->p.getProjectName().equals(name)).mapToDouble(SimpleProjectime::getTimeCost).sum();
+                item.put("workingTime", workingTime);
+                //成本
+                BigDecimal totalCost = new BigDecimal(0);
+                for (SimpleProjectime p : projectimeList) {
+                    if (p.getProjectName().equals(name)) {
+                        String username = list.stream().filter(report -> report.getId().equals(p.getSimpleId())).findFirst().get().getUsername();
+                        BigDecimal hourCost = financeList.stream().filter(f -> f.getName().equals(username)).findFirst().get().getHourCost();
+                        BigDecimal result = hourCost.multiply(new BigDecimal(p.getTimeCost()));
+                        totalCost = totalCost.add(result);
+                    }
+                }
+                item.put("cost", totalCost);
+                totalMoneyCost = totalMoneyCost.add(totalCost);
+                i++;
+                resultList.add(item);
+            }
+        } else if ("按岗位".equals(type)) {
+            //按岗位
+            List<String> posList = list.stream().map(SimpleReport::getPosition).distinct().collect(Collectors.toList());
+            for (String pos:posList) {
+                HashMap<String, Object> item = new HashMap<>();
+                item.put("id", i);
+                item.put("name", pos);
+                //工时
+                double workingTime = list.stream().filter(r->r.getPosition().equals(pos)).mapToDouble(SimpleReport::getTimeCost).sum();
+                item.put("workingTime", workingTime);
+                BigDecimal totalCost = new BigDecimal(0);
+                for (SimpleReport r : list) {
+                    if (r.getPosition().equals(pos)) {
+                        String username = r.getUsername();
+                        BigDecimal hourCost = financeList.stream().filter(f -> f.getName().equals(username)).findFirst().get().getHourCost();
+                        BigDecimal result = hourCost.multiply(new BigDecimal(r.getTimeCost()));
+                        totalCost = totalCost.add(result);
+                    }
+                }
+                item.put("cost", totalCost);
+                totalMoneyCost = totalMoneyCost.add(totalCost);
+                i++;
+                resultList.add(item);
+            }
+        } else {
+            //按部门
+            //按岗位
+            List<String> deptList = list.stream().map(SimpleReport::getDepartment).distinct().collect(Collectors.toList());
+            for (String dept:deptList) {
+                HashMap<String, Object> item = new HashMap<>();
+                item.put("id", i);
+                item.put("name", dept);
+                //工时
+                double workingTime = list.stream().filter(r->r.getDepartment().equals(dept)).mapToDouble(SimpleReport::getTimeCost).sum();
+                item.put("workingTime", workingTime);
+                BigDecimal totalCost = new BigDecimal(0);
+                for (SimpleReport r : list) {
+                    if (r.getDepartment().equals(dept)) {
+                        String username = r.getUsername();
+                        BigDecimal hourCost = financeList.stream().filter(f -> f.getName().equals(username)).findFirst().get().getHourCost();
+                        BigDecimal result = hourCost.multiply(new BigDecimal(r.getTimeCost()));
+                        totalCost = totalCost.add(result);
+                    }
+                }
+                item.put("cost", totalCost);
+                totalMoneyCost = totalMoneyCost.add(totalCost);
+                i++;
+                resultList.add(item);
+            }
+        }
+
+        HashMap map = new HashMap();
+        map.put("costList", resultList);
+        map.put("totalMoneyCost", totalMoneyCost);
+        msg.data = map;
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg getReportByMonth(Integer companyId, String yearMonth) {
+        List<SimpleReport> list = simpleReportService.list(new QueryWrapper<SimpleReport>().eq("company_id", companyId).eq("ymonth", yearMonth));
+        List<String> projectList = new ArrayList<>();
+        if (list.size() > 0) {
+            List<Integer> collect = list.stream().map(SimpleReport::getId).collect(Collectors.toList());
+            List<SimpleProjectime> projectimeList = simpleProjectimeMapper.selectList(new QueryWrapper<SimpleProjectime>().in("simple_id", collect));
+            projectList = projectimeList.stream().map(SimpleProjectime::getProjectName).distinct().collect(Collectors.toList());
+            for (SimpleReport simpleReport : list) {
+                simpleReport.setProjectimeList(projectimeList.stream().filter(p->p.getSimpleId().equals(simpleReport.getId())).collect(Collectors.toList()));
+            }
+        }
+
+        HashMap map = new HashMap();
+        map.put("records", list);
+        map.put("projectList", projectList);
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = map;
+        return msg;
+    }
+
+    String convertNameArray(String[] data) {
+        String s = "";
+        for (int i=0;i<data.length; i++) {
+            s += data[i];
+            if (i < data.length-1) {
+                s += ",";
+            }
+        }
+        return s;
+    }
+}

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

@@ -317,7 +317,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 
     //新增公司和负责人
     @Override
-    public HttpRespMsg insertCompany(String companyName, String name, String phone, String vcode, String password) {
+    public HttpRespMsg insertCompany(String companyName, String name, String phone, String vcode, String password, Integer type) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         //检查验证码是否正确
         LocalDateTime now = LocalDateTime.now();
@@ -335,6 +335,26 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
             //首先生成一个新公司,增加会员的试用一个月
             Company company = new Company().setCompanyName(companyName)
                     .setExpirationDate(LocalDateTime.now().plusMonths(1));
+            //设置版本
+            if (type == 0) {
+                company.setPackageSimple(1);
+            } else if (type == 1) {
+                company.setPackageSimple(0);
+                company.setPackageProject(0);
+                company.setPackageExpense(0);
+                company.setPackageCustomer(0);
+            } else if (type == 2) {
+                company.setPackageSimple(0);
+                company.setPackageProject(1);
+                company.setPackageExpense(1);
+                company.setPackageCustomer(1);
+            } else {
+                company.setPackageSimple(0);
+                company.setPackageProject(1);
+                company.setPackageExpense(1);
+                company.setPackageCustomer(1);
+                company.setPackageEngineering(1);
+            }
             companyMapper.insert(company);
             //生成工作时长
             TimeType timeType = new TimeType();

+ 361 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/UserAgentUtils.java

@@ -0,0 +1,361 @@
+package com.management.platform.util;
+import eu.bitwalker.useragentutils.Browser;
+import eu.bitwalker.useragentutils.OperatingSystem;
+import eu.bitwalker.useragentutils.UserAgent;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+
+/*
+ * 工具类参照文章:https://blog.csdn.net/qq_23832313/article/details/82775316
+ *
+ * @author Tellsea
+ * @date 2020/10/27
+ */
+public class UserAgentUtils {
+
+    private static Logger logger = LoggerFactory.getLogger(UserAgentUtils.class);
+
+    /**
+     * 根据http获取userAgent信息
+     *
+     * @param request
+     * @return
+     */
+    public static String getUserAgent(HttpServletRequest request) {
+        String userAgent = request.getHeader("User-Agent");
+        return userAgent;
+    }
+
+    /**
+     * 根据request获取userAgent,然后解析出osVersion
+     *
+     * @param request
+     * @return
+     */
+    public static String getOsVersion(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getOsVersion(userAgent);
+    }
+
+    /**
+     * 根据userAgent解析出osVersion
+     *
+     * @param userAgent
+     * @return
+     */
+    public static String getOsVersion(String userAgent) {
+        String osVersion = "";
+        if (StringUtils.isBlank(userAgent)) {
+            return osVersion;
+        }
+        String[] strArr = userAgent.substring(userAgent.indexOf("(") + 1,
+                userAgent.indexOf(")")).split(";");
+        if (null == strArr || strArr.length == 0) {
+            return osVersion;
+        }
+
+        osVersion = strArr[1];
+        logger.info("osVersion is:{}", osVersion);
+        return osVersion;
+    }
+
+    /**
+     * 获取操作系统对象
+     *
+     * @param userAgent
+     * @return
+     */
+    private static OperatingSystem getOperatingSystem(String userAgent) {
+        UserAgent agent = UserAgent.parseUserAgentString(userAgent);
+        OperatingSystem operatingSystem = agent.getOperatingSystem();
+        return operatingSystem;
+    }
+
+
+    /**
+     * 获取os:Windows/ios/Android
+     *
+     * @param request
+     * @return
+     */
+    public static String getOs(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getOs(userAgent);
+    }
+
+    /**
+     * 获取os:Windows/ios/Android
+     *
+     * @param userAgent
+     * @return
+     */
+    public static String getOs(String userAgent) {
+        OperatingSystem operatingSystem = getOperatingSystem(userAgent);
+        String os = operatingSystem.getGroup().getName();
+        logger.info("os is:{}", os);
+        return os;
+    }
+
+
+    /**
+     * 获取deviceType
+     *
+     * @param request
+     * @return
+     */
+    public static String getDeviceType(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getDeviceType(userAgent);
+    }
+
+    /**
+     * 获取deviceType
+     *
+     * @param userAgent
+     * @return
+     */
+    public static String getDeviceType(String userAgent) {
+        OperatingSystem operatingSystem = getOperatingSystem(userAgent);
+        String deviceType = operatingSystem.getDeviceType().toString();
+        logger.info("deviceType is:{}", deviceType);
+        return deviceType;
+    }
+
+    /**
+     * 获取操作系统的名字
+     *
+     * @param request
+     * @return
+     */
+    public static String getOsName(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getOsName(userAgent);
+    }
+
+    /**
+     * 获取操作系统的名字
+     *
+     * @param userAgent
+     * @return
+     */
+    public static String getOsName(String userAgent) {
+        OperatingSystem operatingSystem = getOperatingSystem(userAgent);
+        String osName = operatingSystem.getName();
+        logger.info("osName is:{}", osName);
+        return osName;
+    }
+
+
+    /**
+     * 获取device的生产厂家
+     *
+     * @param request
+     */
+    public static String getDeviceManufacturer(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getDeviceManufacturer(userAgent);
+    }
+
+    /**
+     * 获取device的生产厂家
+     *
+     * @param userAgent
+     */
+    public static String getDeviceManufacturer(String userAgent) {
+        OperatingSystem operatingSystem = getOperatingSystem(userAgent);
+        String deviceManufacturer = operatingSystem.getManufacturer().toString();
+        logger.info("deviceManufacturer is:{}", deviceManufacturer);
+        return deviceManufacturer;
+    }
+
+    /**
+     * 获取浏览器对象
+     *
+     * @param agent
+     * @return
+     */
+    public static Browser getBrowser(String agent) {
+        UserAgent userAgent = UserAgent.parseUserAgentString(agent);
+        Browser browser = userAgent.getBrowser();
+        return browser;
+    }
+
+
+    /**
+     * 获取browser name
+     *
+     * @param request
+     * @return
+     */
+    public static String getBorderName(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getBorderName(userAgent);
+    }
+
+    /**
+     * 获取browser name
+     *
+     * @param userAgent
+     * @return
+     */
+    public static String getBorderName(String userAgent) {
+        Browser browser = getBrowser(userAgent);
+        String borderName = browser.getName();
+        logger.info("borderName is:{}", borderName);
+        return borderName;
+    }
+
+
+    /**
+     * 获取浏览器的类型
+     *
+     * @param request
+     * @return
+     */
+    public static String getBorderType(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getBorderType(userAgent);
+    }
+
+    /**
+     * 获取浏览器的类型
+     *
+     * @param userAgent
+     * @return
+     */
+    public static String getBorderType(String userAgent) {
+        Browser browser = getBrowser(userAgent);
+        String borderType = browser.getBrowserType().getName();
+        logger.info("borderType is:{}", borderType);
+        return borderType;
+    }
+
+    /**
+     * 获取浏览器组: CHROME、IE
+     *
+     * @param request
+     * @return
+     */
+    public static String getBorderGroup(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getBorderGroup(userAgent);
+    }
+
+    /**
+     * 获取浏览器组: CHROME、IE
+     *
+     * @param userAgent
+     * @return
+     */
+    public static String getBorderGroup(String userAgent) {
+        Browser browser = getBrowser(userAgent);
+        String browerGroup = browser.getGroup().getName();
+        logger.info("browerGroup is:{}", browerGroup);
+        return browerGroup;
+    }
+
+    /**
+     * 获取浏览器的生产厂商
+     *
+     * @param request
+     * @return
+     */
+    public static String getBrowserManufacturer(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getBrowserManufacturer(userAgent);
+    }
+
+
+    /**
+     * 获取浏览器的生产厂商
+     *
+     * @param userAgent
+     * @return
+     */
+    public static String getBrowserManufacturer(String userAgent) {
+        Browser browser = getBrowser(userAgent);
+        String browserManufacturer = browser.getManufacturer().getName();
+        logger.info("browserManufacturer is:{}", browserManufacturer);
+        return browserManufacturer;
+    }
+
+
+    /**
+     * 获取浏览器使用的渲染引擎
+     *
+     * @param request
+     * @return
+     */
+    public static String getBorderRenderingEngine(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getBorderRenderingEngine(userAgent);
+    }
+
+    /**
+     * 获取浏览器使用的渲染引擎
+     *
+     * @param userAgent
+     * @return
+     */
+    public static String getBorderRenderingEngine(String userAgent) {
+        Browser browser = getBrowser(userAgent);
+        String renderingEngine = browser.getRenderingEngine().name();
+        logger.info("renderingEngine is:{}", renderingEngine);
+        return renderingEngine;
+    }
+
+
+    /**
+     * 获取浏览器版本
+     *
+     * @param request
+     * @return
+     */
+    public static String getBrowserVersion(HttpServletRequest request) {
+        String userAgent = getUserAgent(request);
+        return getBrowserVersion(userAgent);
+    }
+
+    /**
+     * 获取浏览器版本
+     *
+     * @param userAgent
+     * @return
+     */
+    public static String getBrowserVersion(String userAgent) {
+        Browser browser = getBrowser(userAgent);
+        String borderVersion = browser.getVersion(userAgent).toString();
+        return borderVersion;
+    }
+
+
+    public static void main(String[] args) {
+		String winUserAgent = "Mozilla/5.0 (Linux; Android 8.0; LON-AL00 Build/HUAWEILON-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044204 Mobile Safari/537.36 V1_AND_SQ_7.7.8_908_YYB_D QQ/7.7.8.3705 NetType/WIFI WebP/0.3.0 Pixel/1440";
+//		String iosUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16A366 QQ/7.7.8.421 V1_IPH_SQ_7.7.8_1_APP_A Pixel/750 Core/UIWebView Device/Apple(iPhone 6s) NetType/WIFI QBWebViewType/1";
+//        String winUserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36";
+
+        System.out.println("浏览器组:" + getBorderGroup(winUserAgent));
+        System.out.println("浏览器名字:" + getBorderName(winUserAgent));
+        System.out.println("浏览器类型" + getBorderType(winUserAgent));
+        System.out.println("浏览器生产商:" + getBrowserManufacturer(winUserAgent));
+        System.out.println("浏览器版本:" + getBrowserVersion(winUserAgent));
+        System.out.println("设备生产厂商:" + getDeviceManufacturer(winUserAgent));
+        System.out.println("设备类型:" + getDeviceType(winUserAgent));
+        System.out.println("设备操作系统:" + getOs(winUserAgent));
+        System.out.println("操作系统的名字:" + getOsName(winUserAgent));
+        System.out.println("操作系统的版本号:" + getOsVersion(winUserAgent));
+        System.out.println("操作系统浏览器的渲染引擎:" + getBorderRenderingEngine(winUserAgent));
+        if (getOs(winUserAgent).contains("Windows")) {
+            System.out.println("是Windows");
+        } if (getOs(winUserAgent).contains("Linux")) {
+            System.out.println("是Linux");
+        } else {
+            System.out.println(getOs(winUserAgent));
+            System.out.println("无法匹配");
+        }
+    }
+}
+

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

@@ -114,7 +114,7 @@ referer:
     - www.ttkuaiban.com
     - mobworktime.ttkuaiban.com
     - worktime.ttkuaiban.com
-excludeUrls: /wxcorp/*,/wxcorp/*/*,/dingding/*,/error
+excludeUrls: /wxcorp/*,/wxcorp/*/*,/dingding/*,/error,/testClient,/corpWXAuth
 
 #企业微信相关参数
 suitId: ww4e237fd6abb635af

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

@@ -17,11 +17,12 @@
         <result column="package_expense" property="packageExpense" />
         <result column="package_customer" property="packageCustomer" />
         <result column="package_engineering" property="packageEngineering" />
+        <result column="package_simple" property="packageSimple" />
     </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, package_customer, package_engineering
+        id, company_name, staff_count_max, expiration_date, set_meal, package_worktime, package_project, package_contract, package_oa, package_etimecard, package_expense, package_customer, package_engineering, package_simple
     </sql>
 
 </mapper>

+ 28 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SimpleFinanceMapper.xml

@@ -0,0 +1,28 @@
+<?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.SimpleFinanceMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.SimpleFinance">
+        <id column="id" property="id" />
+        <result column="name" property="name" />
+        <result column="company_id" property="companyId" />
+        <result column="month_cost" property="monthCost" />
+        <result column="bonus" property="bonus" />
+        <result column="allowance" property="allowance" />
+        <result column="insurance_old" property="insuranceOld" />
+        <result column="insurance_medical" property="insuranceMedical" />
+        <result column="insurance_losejob" property="insuranceLosejob" />
+        <result column="house_fund" property="houseFund" />
+        <result column="others" property="others" />
+        <result column="total_cost" property="totalCost" />
+        <result column="ymonth" property="ymonth" />
+        <result column="hour_cost" property="hourCost" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, name, company_id, month_cost, bonus, allowance, insurance_old, insurance_medical, insurance_losejob, house_fund, others, total_cost, ymonth, hour_cost
+    </sql>
+
+</mapper>

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

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.management.platform.mapper.SimpleProjectimeMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.SimpleProjectime">
+        <id column="id" property="id" />
+        <result column="simple_id" property="simpleId" />
+        <result column="project_name" property="projectName" />
+        <result column="time_cost" property="timeCost" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, simple_id, project_name, time_cost
+    </sql>
+
+</mapper>

+ 24 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SimpleReportMapper.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.management.platform.mapper.SimpleReportMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.SimpleReport">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="ymonth" property="ymonth" />
+        <result column="report_date" property="reportDate" />
+        <result column="username" property="username" />
+        <result column="position" property="position" />
+        <result column="department" property="department" />
+        <result column="time_cost" property="timeCost" />
+        <result column="indate" property="indate" />
+        <result column="creator_id" property="creatorId" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, ymonth, report_date, username, position, department, time_cost, indate, creator_id
+    </sql>
+
+</mapper>

二進制
fhKeeper/formulahousekeeper/management-platform/工时统计表示例.xlsx


二進制
fhKeeper/formulahousekeeper/management-platform/项目工时统计表.xlsx


+ 39 - 27
fhKeeper/formulahousekeeper/timesheet/src/main.js

@@ -37,7 +37,7 @@ import './assets/myfont/iconfont.css'
 // const router = new VueRouter({
 //     routes
 // })
-import {fixedRouter, allRouters } from './routes'
+import {fixedRouter, allRouters, simpleRouters } from './routes'
 import router from './routes'
 
 import NProgress from 'nprogress'
@@ -72,35 +72,47 @@ router.beforeEach((to, from, next) => {
         if (!addRouFlag) {
             if(user != null) {
                 addRouFlag = true;
-                var getRoutes = null;
-                var filterRouter = allRouters;
-                if (user.company.packageExpense == 0) {
-                    filterRouter = filterRouter.filter(r=>{return r.name != '费用报销' && r.name != '项目报表服务'});
-                }
-                if (user.company.packageCustomer == 0) {
-                    //没有客户管理功能的,需要去掉
-                    filterRouter = filterRouter.filter(r=>{return r.name != '客户管理'});
-                }
-                if (user.company.packageEngineering == 0) {
-                    //非工程类的,去掉专业管理
-                    filterRouter = filterRouter.filter(r=>{return r.name != '工程专业管理' && r.name != '专业审核' && r.name != '部门审核'});
-                }
-
-                if (user.role == 1 || user.role == 2) {
-                    getRoutes = filterRouter;
+                //如果是简易版,直接赋值
+                if (user.company.packageSimple == 1) {
+                    console.log('走进了建议模式');
+                    getRoutes = simpleRouters;
+                    global.antRouter = getRoutes;
+                    router.addRoutes(getRoutes);
+                    router.options.routes = getRoutes;
+                    router.push({ path: to.path })
                 } else {
-                    var modules = userModules.filter(u=>u.role == user.role)[0].modules;
-                    if (user.role == 0 && user.leader) {
-                        modules.push(2, "项目报告审核");
+                    var getRoutes = null;
+                    var filterRouter = allRouters;
+                    if (user.company.packageExpense == 0) {
+                        filterRouter = filterRouter.filter(r=>{return r.name != '费用报销' && r.name != '项目报表服务'});
+                    }
+                    if (user.company.packageCustomer == 0) {
+                        //没有客户管理功能的,需要去掉
+                        filterRouter = filterRouter.filter(r=>{return r.name != '客户管理'});
                     }
-                    getRoutes = filterRouter.filter(r=>{
-                        return modules.filter(m=>m == r.name).length > 0;
-                    });
+                    if (user.company.packageEngineering == 0) {
+                        //非工程类的,去掉专业管理
+                        filterRouter = filterRouter.filter(r=>{return r.name != '工程专业管理' && r.name != '专业审核' && r.name != '部门审核'});
+                    }
+
+                    if (user.role == 1 || user.role == 2) {
+                        getRoutes = filterRouter;
+                    } else {
+                        var modules = userModules.filter(u=>u.role == user.role)[0].modules;
+                        if (user.role == 0 && user.leader) {
+                            modules.push(2, "项目报告审核");
+                        }
+                        getRoutes = filterRouter.filter(r=>{
+                            return modules.filter(m=>m == r.name).length > 0;
+                        });
+                    }
+                    
+                    global.antRouter = fixedRouter.concat(getRoutes);
+                    router.addRoutes(fixedRouter.concat(getRoutes));
+                    router.options.routes = fixedRouter.concat(getRoutes);
+                    router.push({ path: to.path })
                 }
-                global.antRouter = fixedRouter.concat(getRoutes);
-                router.addRoutes(fixedRouter.concat(getRoutes));
-                router.options.routes = fixedRouter.concat(getRoutes);
-                router.push({ path: to.path })
+                
                 
             }
         }

+ 30 - 21
fhKeeper/formulahousekeeper/timesheet/src/routes.js

@@ -54,6 +54,9 @@ import workflow from './views/workflow/report';
 // 权限管理
 // import jurisdiction from './views/jurisdiction/jurisdiction'
 
+//简易工时统计表
+import simpleReport from './views/simplereport/list';
+
 Vue.use(Router)
 
 export const fixedRouter = [
@@ -247,27 +250,7 @@ export const allRouters = [//组织架构
             { path: '/team', component: team, name: '组织架构' },
         ]
     },
-    // {
-    //     path: '/',
-    //     component: Home,
-    //     name: '',
-    //     iconCls: 'iconfont firerock-iconquanxian',
-    //     leaf: true,//只有一个节点
-    //     children: [
-    //         { path: '/role', component: role, name: '角色权限' },
-    //     ]
-    // },
-    // {
-        
-    //     path: '/',
-    //     component: Home,
-    //     name: '',
-    //     iconCls: 'iconfont firerock-iconliucheng',
-    //     leaf: true,//只有一个节点
-    //     children: [
-    //         { path: '/workflow', component: workflow, name: '审批流程设置' },
-    //     ]
-    // },
+    
     //设置时间类型
     {
         
@@ -293,6 +276,32 @@ export const allRouters = [//组织架构
     }
 ]
 
+export const simpleRouters = [
+    //工时统计表
+    {
+        
+        path: '/',
+        component: Home,
+        name: '',
+        iconCls: 'iconfont firerock-icontianbao1',
+        leaf: true,
+        children: [
+            { path: '/simple', component: simpleReport, name: '工时统计表' },
+        ]
+    },
+    {
+        path: '/404',
+        component: NotFound,
+        name: '',
+        hidden: true
+    },
+    {
+        path: '*',
+        hidden: true,
+        redirect: { path: '/404' }
+    }
+]
+
 export default new Router({
     routes: fixedRouter
 })

+ 4 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/Login.vue

@@ -256,7 +256,10 @@
                             if (res.code == "ok") {
                                 var user = res.data;
                                 sessionStorage.setItem('user', JSON.stringify(res.data));
-                                if (user.role == 3) {
+                                if (user.company.packageSimple == 1) {
+                                    //简易模式,直接进入工时统计表
+                                    this.$router.push({ path: '/simple' });
+                                } else if (user.role == 3) {
                                     //公司高层
                                     this.$router.push({ path: '/cost' });
                                 } else if (user.role == 4) {

+ 14 - 4
fhKeeper/formulahousekeeper/timesheet/src/views/Register.vue

@@ -28,8 +28,16 @@
                     <el-input type="password" v-model="ruleForm.repwd" autocomplete="off" placeholder="重复密码" clearable prefix-icon="iconfont firerock-iconmima">
                     </el-input>
                 </el-form-item>
-                <div style="color:#aaa;margin:55px 0 20px 0;"></div>
-                <div class="login-button" style="width:100%;margin-top:10px;">
+                
+                <el-form-item class="login-input" prop="type" style="text-align:center;">
+                    <el-divider ></el-divider>
+                    <div style="margin-top:10px;">
+                    <span>选择版本: </span><el-select v-model="ruleForm.type" style="width:250px;">
+                        <el-option v-for="item in typeList" :value="item.id" :label="item.name" :key="item.id"></el-option>
+                    </el-select>
+                    </div>
+                </el-form-item>
+                <div class="login-button" style="width:100%;margin-top:20px;">
                     <el-button type="primary" style="width:100%;" @click.native.prevent="handleSubmit" :loading="logining">注册</el-button>
                 </div>
             </el-form>
@@ -41,6 +49,8 @@
     export default {
         data() {
             return {
+                typeList:[{id:0,name:'工时统计表简易版'},{id:1,name:'工时统计基础版'},
+                {id:2,name:'项目管理专业版'},{id:3,name:'工程管理专业版'}],
                 logining: false,
                 showTimer: false,
                 countNum: 60,
@@ -49,7 +59,7 @@
                     companyName: '',
                     name: '',
                     phone: '',
-
+                    type:2,
                 },
                 rules: {
                     companyName: [{ required: true, message: '请输入公司名', trigger: 'blur' },],
@@ -176,7 +186,7 @@
                 -moz-border-radius: 5px;
                 background-clip: padding-box;
                 width: 450px;
-                height: 385px;
+                height: 495px;
                 padding: 25px 35px 25px 35px;
                 background: #fff;
                 border: 1px solid #eaeaea;

+ 436 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/simplereport/list.vue

@@ -0,0 +1,436 @@
+<template>
+    <section>
+        <!--工具条-->
+        <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
+            <el-form :inline="true">
+                <el-form-item label="员工工时统计 | 月份选择" style="margin-top:5px;">
+                <el-date-picker size="small" v-model="date" :editable="false" format="yyyy-MM" value-format="yyyy-MM" @change="changeMonth" :clearable="false" type="month" placeholder="选择月份"></el-date-picker>
+            </el-form-item>
+            
+            <el-form-item style="margin-top:5px;">
+                <el-radio-group @change="onTabChange" v-model="tabIndex">
+                
+                <el-radio label="1">看薪资</el-radio>
+                <el-radio label="2">看工时</el-radio>
+                </el-radio-group>
+                <el-button type="default" size="small" style="margin-left:30px;" @click="getProjectReport()">查看报表</el-button>
+            </el-form-item>
+            <el-form-item style="float:right;">
+                <el-link type="primary" :underline="false" href="./upload/员工工时统计模板.xlsx" download="员工工时统计模板.xlsx">模板下载</el-link>
+            </el-form-item>
+            <!-- <el-form-item style="float:right;">
+                <el-upload ref="upload" action="#" :limit="1" :http-request="importFinance" :show-file-list="false">
+                        <el-link type="primary" :underline="false" >财务数据上传</el-link>
+                    </el-upload>
+            </el-form-item> -->
+            <el-form-item style="float:right;">
+                <el-link type="primary" :underline="false" @click="importDialog = true;isUploading=false;">数据上传</el-link>
+            </el-form-item>
+            </el-form>
+        </el-col>
+        
+        <!--列表-->
+        <el-table :data="reportList" highlight-current-row v-loading="listLoading" 
+        show-summary=true v-show="tabIndex==2"
+        ref="Timetable"
+        :height="600" style="width: 100%;">
+        <el-table-column prop="reportDate" label="日期" sortable width="80" fixed="left"></el-table-column>
+        <el-table-column prop="username" label="姓名" width="100"  fixed="left"></el-table-column>
+            
+            <el-table-column prop="position" label="岗位" sortable width="120"></el-table-column>
+            <el-table-column prop="department" label="部门" sortable width="150"></el-table-column>
+            
+            <el-table-column v-for="item in projectList" :label="item" :key="item">
+                <template slot-scope="scope">
+                    {{scope.row.projectimeList.filter(p=>p.projectName == item).length==0?"0.0":
+                            scope.row.projectimeList.filter(p=>p.projectName == item)[0].timeCost.toFixed(1)}}
+                </template>
+            </el-table-column>
+            
+            <el-table-column prop="timeCost" label="总时长(h)" >
+                <template slot-scope="scope">
+                    {{scope.row.timeCost.toFixed(1)}}
+                </template>
+            </el-table-column>
+        </el-table>
+        <!-- <el-form :inline="true" >
+            <el-form-item >
+                <el-link type="primary" :underline="false" @click="assignToProject" style="margin-left:5px;">查看项目成本分配</el-link>
+            </el-form-item>
+            <el-form-item style="float:right;">
+                <el-link type="primary" :underline="false" @click="exportData">导出数据</el-link>
+            </el-form-item>
+        </el-form> -->
+        
+        <el-table :data="list" highlight-current-row v-loading="listLoading" 
+        show-summary=true v-show="tabIndex==1"
+        ref="table"
+        :height="600" style="width: 100%;">
+            <el-table-column prop="name" label="姓名"  width="150"></el-table-column>
+            <el-table-column prop="monthCost" label="工资"  width="150"></el-table-column>
+            <el-table-column prop="bonus" label="奖金" ></el-table-column>
+            <el-table-column prop="allowance" label="津贴" ></el-table-column>
+            <el-table-column prop="insuranceOld" label="养老保险" ></el-table-column>
+            <el-table-column prop="insuranceMedical" label="医疗保险" ></el-table-column>
+            <el-table-column prop="insuranceLosejob" label="失业保险" ></el-table-column>
+            <el-table-column prop="houseFund" label="住房公积金" ></el-table-column>
+            <el-table-column prop="others" label="其他" ></el-table-column>
+            <el-table-column prop="totalCost" label="总成本" ></el-table-column>
+        </el-table>
+        <!-- <el-form :inline="true" >
+            <el-form-item >
+                <el-link type="primary" :underline="false" @click="assignToProject" style="margin-left:5px;">查看项目成本分配</el-link>
+            </el-form-item>
+            <el-form-item style="float:right;">
+                <el-link type="primary" :underline="false" @click="exportData">导出数据</el-link>
+            </el-form-item>
+        </el-form> -->
+        
+        
+         
+         <!--导入时的设置界面 -->
+         <el-dialog title="工时数据导入" v-if="importDialog" :visible.sync="importDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
+            <el-form ref="form3" :model="importParam" >
+                <el-form-item label="导入月份" >
+                    <div style="color:orange;">{{date}}</div>
+                </el-form-item>
+                <p>请按照模板格式填写员工月度工时表和员工月度薪资表</p>
+                <el-link type="primary" :underline="false" href="./upload/员工工时统计模板.xlsx" download="员工工时统计模板.xlsx">模板下载</el-link>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-upload ref="upload" action="#" :limit="1" :http-request="importFinance" :show-file-list="false" >
+                        <el-button type="primary" style="width:100%;" :loading="isUploading" >选择文件并开始导入</el-button>
+                    </el-upload>
+            </div>
+        </el-dialog>
+        <el-dialog v-if="showDialog" :visible.sync="showDialog" 
+        :close-on-click-modal="false" width="95%">
+            <div id="container" style="height:500px"></div>
+            <div slot="title" >
+                <span style="color:#666;font-size:14px;">统计维度: </span>
+                <el-select v-model="typeIndex" size="small" @change="switchType">
+                    <el-option value="按项目">按项目</el-option>
+                    <el-option value="按岗位">按岗位</el-option>
+                    <el-option value="按部门">按部门</el-option>
+                </el-select>
+                <el-button size="small" @click="exportData">导出Excel</el-button>
+            </div>
+        </el-dialog>
+        
+    </section>
+</template>
+<style scoped>
+.line {
+    padding:10px;
+}
+.line span{
+    font-size:18px;
+}
+.line span:nth-child(even){
+    float:right;
+}
+</style>
+<script>
+    import util from "../../common/js/util";
+
+    export default {
+        data() {
+            return {
+                typeIndex:'按项目',
+                reportList:[],
+                projectList:[],
+                tabIndex:"1",
+                isUploading:false,
+                showDialog:false,
+                importDialog: false,
+                importParam:{},
+                user: JSON.parse(sessionStorage.getItem("user")),
+                
+                date: null,
+                tableHeight: 0,
+                listLoading: false,
+                list: [],
+                addLoading: false,
+                myChart: null,
+                params: null,
+            };
+        },
+        methods: {
+            switchType() {
+                this.getProjectReport();
+            },
+            getProjectReport(){
+                this.showDialog = true;
+                var _this = this;
+                this.http.post('/simple-report/getTimeCost', {yearMonth: this.date,companyId: this.user.companyId, type: this.typeIndex},
+                res => {
+                    if (res.code == "ok") {
+                        var xList = [], yList = [], list = res.data.costList, 
+                        totalMoneyCost = res.data.totalMoneyCost;
+                        for(var i in list) {
+                            xList.push(list[i].name);
+                                yList.push({
+                                    "value": list[i].cost,
+                                    "id": list[i].id,
+                                    "time": list[i].workingTime
+                                });
+                        }
+
+                        var myChart = echarts.init(document.getElementById("container"));
+                        _this.myChart = myChart;
+                        var option = {
+                            title: {
+                                text: '成本统计 总计' + totalMoneyCost + '元',
+                                left:'left',
+                            },
+                            // 工具箱
+                            toolbox: {
+                                show: true,
+                                feature:{
+                                    saveAsImage:{
+                                        show:true
+                                    },
+                                    restore:{
+                                        show:true
+                                    },
+                                    magicType:{
+                                        type:['line','bar']
+                                    },
+                                     
+                                }
+                            },
+                            tooltip:{
+                                trigger:'axis',
+                                formatter: function (params,ticket,callback) {
+                                    var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.value 
+                                    + "元 <br/>工作时长"+" : " + params[0].data.time + "小时";
+                                    _this.params = params;
+                                    return res;
+                                }
+                            },
+                            xAxis: {
+                                data: xList,
+                                axisLabel: {
+                                    interval:0,rotate:20
+                                }
+                            },
+                            yAxis: [{
+                                type : 'value',
+                                axisLabel: {
+                                    formatter:'{value} (元)'
+                                }
+                            }],
+                            series: [{
+                                name: '工作时长(h)',
+                                type: 'bar',
+                                barMaxWidth: 30,
+                                data: yList,
+                            }]
+                        };
+                        myChart.setOption(option);
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            //导出财务数据
+            exportData() {
+                this.listLoading = true;
+                this.http.post('/simple-report/exportData', {
+                    yearMonth: this.date,companyId: this.user.companyId, type: this.typeIndex
+                },
+                res => {
+                    this.listLoading = false;
+                    if (res.code == "ok") {
+                        var aTag = document.createElement('a');
+                        aTag.download = this.date+this.typeIndex+"报表.xlsx";
+                        aTag.href = res.data;
+                        aTag.click();
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.listLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            getSummaries(param) {
+                const { columns, data } = param;
+                const sums = [];
+                columns.forEach((column, index) => {
+                if (index === 0) {
+                    sums[index] = '总价';
+                    return;
+                }
+                const values = data.map(item => Number(item[column.property]));
+                if (!values.every(value => isNaN(value))) {
+                    sums[index] = values.reduce((prev, curr) => {
+                    const value = Number(curr);
+                    if (!isNaN(value)) {
+                        return prev + curr;
+                    } else {
+                        return prev;
+                    }
+                    }, 0);
+                    sums[index] += ' 元';
+                } else {
+                    sums[index] = 'N/A';
+                }
+                });
+
+                return sums;
+            },
+            changeMonth() {
+                //改变月份
+                this.getList();
+                this.getReportList();
+            },
+            // 批量导入人员
+            importFinance(item) {
+                //首先判断文件类型
+                let str = item.file.name.split(".");
+                let format = str[str.length - 1];
+                if (format != "xls" && format != "xlsx") {
+                    this.$message({
+                        message: "请选择.xls或.xlsx文件",
+                        type: "error"
+                    });
+                } else {
+                    this.listLoading = true;
+                    let formData = new FormData();
+                    formData.append("file", item.file);
+                    formData.append("companyId", this.user.companyId);
+                    console.log('date====='+this.date);
+                    formData.append("yearMonth", this.date);
+                    this.isUploading = true;
+                    this.http.uploadFile('/simple-report/importData', formData,
+                    res => {
+                        this.$refs.upload.clearFiles();
+                        this.listLoading = false;
+                        this.isUploading = false;
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: "导入成功",
+                                type: "success"
+                            });
+                            this.importDialog = false;
+                            //重新读取列表
+                            this.getList();
+                            this.getReportList();
+                            this.getProjectReport();
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.$refs.upload.clearFiles();
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                    });
+                }
+            },
+
+            getReportList() {
+                this.http.post('/simple-report/getReportByMonth', {
+                    companyId: this.user.companyId,
+                    yearMonth: this.date
+                },
+                res => {
+                    this.listLoading = false;
+                    if (res.code == "ok") {
+                        var data = res.data;
+                        this.reportList = data.records;
+                        this.projectList = data.projectList;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.listLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            //获取薪资列表
+            getList() {
+                this.listLoading = true;
+                this.http.post('/simple-report/getByMonth', {
+                    companyId: this.user.companyId,
+                    yearMonth: this.date
+                },
+                res => {
+                    this.listLoading = false;
+                    if (res.code == "ok") {
+                        var list = res.data;
+                        this.list = list;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.listLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+
+        },
+        created() {
+            
+            var d = new Date();
+            this.date = d.getFullYear() +'-'+ ((d.getMonth()+1) < 10? '0'+(d.getMonth()+1):d.getMonth()+1);
+            
+        },
+        mounted() {
+            let height = window.innerHeight;
+            this.tableHeight = height - 245;
+            const that = this;
+            window.onresize = function temp() {
+                that.tableHeight = window.innerHeight - 245;
+            };
+            this.getList();
+            this.getReportList();
+            // this.getProjectReport();
+        },
+        updated() {
+            this.$nextTick(() => {
+                this.$refs['table'].doLayout();
+            }) 
+        }
+    };
+</script>
+
+<style lang="scss" scoped>
+</style>

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

@@ -172,8 +172,9 @@
         <!-- 填写日报的dialog -->
         <el-dialog :title="isBatch==0?'填写日报':'批量填报'" :visible.sync="dialogVisible" width="60%" :close-on-click-modal="false">
             <el-form ref="workForm" :model="workForm" :rules="workRules" label-width="100px">
-                <el-form-item label="选择人员" prop="userNames" v-if="isSubstitude" 
-                :rules="{ required: true, message: '请选择代填人员', trigger: 'change' }">
+                <el-form-item label="选择人员" v-if="isSubstitude" 
+
+                >
                     <el-input @focus="showChooseMembTree" v-model="workForm.userNames"
                     placeholder="请选择代填人员" ></el-input>
                 </el-form-item>
@@ -1562,14 +1563,14 @@
                 if (this.isSubstitude) {
                     this.getSubstitudeUserDeptList();
                 }
-                if(i == -1) {
+                if(i == -1 || this.isSubstitude) {
                     this.isDisable = false;
                 } else {
                     this.isDisable = true;
                 }
                 let day = (this.choseDay + 1) > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
                 this.isBatch = isBatch;
-                if (this.isBatch == 0) {
+                if (this.isBatch == 0 && !this.isSubstitude) {
                     this.workForm.createDate = this.date + day; // 获取个人某天的日报
                     this.getReport(i);
                 } else {
@@ -1640,7 +1641,7 @@
 
             // 改变月份
             changeMonth() {
-                if (this.isBatch == 0) {
+                if (this.isBatch == 0 && !this.isSubstitude) {
                     //只有按天填报才能获取当天的日报
                     this.getReport()
                 }
@@ -1650,6 +1651,16 @@
             submitDepartment() {
                 this.$refs.workForm.validate(valid => {
                     if (valid) {
+                        //代填的情况,检查人员是否已经选择
+                        if (this.isSubstitude) {
+                            if (this.workForm.userNames == null || this.workForm.userNames.length == 0) {
+                                this.$message({
+                                        message: "请选择代填的人员",
+                                        type: "error"
+                                    });
+                                return;
+                            }
+                        }
                         //检查时间,全天和上下午不能同时存在
                         if (this.reportTimeType.type == 0) {
                             var alldayNum = 0;