فهرست منبع

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. BIN
      fhKeeper/formulahousekeeper/management-platform/工时统计表示例.xlsx
  30. BIN
      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>
 <head>
     <meta charset="utf-8">
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <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利器"/>
     <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="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/bootstrap.css" rel="stylesheet">
     <!-- <link href="css/fontawesome-all.css" rel="stylesheet"> -->
     <!-- <link href="css/fontawesome-all.css" rel="stylesheet"> -->
@@ -108,11 +108,11 @@
                     <div class="row">
                     <div class="row">
                         <div class="col-lg-12 col-xl-12">
                         <div class="col-lg-12 col-xl-12">
                             <div class="text-container">
                             <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 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">
                                     <div style="width: 100%;" class="ald">
                                         <!-- <a class="btn-solid-lg btn-solid-lg-white page-scroll overload">软件演示 -->
                                         <!-- <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">
                                             <div class="service2">
                                                 <p style="color: #333">微信扫码</p>
                                                 <p style="color: #333">微信扫码</p>
                                                 <img src="./images/code.jpg">
                                                 <img src="./images/code.jpg">
@@ -322,6 +322,31 @@
                 <p>PRICE PLAN</p>
                 <p>PRICE PLAN</p>
             </div>
             </div>
             <div class="pri">
             <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">
                     <div class="li_con">
                     <div class="li_con">
                         <div>基础版</div>
                         <div>基础版</div>

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

@@ -159,6 +159,15 @@
             <artifactId>spring-boot-configuration-processor</artifactId>
             <artifactId>spring-boot-configuration-processor</artifactId>
             <optional>true</optional>
             <optional>true</optional>
         </dependency>
         </dependency>
+
+        <!-- 获取客户端信息 -->
+        <!-- https://mvnrepository.com/artifact/eu.bitwalker/UserAgentUtils -->
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+            <version>1.21</version>
+        </dependency>
+
     </dependencies>
     </dependencies>
 
 
     <build>
     <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.SysConfigMapper;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.UserAgentUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.*;
 import org.springframework.http.*;
 import org.springframework.stereotype.Controller;
 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.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.client.RestTemplate;
 import org.springframework.web.client.RestTemplate;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.view.RedirectView;
 import org.springframework.web.servlet.view.RedirectView;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 import java.time.ZoneOffset;
 import java.util.HashMap;
 import java.util.HashMap;
@@ -30,7 +34,8 @@ import java.util.Map;
 
 
 @Controller
 @Controller
 public class AuthRedirectController {
 public class AuthRedirectController {
-
+    @Resource
+    HttpServletRequest request;
     @Value("${suitId}")
     @Value("${suitId}")
     private String suitId;
     private String suitId;
     @Value("${suitSecret}")
     @Value("${suitSecret}")
@@ -52,7 +57,14 @@ public class AuthRedirectController {
     @RequestMapping("/corpWXAuth")
     @RequestMapping("/corpWXAuth")
     public ModelAndView auth(String code, int state) {
     public ModelAndView auth(String code, int state) {
         Map<String,Object> reqParam = new HashMap<String,Object>(16);
         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 url = WeiXinCorpController.GET_CORP_USERINFO_URL.replace("SUITE_ACCESS_TOKEN", getSuiteAccessToken()).replace("CODE", code);
         String forObject = this.restTemplate.getForObject(url, String.class);
         String forObject = this.restTemplate.getForObject(url, String.class);
         JSONObject obj = JSONObject.parseObject(forObject);
         JSONObject obj = JSONObject.parseObject(forObject);
@@ -76,6 +88,39 @@ public class AuthRedirectController {
         return modelAndView;
         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() {
     private String getSuiteAccessToken() {
         if (WeiXinCorpController.SUITE_ACCESS_TOKEN == null || WeiXinCorpController.suiteTokenExpireTime < System.currentTimeMillis()) {
         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 公司名
      * companyName 公司名
      * name 姓名
      * name 姓名
      * phone 电话号码
      * phone 电话号码
+     * type: 0-简易版,1-基础版,2-项目管理专业版,3-工程管理专业版
      */
      */
     @RequestMapping("/insertCompany")
     @RequestMapping("/insertCompany")
     public HttpRespMsg insertCompany(
     public HttpRespMsg insertCompany(
             @RequestParam String companyName, @RequestParam String name, @RequestParam String phone,
             @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>
  * </p>
  *
  *
  * @author Seyason
  * @author Seyason
- * @since 2021-08-28
+ * @since 2021-10-22
  */
  */
 @Data
 @Data
 @EqualsAndHashCode(callSuper = false)
 @EqualsAndHashCode(callSuper = false)
@@ -103,6 +103,12 @@ public class Company extends Model<Company> {
     @TableField("package_engineering")
     @TableField("package_engineering")
     private Integer packageEngineering;
     private Integer packageEngineering;
 
 
+    /**
+     * 简单表格版本
+     */
+    @TableField("package_simple")
+    private Integer packageSimple;
+
 
 
     @Override
     @Override
     protected Serializable pkVal() {
     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 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,
     HttpRespMsg insertUser(String id, String name, String phone, Integer role, Double monthCost, Double cost, Integer departmentId,
                            Integer salaryType, String costApplyDate,
                            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
     @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();
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         //检查验证码是否正确
         //检查验证码是否正确
         LocalDateTime now = LocalDateTime.now();
         LocalDateTime now = LocalDateTime.now();
@@ -335,6 +335,26 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
             //首先生成一个新公司,增加会员的试用一个月
             //首先生成一个新公司,增加会员的试用一个月
             Company company = new Company().setCompanyName(companyName)
             Company company = new Company().setCompanyName(companyName)
                     .setExpirationDate(LocalDateTime.now().plusMonths(1));
                     .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);
             companyMapper.insert(company);
             //生成工作时长
             //生成工作时长
             TimeType timeType = new TimeType();
             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
     - www.ttkuaiban.com
     - mobworktime.ttkuaiban.com
     - mobworktime.ttkuaiban.com
     - worktime.ttkuaiban.com
     - worktime.ttkuaiban.com
-excludeUrls: /wxcorp/*,/wxcorp/*/*,/dingding/*,/error
+excludeUrls: /wxcorp/*,/wxcorp/*/*,/dingding/*,/error,/testClient,/corpWXAuth
 
 
 #企业微信相关参数
 #企业微信相关参数
 suitId: ww4e237fd6abb635af
 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_expense" property="packageExpense" />
         <result column="package_customer" property="packageCustomer" />
         <result column="package_customer" property="packageCustomer" />
         <result column="package_engineering" property="packageEngineering" />
         <result column="package_engineering" property="packageEngineering" />
+        <result column="package_simple" property="packageSimple" />
     </resultMap>
     </resultMap>
 
 
     <!-- 通用查询结果列 -->
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
     <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>
     </sql>
 
 
 </mapper>
 </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>

BIN
fhKeeper/formulahousekeeper/management-platform/工时统计表示例.xlsx


BIN
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({
 // const router = new VueRouter({
 //     routes
 //     routes
 // })
 // })
-import {fixedRouter, allRouters } from './routes'
+import {fixedRouter, allRouters, simpleRouters } from './routes'
 import router from './routes'
 import router from './routes'
 
 
 import NProgress from 'nprogress'
 import NProgress from 'nprogress'
@@ -72,35 +72,47 @@ router.beforeEach((to, from, next) => {
         if (!addRouFlag) {
         if (!addRouFlag) {
             if(user != null) {
             if(user != null) {
                 addRouFlag = true;
                 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 {
                 } 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 jurisdiction from './views/jurisdiction/jurisdiction'
 
 
+//简易工时统计表
+import simpleReport from './views/simplereport/list';
+
 Vue.use(Router)
 Vue.use(Router)
 
 
 export const fixedRouter = [
 export const fixedRouter = [
@@ -247,27 +250,7 @@ export const allRouters = [//组织架构
             { path: '/team', component: team, name: '组织架构' },
             { 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({
 export default new Router({
     routes: fixedRouter
     routes: fixedRouter
 })
 })

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

@@ -256,7 +256,10 @@
                             if (res.code == "ok") {
                             if (res.code == "ok") {
                                 var user = res.data;
                                 var user = res.data;
                                 sessionStorage.setItem('user', JSON.stringify(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' });
                                     this.$router.push({ path: '/cost' });
                                 } else if (user.role == 4) {
                                 } 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 type="password" v-model="ruleForm.repwd" autocomplete="off" placeholder="重复密码" clearable prefix-icon="iconfont firerock-iconmima">
                     </el-input>
                     </el-input>
                 </el-form-item>
                 </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>
                     <el-button type="primary" style="width:100%;" @click.native.prevent="handleSubmit" :loading="logining">注册</el-button>
                 </div>
                 </div>
             </el-form>
             </el-form>
@@ -41,6 +49,8 @@
     export default {
     export default {
         data() {
         data() {
             return {
             return {
+                typeList:[{id:0,name:'工时统计表简易版'},{id:1,name:'工时统计基础版'},
+                {id:2,name:'项目管理专业版'},{id:3,name:'工程管理专业版'}],
                 logining: false,
                 logining: false,
                 showTimer: false,
                 showTimer: false,
                 countNum: 60,
                 countNum: 60,
@@ -49,7 +59,7 @@
                     companyName: '',
                     companyName: '',
                     name: '',
                     name: '',
                     phone: '',
                     phone: '',
-
+                    type:2,
                 },
                 },
                 rules: {
                 rules: {
                     companyName: [{ required: true, message: '请输入公司名', trigger: 'blur' },],
                     companyName: [{ required: true, message: '请输入公司名', trigger: 'blur' },],
@@ -176,7 +186,7 @@
                 -moz-border-radius: 5px;
                 -moz-border-radius: 5px;
                 background-clip: padding-box;
                 background-clip: padding-box;
                 width: 450px;
                 width: 450px;
-                height: 385px;
+                height: 495px;
                 padding: 25px 35px 25px 35px;
                 padding: 25px 35px 25px 35px;
                 background: #fff;
                 background: #fff;
                 border: 1px solid #eaeaea;
                 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 -->
         <!-- 填写日报的dialog -->
         <el-dialog :title="isBatch==0?'填写日报':'批量填报'" :visible.sync="dialogVisible" width="60%" :close-on-click-modal="false">
         <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 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"
                     <el-input @focus="showChooseMembTree" v-model="workForm.userNames"
                     placeholder="请选择代填人员" ></el-input>
                     placeholder="请选择代填人员" ></el-input>
                 </el-form-item>
                 </el-form-item>
@@ -1562,14 +1563,14 @@
                 if (this.isSubstitude) {
                 if (this.isSubstitude) {
                     this.getSubstitudeUserDeptList();
                     this.getSubstitudeUserDeptList();
                 }
                 }
-                if(i == -1) {
+                if(i == -1 || this.isSubstitude) {
                     this.isDisable = false;
                     this.isDisable = false;
                 } else {
                 } else {
                     this.isDisable = true;
                     this.isDisable = true;
                 }
                 }
                 let day = (this.choseDay + 1) > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
                 let day = (this.choseDay + 1) > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
                 this.isBatch = isBatch;
                 this.isBatch = isBatch;
-                if (this.isBatch == 0) {
+                if (this.isBatch == 0 && !this.isSubstitude) {
                     this.workForm.createDate = this.date + day; // 获取个人某天的日报
                     this.workForm.createDate = this.date + day; // 获取个人某天的日报
                     this.getReport(i);
                     this.getReport(i);
                 } else {
                 } else {
@@ -1640,7 +1641,7 @@
 
 
             // 改变月份
             // 改变月份
             changeMonth() {
             changeMonth() {
-                if (this.isBatch == 0) {
+                if (this.isBatch == 0 && !this.isSubstitude) {
                     //只有按天填报才能获取当天的日报
                     //只有按天填报才能获取当天的日报
                     this.getReport()
                     this.getReport()
                 }
                 }
@@ -1650,6 +1651,16 @@
             submitDepartment() {
             submitDepartment() {
                 this.$refs.workForm.validate(valid => {
                 this.$refs.workForm.validate(valid => {
                     if (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) {
                         if (this.reportTimeType.type == 0) {
                             var alldayNum = 0;
                             var alldayNum = 0;