Ver Fonte

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

# Conflicts:
#	fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ScreenshotServiceImpl.java
seyason há 5 anos atrás
pai
commit
737bea1d18
23 ficheiros alterados com 582 adições e 109 exclusões
  1. 8 1
      fhKeeper/formulahousekeeper/management-platform/pom.xml
  2. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  3. 16 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java
  4. 3 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeCalculation.java
  5. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  6. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ScreenshotMapper.java
  7. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  8. 3 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserService.java
  9. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  10. 88 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  11. 11 10
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ScreenshotServiceImpl.java
  12. 46 13
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TimeCalculationServiceImpl.java
  13. 109 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  14. 15 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  15. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ScreenshotMapper.xml
  16. 13 8
      fhKeeper/formulahousekeeper/timesheet/src/http.js
  17. 3 5
      fhKeeper/formulahousekeeper/timesheet/src/port.js
  18. 10 10
      fhKeeper/formulahousekeeper/timesheet/src/routes.js
  19. 26 1
      fhKeeper/formulahousekeeper/timesheet/src/views/desktop/index.vue
  20. 29 1
      fhKeeper/formulahousekeeper/timesheet/src/views/desktop/unusual.vue
  21. 1 31
      fhKeeper/formulahousekeeper/timesheet/src/views/system/index.vue
  22. 181 5
      fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue
  23. 2 2
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/statistics.vue

+ 8 - 1
fhKeeper/formulahousekeeper/management-platform/pom.xml

@@ -104,7 +104,14 @@
             <artifactId>tess4j</artifactId>
         </dependency>
 
-
+        <!--手动引入opencv 否则无法maven打包-->
+        <dependency>
+            <groupId>org.opencv</groupId>
+            <artifactId>opencv</artifactId>
+            <version>4.2.0</version>
+            <scope>system</scope>
+            <systemPath>${basedir}/opencv/opencv-420.jar</systemPath>
+        </dependency>
     </dependencies>
 
 

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

@@ -41,6 +41,12 @@ public class ReportController {
         return reportService.getReportList(date, request);
     }
 
+    @RequestMapping("/exportReport")
+    public HttpRespMsg exportReport(@RequestParam String date) {
+        return reportService.exportReport(date, request);
+    }
+
+
     /**
      * 根据时间 获取本人报告信息 以及工时
      * date 日期 格式yyyy-mm-dd
@@ -79,7 +85,7 @@ public class ReportController {
             }
         } catch (NullPointerException e) {
             HttpRespMsg httpRespMsg = new HttpRespMsg();
-            httpRespMsg.setError("缺少数据");
+            httpRespMsg.setError("验证失败");
             return httpRespMsg;
         }
         return reportService.editReport(reportList);

+ 16 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java

@@ -80,7 +80,7 @@ public class UserController {
      * newPassword 新密码
      */
     @RequestMapping("/editPassword")
-    HttpRespMsg editPassword(@RequestParam String originPassword, @RequestParam String newPassword) {
+    public HttpRespMsg editPassword(@RequestParam String originPassword, @RequestParam String newPassword) {
         return userService.editPassword(originPassword, newPassword, request);
     }
 
@@ -91,7 +91,8 @@ public class UserController {
      * phone 电话号码
      */
     @RequestMapping("/insertCompany")
-    HttpRespMsg insertCompany(@RequestParam String companyName, @RequestParam String name, @RequestParam String phone) {
+    public HttpRespMsg insertCompany(
+            @RequestParam String companyName, @RequestParam String name, @RequestParam String phone) {
         return userService.insertCompany(companyName, name, phone);
     }
 
@@ -102,7 +103,7 @@ public class UserController {
      * role 角色 0-普通员工 2-管理员
      */
     @RequestMapping("/insertUser")
-    HttpRespMsg insertUser(@RequestParam String name, @RequestParam String phone, @RequestParam Integer role) {
+    public HttpRespMsg insertUser(@RequestParam String name, @RequestParam String phone, @RequestParam Integer role) {
         return userService.insertUser(name, phone, role, request);
     }
 
@@ -111,8 +112,19 @@ public class UserController {
      * file Excel文件
      */
     @RequestMapping("/importUser")
-    HttpRespMsg importUser(@RequestParam MultipartFile file) {
+    public HttpRespMsg importUser(@RequestParam MultipartFile file) {
         return userService.importUser(file, request);
     }
+
+
+    /**
+     * 切换权限
+     * 负责人可以将本公司的管理员切换至普通员工或者反之
+     * id 目标id
+     */
+    @RequestMapping("/switchPermission")
+    public HttpRespMsg switchPermission(@RequestParam String id) {
+        return userService.switchPermission(id, request);
+    }
 }
 

+ 3 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeCalculation.java

@@ -17,7 +17,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author 吴涛涛
- * @since 2020-01-09
+ * @since 2020-01-16
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -63,10 +63,10 @@ public class TimeCalculation extends Model<TimeCalculation> {
     private LocalTime endTime;
 
     /**
-     * 持续时间
+     * 持续时间
      */
     @TableField("duration")
-    private Double duration;
+    private Integer duration;
 
 
     @Override

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java

@@ -17,6 +17,8 @@ import java.util.Map;
  * @since 2019-12-31
  */
 public interface ReportMapper extends BaseMapper<Report> {
+    List<Map<String, Object>> getAllReportByDate(@Param("date") String date);
+
     List<Map<String, Object>> getReportByDate(@Param("date") String date, @Param("id") String id);
 
     List<Map<String, Object>> getReportNameByDate(@Param("date") String date, @Param("companyId") Integer companyId);

+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ScreenshotMapper.java

@@ -18,7 +18,8 @@ import java.util.Map;
  * @since 2020-01-02
  */
 public interface ScreenshotMapper extends BaseMapper<Screenshot> {
-    List<Map<String, Object>> getLatestScreenshotList(@Param("companyId")Integer companyId);
+    List<Map<String, Object>> getLatestScreenshotList(@Param("companyId")Integer companyId,
+                                                      @Param("date")String date);
 
     HttpRespMsg saveAndProcessImage(ScreenshotVO screenshotvo);
 }

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

@@ -18,6 +18,8 @@ import java.util.List;
 public interface ReportService extends IService<Report> {
     HttpRespMsg getReportList(String date, HttpServletRequest request);
 
+    HttpRespMsg exportReport(String date, HttpServletRequest request);
+
     HttpRespMsg getReport(String date, HttpServletRequest request);
 
     HttpRespMsg editReport(List<Report> reportList);

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

@@ -32,5 +32,7 @@ public interface UserService extends IService<User> {
 
     HttpRespMsg insertUser(String name, String phone, Integer role, HttpServletRequest request);
 
-    HttpRespMsg importUser(MultipartFile file, HttpServletRequest request);
+    HttpRespMsg importUser(MultipartFile multipartFile, HttpServletRequest request);
+
+    HttpRespMsg switchPermission(String id, HttpServletRequest request);
 }

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

@@ -41,6 +41,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             httpRespMsg.data = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", companyId));
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
+            return httpRespMsg;
         }
         return httpRespMsg;
     }
@@ -68,8 +69,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             }
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
+            return httpRespMsg;
         }
-
         return httpRespMsg;
     }
 

+ 88 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -12,17 +12,18 @@ import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.ReportService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.util.HttpRespMsg;
+import org.apache.poi.hssf.usermodel.*;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
@@ -47,6 +48,9 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     @Resource
     private ProjectMapper projectMapper;
 
+    @Value(value = "${upload.path}")
+    private String path;
+
     //获取报告列表
     @Override
     public HttpRespMsg getReportList(String date, HttpServletRequest request) {
@@ -62,6 +66,84 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             httpRespMsg.data = nameList;
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
+            return httpRespMsg;
+        }
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg exportReport(String date, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            //准备导出
+            HSSFWorkbook workbook = new HSSFWorkbook();
+            HSSFSheet sheet = workbook.createSheet(date + "日报");
+            //创建表头
+            HSSFRow headRow = sheet.createRow(0);
+            //设置列宽 setColumnWidth的第二个参数要乘以256,这个参数的单位是1/256个字符宽度
+            sheet.setColumnWidth(0, 5 * 256);
+            sheet.setColumnWidth(1, 18 * 256);
+            sheet.setColumnWidth(2, 18 * 256);
+            sheet.setColumnWidth(3, 18 * 256);
+            sheet.setColumnWidth(4, 30 * 256);
+            sheet.setColumnWidth(5, 18 * 256);
+            //设置为居中加粗
+            HSSFCellStyle headStyle = workbook.createCellStyle();
+            HSSFFont font = workbook.createFont();
+            font.setBold(true);
+            headStyle.setFont(font);
+
+            HSSFCell headCell;
+            headCell = headRow.createCell(0);
+            headCell.setCellValue("序号");
+            headCell.setCellStyle(headStyle);
+            headCell = headRow.createCell(1);
+            headCell.setCellValue("上传者");
+            headCell.setCellStyle(headStyle);
+            headCell = headRow.createCell(2);
+            headCell.setCellValue("项目名称");
+            headCell.setCellStyle(headStyle);
+            headCell = headRow.createCell(3);
+            headCell.setCellValue("工作时间");
+            headCell.setCellStyle(headStyle);
+            headCell = headRow.createCell(4);
+            headCell.setCellValue("工作内容");
+            headCell.setCellStyle(headStyle);
+            headCell = headRow.createCell(5);
+            headCell.setCellValue("提交时间");
+            headCell.setCellStyle(headStyle);
+
+            //设置日期格式
+            HSSFCellStyle style = workbook.createCellStyle();
+            style.setDataFormat(HSSFDataFormat.getBuiltinFormat("yy/mm/dd hh:mm"));
+            //新增数据行,并且设置单元格数据
+            int rowNum = 1;
+            for (Map<String, Object> map : reportMapper.getAllReportByDate(date)) {
+                HSSFRow row = sheet.createRow(rowNum);
+                row.createCell(0).setCellValue(rowNum);
+                row.createCell(1).setCellValue((String) map.get("name"));
+                row.createCell(2).setCellValue((String) map.get("project"));
+                row.createCell(3).setCellValue((String) map.get("duration"));
+                row.createCell(4).setCellValue((String) map.get("content"));
+                HSSFCell cell = row.createCell(5);
+                cell.setCellValue((String) map.get("time"));
+                cell.setCellStyle(style);
+                rowNum++;
+            }
+
+            //生成Excel文件
+            String fileUrlSuffix = date + "日报" + new SimpleDateFormat("hh-mm-ss").format(new Date()) + ".xls";
+            FileOutputStream fos = new FileOutputStream(path + fileUrlSuffix);
+            workbook.write(fos);
+            fos.flush();
+            fos.close();
+            httpRespMsg.data = "/upload/" + fileUrlSuffix;
+        } catch (NullPointerException e) {
+            httpRespMsg.setError("验证失败");
+            return httpRespMsg;
+        } catch (IOException e) {
+            httpRespMsg.setError("文件生成错误");
+            return httpRespMsg;
         }
         return httpRespMsg;
     }
@@ -92,8 +174,10 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             httpRespMsg.data = resultMap;
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
+            return httpRespMsg;
         } catch (DateTimeParseException e) {
             httpRespMsg.setError("日期格式有误");
+            return httpRespMsg;
         }
         return httpRespMsg;
     }

+ 11 - 10
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ScreenshotServiceImpl.java

@@ -51,7 +51,7 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
     public static Logger log = Logger.getLogger(ScreenshotServiceImpl.class);
 
     //检测时间间隔秒数
-    private static Long DETECTION_INTERVAL = 600L;
+    private static Integer DETECTION_INTERVAL = 600;
 
     @Value(value = "${upload.path}")
     private String path;
@@ -82,7 +82,8 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
         //获取每一个人最后一张截图
         try {
             List<Map<String, Object>> resultMap = screenshotMapper
-                    .getLatestScreenshotList(userMapper.selectById(request.getHeader("Token")).getCompanyId());
+                    .getLatestScreenshotList(userMapper.selectById(request.getHeader("Token")).getCompanyId(),
+                            LocalDate.now(ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
             for (Map<String, Object> map : resultMap) {
                 //对于每一张图 将时间戳转换为时间
                 map.put("time", new SimpleDateFormat("HH:mm:ss").format(map.get("indate")));
@@ -203,7 +204,7 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
             try {
                 String browserName = isBrowser(new File(filePath));
                 System.out.println(
-                        "找到浏览器=="+browserName
+                        "找到浏览器==" + browserName
                 );
                 if (browserName != null) {
                     screenshot.setPicType(1);
@@ -300,7 +301,7 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
         try {
             browserName = isBrowser(new File("C://Users/seya/Desktop/chrome.jpg"));
             System.out.println(
-                    "找到浏览器=="+browserName
+                    "找到浏览器==" + browserName
             );
         } catch (Exception e) {
             e.printStackTrace();
@@ -465,9 +466,9 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
                 //如果是连续的话那就准备修改上一条记录的最后时间和持续时间
                 LocalTime startTime = latestRecord.getStartTime();
                 //计算新的间隔
-                Double duration = (double) ((currentTime.getHour() - startTime.getHour()) * 3600
+                Integer duration = ((currentTime.getHour() - startTime.getHour()) * 3600
                         + (currentTime.getMinute() - startTime.getMinute()) * 60
-                        + (currentTime.getSecond() - startTime.getSecond())) / 3600;
+                        + (currentTime.getSecond() - startTime.getSecond()));
                 //设置新的结束时间和持续时间 保存记录
                 latestRecord.setEndTime(currentTime).setDuration(duration);
                 timeCalculationMapper.updateById(latestRecord);
@@ -482,14 +483,14 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
                         //设置开始时间和结束时间都为当前时间
                         .setStartTime(currentTime)
                         .setEndTime(currentTime)
-                        //第一次的持续时间默认为最短的一次间隔 以后为开始时间和结束时间只差 以防看一眼不计入时间的现象
-                        .setDuration(0.0);
+                        //第一次的持续时间默认为最少单位1秒 不然我看一眼就成了0秒了
+                        .setDuration(1);
                 timeCalculationMapper.insert(timeCalculation);
             }
             /*之后可能还需要处理跨越一天的情况*/
         } catch (NullPointerException e) {
             //凡是有空指针说明缺少用户id或者时间数据
-            log.info("=====工作时长统计失败 缺少用户或时间数据=====");
+            log.info("工作时长统计失败 缺少用户或时间数据");
         }
     }
 
@@ -508,7 +509,7 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
                 File[] targetFile = subFolder.listFiles();
                 boolean isMatch = false;
                 for (File targetPic : targetFile) {
-                    System.out.println("targetPic=="+targetPic.getAbsolutePath());
+                    System.out.println("targetPic==" + targetPic.getAbsolutePath());
                     boolean matchPic = ImageReconizeUtil.isTemplateMatch(pic.getAbsolutePath(), targetPic.getAbsolutePath());
                     if (matchPic) {
                         isMatch = true;

+ 46 - 13
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TimeCalculationServiceImpl.java

@@ -13,7 +13,6 @@ import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import java.time.LocalDate;
-import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
@@ -47,13 +46,13 @@ public class TimeCalculationServiceImpl extends ServiceImpl<TimeCalculationMappe
         LocalDate todayDate = LocalDate.now(ZoneOffset.of("+8"));
         resultMap.put("date", todayDate);
         //时间占比 预先定义好长度为9的数组再向里面添加
-        Double[] doubleArray = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+        Integer[] timeArray = {0, 0, 0, 0, 0, 0, 0, 0, 0};
         for (TimeCalculation timeCalculation : timeCalculationMapper.selectList(new QueryWrapper<TimeCalculation>()
                 .eq("user_id", userId)
                 .eq("date", todayDate))) {
-            doubleArray[timeCalculation.getActionType()] += timeCalculation.getDuration();
+            timeArray[timeCalculation.getActionType()] += timeCalculation.getDuration();
         }
-        resultMap.put("timeDistribution", doubleArray);
+        resultMap.put("timeDistribution", timeArray);
         httpRespMsg.data = resultMap;
         return httpRespMsg;
     }
@@ -74,6 +73,7 @@ public class TimeCalculationServiceImpl extends ServiceImpl<TimeCalculationMappe
             httpRespMsg.data = resultMap;
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
+            return httpRespMsg;
         }
         return httpRespMsg;
     }
@@ -92,23 +92,28 @@ public class TimeCalculationServiceImpl extends ServiceImpl<TimeCalculationMappe
                 map.put("name", userMap.get("name"));
                 map.put("phone", userMap.get("phone"));
                 //然后根据日期和用户id获取到所有的记录 然后手动累加在一起
-                Double[] doubleArray = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+                Long[] timeArray = {0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L};
+                String[] stringArray = new String[9];
                 for (Map<String, Object> dataMap : timeCalculationMapper
                         .getTodayStatistics((String) userMap.get("id"), date, companyId)) {
-                    doubleArray[(int) dataMap.get("type")] += (Double) dataMap.get("duration");
+                    timeArray[(int) dataMap.get("type")] += (Long) dataMap.get("duration");
                 }
-                map.put("statistics", doubleArray);
+                for (int i = 0; i < 9; i++) {
+                    stringArray[i] = convertSecond(timeArray[i]);
+                }
+                map.put("statistics", stringArray);
                 //最后是数组的和
-                Double sum = 0.0;
-                for (Double singleNumber : doubleArray) {
+                Long sum = 0L;
+                for (Long singleNumber : timeArray) {
                     sum += singleNumber;
                 }
-                map.put("sum", sum);
+                map.put("sum", convertSecond(sum));
                 resultList.add(map);
             }
             httpRespMsg.data = resultList;
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
+            return httpRespMsg;
         }
         return httpRespMsg;
     }
@@ -134,6 +139,7 @@ public class TimeCalculationServiceImpl extends ServiceImpl<TimeCalculationMappe
             }
             List<Map<String, Object>> resultList = new ArrayList<>();
             for (String date : dateList) {
+                Integer total = 0;
                 Map<String, Object> dataMap = new HashMap<>();
                 dataMap.put("date", date);
                 List<Map<String, Object>> list = new ArrayList<>();
@@ -142,19 +148,46 @@ public class TimeCalculationServiceImpl extends ServiceImpl<TimeCalculationMappe
                         Map<String, Object> map = new HashMap<>();
                         map.put("startTime", timeCalculation.getStartTime().format(DateTimeFormatter.ofPattern("HH:mm")));
                         map.put("endTime", timeCalculation.getEndTime().format(DateTimeFormatter.ofPattern("HH:mm")));
-                        map.put("duration", timeCalculation.getDuration());
+                        Integer todayTime = timeCalculation.getDuration();
+                        map.put("duration", convertSecond(todayTime));
+                        total += todayTime;
                         list.add(map);
                     }
                 }
                 dataMap.put("time", list);
+                //这里检查如果只有一天记录的话那就再多计算一个当天总工作时间
+                if (dateList.size() == 1) {
+                    dataMap.put("total", total);
+                }
                 resultList.add(dataMap);
             }
             httpRespMsg.data = resultList;
-        } catch (NullPointerException e) {
-            httpRespMsg.setError("验证失败");
         } catch (DateTimeParseException e) {
             httpRespMsg.setError("日期格式有误");
+            return httpRespMsg;
+        } catch (NullPointerException e) {
+            httpRespMsg.setError("验证失败");
+            return httpRespMsg;
         }
         return httpRespMsg;
     }
+
+    //秒数转化为时间字符串
+    private static String convertSecond(Integer time) {
+        Integer hour = 0, minute = 0, second = 0;
+        hour = time / 3600;
+        time = time % 3600;
+        minute = time / 60;
+        second = minute % 60;
+        return hour + "小时" + minute + "分" + second + "秒";
+    }
+
+    private static String convertSecond(Long time) {
+        Long hour = 0L, minute = 0L, second = 0L;
+        hour = time / 3600;
+        time = time % 3600;
+        minute = time / 60;
+        second = minute % 60;
+        return hour + "小时" + minute + "分" + second + "秒";
+    }
 }

+ 109 - 6
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java

@@ -11,15 +11,19 @@ import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MD5Util;
 import com.management.platform.util.SnowFlake;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.*;
+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.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
-import java.io.FileInputStream;
-import java.io.IOException;
+import java.io.*;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -104,6 +108,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
                     .eq("company_id", userMapper.selectById(request.getHeader("Token")).getCompanyId()));
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
+            return httpRespMsg;
         }
         return httpRespMsg;
     }
@@ -119,7 +124,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
             if (target == null) {
                 httpRespMsg.setError("未找到用户");
             } else {
-                if (!requester.getCompanyId().equals(target.getRole())) {
+                if (!requester.getCompanyId().equals(target.getCompanyId())) {
                     httpRespMsg.setError("只能删除同一公司人员的账号");
                 } else if (target.getRole() == 2) {
                     httpRespMsg.setError("负责人账号不可删除");
@@ -131,6 +136,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
             }
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
+            return httpRespMsg;
         }
         return httpRespMsg;
     }
@@ -150,6 +156,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
             }
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
+            return httpRespMsg;
         }
         return httpRespMsg;
     }
@@ -214,15 +221,111 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
             }
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
+            return httpRespMsg;
         }
         return httpRespMsg;
     }
 
     //导入用户
     @Override
-    public HttpRespMsg importUser(MultipartFile file, HttpServletRequest request) {
+    public HttpRespMsg importUser(MultipartFile multipartFile, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
-        httpRespMsg.setError("现在不能导入");
+        try {
+            //首先先搞到公司id
+            Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
+            //然后处理文件
+            String fileName = multipartFile.getOriginalFilename();
+            File file = new File(fileName == null ? "file" : fileName);
+            InputStream inputStream = multipartFile.getInputStream();
+            OutputStream 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);
+            //我们只需要第一个sheet
+            XSSFSheet sheet = workbook.getSheetAt(0);
+            //查重检验的手机号列表
+            List<String> phoneList = new ArrayList<>();
+            //要插入的账号列表
+            List<User> userList = new ArrayList<>();
+            for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
+                XSSFRow row = sheet.getRow(rowIndex);
+                if (row == null) {
+                    continue;
+                }
+                //此处新建账号 默认密码为000000 默认 姓名第一列 手机号第二列
+                Long id = SnowFlake.nextId();
+                XSSFCell nameCell = row.getCell(0);
+                XSSFCell phoneCell = row.getCell(1);
+                nameCell.setCellType(CellType.STRING);
+                phoneCell.setCellType(CellType.STRING);
+                String name = nameCell.getStringCellValue();
+                String phone = phoneCell.getStringCellValue();
+                phoneList.add(phone);
+                userList.add(new User()
+                        .setId(id.toString())
+                        .setName(name)
+                        .setPassword(MD5Util.getPassword("000000"))
+                        .setPhone(phone)
+                        .setRole(0)
+                        .setCompanyId(companyId));
+            }
+            //最后删掉这个文件
+            if (!file.delete()) {
+                System.out.println("临时文件" + file.getName() + "删除失败");
+            }
+            //校验是否有重复账号
+            if (userMapper.selectCount(new QueryWrapper<User>().in("phone", phoneList)) == 0) {
+                for (User user : userList) {
+                    userMapper.insert(user);
+                }
+            } else {
+                httpRespMsg.setError("手机号有重复 批量新建账号失败");
+                /*这里以后可能需要返回重复的手机号的具体信息*/
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            httpRespMsg.setError("文件处理出错");
+            return httpRespMsg;
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+            httpRespMsg.setError("数据格式有误或存在空数据 导出失败");
+            return httpRespMsg;
+        } catch (Exception e) {
+            e.printStackTrace();
+            httpRespMsg.setError("发生其他错误");
+            return httpRespMsg;
+        }
+        return httpRespMsg;
+    }
+
+    //切换权限状态
+    @Override
+    public HttpRespMsg switchPermission(String id, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            User requester = userMapper.selectById(request.getHeader("Token")),
+                    target = userMapper.selectById(id);
+            //管理员只能新增员工
+            if (requester.getRole() != 1) {
+                httpRespMsg.setError("仅负责人有权限更改其他人员权限");
+            } else if (!target.getCompanyId().equals(requester.getCompanyId())) {
+                httpRespMsg.setError("只可修改同一公司人员的权限");
+            } else if (target.getRole() == 1) {
+                httpRespMsg.setError("不可修改负责人的权限");
+            } else {
+                target.setRole(target.getRole() == 0 ? 2 : 0);
+                userMapper.updateById(target);
+            }
+        } catch (NullPointerException e) {
+            httpRespMsg.setError("缺少数据 未查询到相应人员信息");
+            return httpRespMsg;
+        }
         return httpRespMsg;
     }
 }

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

@@ -18,6 +18,20 @@
         id, creator_id, project_id, create_date, working_time, content, create_time
     </sql>
 
+    <!--根据日期获取全部报告信息-->
+    <select id="getAllReportByDate" resultType="java.util.Map">
+        SELECT c.name, b.project_name AS project, a.working_time AS duration, a.content, a.create_time AS time
+        FROM report AS a
+        JOIN project AS b ON a.project_id=b.id
+        LEFT JOIN user AS c ON a.creator_id=c.id
+        WHERE 1=1
+        <if test="date != null and date != ''">
+            AND a.create_date=#{date}
+        </if>
+        AND a.creator_id=#{id}
+        ORDER BY a.creator_id ASC
+    </select>
+
     <!--根据日期获取报告信息-->
     <select id="getReportByDate" resultType="java.util.Map">
         SELECT b.project_name AS project, a.working_time AS time, a.content
@@ -28,7 +42,7 @@
             AND a.create_date=#{date}
         </if>
         AND a.creator_id=#{id}
-        ORDER BY a.project_id ASC
+        ORDER BY a.creator_id ASC
     </select>
 
     <!--根据日期获取报告上传人-->

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ScreenshotMapper.xml

@@ -36,6 +36,9 @@
         <if test="companyId != null and companyId != ''">
             AND c.company_id=#{companyId}
         </if>
+        <if test="date != null and date != ''">
+            AND a.date_str=#{date}
+        </if>
     </select>
 
 </mapper>

+ 13 - 8
fhKeeper/formulahousekeeper/timesheet/src/http.js

@@ -36,7 +36,7 @@ export default {
      * @param exception 异常的回调函数
      */
     post (url, data, response, exception) {
-        var user = sessionStorage.getItem('user') , token = "";
+        let user = sessionStorage.getItem('user') , token = "";
         if(user != null){
             token = JSON.parse(user).id
             // data.token = token
@@ -72,15 +72,17 @@ export default {
      * @param exception 异常的回调函数
      */
     get (url , response, exception) {
-        var user = sessionStorage.getItem('user') , token = "";
+        let user = sessionStorage.getItem('user') , token = "";
         if(user != null){
-            token = JSON.parse(user).headImgurl
+            token = JSON.parse(user).id
+            // data.token = token
         }
         axios({
             method: 'get',
             url: handleUrl(url),
             headers: {
-                'Content-Type': 'application/json; charset=UTF-8'
+                'Content-Type': 'application/json; charset=UTF-8',
+                'Token': token
             }
         }).then(
             (result) => {
@@ -104,10 +106,10 @@ export default {
      * @param exception 异常的回调函数
      */
     uploadFile (url, data, response, exception) {
-        var user = sessionStorage.getItem('user') , token = "";
+        let user = sessionStorage.getItem('user') , token = "";
         if(user != null){
-            token = JSON.parse(user).headImgurl
-            data.append("token", token);
+            token = JSON.parse(user).id
+            // data.token = token
         }
         axios({
             method: 'post',
@@ -115,7 +117,10 @@ export default {
             data: handleParams(data),
             dataType: 'json',
             processData: false,
-            contentType: false
+            contentType: false,
+            headers: {
+                'Token': token
+            }
         }).then(
             (result) => {
                 response(handleResults(result, data))

+ 3 - 5
fhKeeper/formulahousekeeper/timesheet/src/port.js

@@ -1,13 +1,11 @@
 export default {
-    test:{
-      test1:'/time-calculation/getDuration'
-    },
-
-
     manage: {
         login: '/user/loginAdmin', // 登录
         list: '/user/getEmployeeList', //获取员工列表
         delete: '/user/deleteUser', //删除用户
+        insert: '/user/insertUser', //单独新增用户
+        import: '/user/importUser', //批量导入用户
+        permission: '/user/switchPermission', //切换权限
     },
 
     //时间

+ 10 - 10
fhKeeper/formulahousekeeper/timesheet/src/routes.js

@@ -60,16 +60,16 @@ let routes = [
         ]
     },
     //系统管理
-    {
-        path: '/',
-        component: Home,
-        name: '',
-        iconCls: 'fa fa-cog',
-        leaf: true,//只有一个节点
-        children: [
-            { path: '/system', component: system, name: '系统管理' },
-        ]
-    },
+    // {
+    //     path: '/',
+    //     component: Home,
+    //     name: '',
+    //     iconCls: 'fa fa-cog',
+    //     leaf: true,//只有一个节点
+    //     children: [
+    //         { path: '/system', component: system, name: '系统管理' },
+    //     ]
+    // },
     {
         path: '/404',
         component: NotFound,

+ 26 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/desktop/index.vue

@@ -28,7 +28,7 @@
             <!-- pic_type 这里需要一个巨长的三目运算符 -->
             <!-- 0-编程,1-查资料,2-看文档,3-做设计,4-美工,5-运营,6-看小说,7-打游戏,8-听音乐 -->
             <!-- 现在基本都是null -->
-            <span>{{item.pic_type == null ? 0 : item.pic_type}}</span>
+            <span>{{converType(item.pic_type == null ? 0 : item.pic_type)}}</span>
             <div class="bottom clearfix">
               <el-link>
                 <i class="fa fa-circle"></i>
@@ -98,6 +98,31 @@ export default {
     },
     jumpTo(id) {
       this.$router.push("/desktop/" + id);
+    },
+    //类型枚举转换
+    converType(type) {
+      switch (type) {
+        case 0:
+          return "编程";
+        case 1:
+          return "查资料";
+        case 2:
+          return "看文档";
+        case 3:
+          return "做设计";
+        case 4:
+          return "美工";
+        case 5:
+          return "运营";
+        case 6:
+          return "看小说";
+        case 7:
+          return "打游戏";
+        case 8:
+          return "听音乐";
+        default:
+          return "未知";
+      }
     }
   },
   created() {

+ 29 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/desktop/unusual.vue

@@ -15,7 +15,9 @@
     >
       <el-table-column type="index" width="60"></el-table-column>
       <el-table-column prop="name" label="姓名" width="140" sortable></el-table-column>
-      <el-table-column prop="type" label="行为"></el-table-column>
+      <el-table-column label="行为">
+        <template slot-scope="scope">{{converType(scope.row.type)}}</template>
+      </el-table-column>
       <el-table-column prop="time" label="时间" width="180" sortable></el-table-column>
       <el-table-column prop="date" label="日期" width="180" sortable></el-table-column>
     </el-table>
@@ -87,6 +89,32 @@ export default {
     handleSizeChange(val) {
       this.size = val;
       this.getDevianceList();
+    },
+
+    //类型枚举转换
+    converType(type) {
+      switch (type) {
+        case 0:
+          return "编程";
+        case 1:
+          return "查资料";
+        case 2:
+          return "看文档";
+        case 3:
+          return "做设计";
+        case 4:
+          return "美工";
+        case 5:
+          return "运营";
+        case 6:
+          return "看小说";
+        case 7:
+          return "打游戏";
+        case 8:
+          return "听音乐";
+        default:
+          return "未知";
+      }
     }
   },
   created() {

+ 1 - 31
fhKeeper/formulahousekeeper/timesheet/src/views/system/index.vue

@@ -208,34 +208,6 @@ export default {
           });
         }
       );
-    },
-    //测试用的 没事就删掉吧
-    getTest() {
-      this.listLoading = true;
-      this.http.post(
-        this.port.test.test1,
-        {
-          startDate: "2020-01-01",
-          endDate: "2020-01-15"
-        },
-        res => {
-          this.listLoading = false;
-          if (res.code == "ok") {
-          } else {
-            this.$message({
-              message: res.msg,
-              type: "error"
-            });
-          }
-        },
-        error => {
-          this.listLoading = false;
-          this.$message({
-            message: error,
-            type: "error"
-          });
-        }
-      );
     }
   },
   created() {
@@ -246,9 +218,7 @@ export default {
       that.tableHeight = window.innerHeight - 195;
     };
   },
-  mounted() {
-    this.getTest();
-  }
+  mounted() {}
 };
 </script>
 

+ 181 - 5
fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue

@@ -4,10 +4,18 @@
     <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
       <el-form :inline="true">
         <el-form-item style="float:right;">
-          <el-link type="primary" :underline="false">添加人员</el-link>
+          <el-link type="primary" :underline="false" @click="openInsertDialog">添加人员</el-link>
         </el-form-item>
         <el-form-item style="float:right;">
-          <el-link type="primary" :underline="false">批量导入</el-link>
+          <el-upload
+            ref="upload"
+            action="#"
+            :limit="1"
+            :http-request="importUser"
+            :show-file-list="false"
+          >
+            <el-link type="primary" :underline="false">批量导入</el-link>
+          </el-upload>
         </el-form-item>
       </el-form>
     </el-col>
@@ -23,15 +31,31 @@
       <el-table-column type="index" width="60"></el-table-column>
       <el-table-column prop="name" label="姓名" sortable></el-table-column>
       <el-table-column prop="phone" label="手机"></el-table-column>
+      <el-table-column label="角色">
+        <template slot-scope="scope">
+          {{scope.row.role == 0 ? "普通员工" :
+          scope.row.role == 1 ? "负责人" : "管理员"}}
+        </template>
+      </el-table-column>
       <el-table-column label="操作">
         <template slot-scope="scope">
+          <el-button
+            size="small"
+            v-if="scope.row.role == 0 && user.role == 1"
+            @click="switchRole(scope.$index)"
+          >切换为管理员</el-button>
+          <el-button
+            size="small"
+            v-if="scope.row.role == 2 && user.role == 1"
+            @click="switchRole(scope.$index)"
+          >切换为员工</el-button>
           <el-button size="small" type="danger" @click="deleteUser(scope.$index)">删除</el-button>
         </template>
       </el-table-column>
     </el-table>
 
     <!--工具条-->
-    <el-col :span="24" class="toolbar">
+    <!-- <el-col :span="24" class="toolbar">
       <el-pagination
         @size-change="handleSizeChange"
         @current-change="handleCurrentChange"
@@ -41,7 +65,29 @@
         :total="total"
         style="float:right;"
       ></el-pagination>
-    </el-col>
+    </el-col>-->
+
+    <!-- 新增单个人员的Dialog -->
+    <el-dialog title="新增人员" :visible.sync="dialogVisible" width="400px">
+      <el-form ref="form1" :model="insertForm" :rules="rules" label-width="60px">
+        <el-form-item label="名字" prop="name">
+          <el-input v-model="insertForm.name" placeholder="请输入姓名" clearable></el-input>
+        </el-form-item>
+        <el-form-item label="电话" prop="phone">
+          <el-input v-model="insertForm.phone" placeholder="请输入电话" clearable></el-input>
+        </el-form-item>
+        <el-form-item label="角色" prop="role">
+          <el-select v-model="insertForm.role" placeholder="请选择角色" style="width: 100%">
+            <el-option label="普通员工" :value="0"></el-option>
+            <el-option label="管理员" :value="2"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible=false">取消</el-button>
+        <el-button type="primary" @click="submitInsert">提交</el-button>
+      </span>
+    </el-dialog>
   </section>
 </template>
 
@@ -56,7 +102,18 @@ export default {
       total: 0,
       page: 1,
       size: 20,
-      list: []
+      list: [],
+      dialogVisible: false,
+      insertForm: {
+        name: null,
+        phone: null,
+        role: null
+      },
+      rules: {
+        name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
+        phone: [{ required: true, message: "请输入电话", trigger: "blur" }],
+        role: [{ required: true, message: "请选择角色", trigger: "blur" }]
+      }
     };
   },
   methods: {
@@ -98,6 +155,117 @@ export default {
       );
     },
 
+    //新增员工
+    submitInsert() {
+      this.$refs.form1.validate(valid => {
+        if (valid) {
+          this.listLoading = true;
+          this.http.post(
+            this.port.manage.insert,
+            {
+              name: this.insertForm.name,
+              phone: this.insertForm.phone,
+              role: this.insertForm.role
+            },
+            res => {
+              this.listLoading = false;
+              if (res.code == "ok") {
+                this.dialogVisible = false;
+                //重新读取列表
+                this.getUser();
+              } else {
+                this.$message({
+                  message: res.msg,
+                  type: "error"
+                });
+              }
+            },
+            error => {
+              this.listLoading = false;
+              this.$message({
+                message: error,
+                type: "error"
+              });
+            }
+          );
+        }
+      });
+    },
+
+    //获取所有员工的列表
+    importUser(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);
+        this.http.uploadFile(
+          this.port.manage.import,
+          formData,
+          res => {
+            this.$refs.upload.clearFiles();
+            this.listLoading = false;
+            if (res.code == "ok") {
+              //重新读取列表
+              this.getUser();
+            } else {
+              this.$message({
+                message: res.msg,
+                type: "error"
+              });
+            }
+          },
+          error => {
+            this.$refs.upload.clearFiles();
+            this.listLoading = false;
+            this.$message({
+              message: error,
+              type: "error"
+            });
+          }
+        );
+      }
+    },
+
+    //切换角色 0/2
+    switchRole(index) {
+      this.listLoading = true;
+      this.http.post(
+        this.port.manage.permission,
+        { id: this.list[index].id },
+        res => {
+          this.listLoading = false;
+          if (res.code == "ok") {
+            this.$message({
+              message: "切换角色成功",
+              type: "success"
+            });
+            //重新读取列表
+            this.getUser();
+          } else {
+            this.$message({
+              message: res.msg,
+              type: "error"
+            });
+          }
+        },
+        error => {
+          this.listLoading = false;
+          this.$message({
+            message: error,
+            type: "error"
+          });
+        }
+      );
+    },
+
     //三天之内删了你 数据库都给你清了
     deleteUser(index) {
       this.$confirm(
@@ -140,6 +308,14 @@ export default {
           );
         })
         .catch(() => {});
+    },
+
+    //打开单独新增的Dialog
+    openInsertDialog() {
+      this.insertForm.name = null;
+      this.insertForm.phone = null;
+      this.insertForm.role = null;
+      this.dialogVisible = true;
     }
   },
 

+ 2 - 2
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/statistics.vue

@@ -15,9 +15,9 @@
             placeholder="选择日期"
           ></el-date-picker>
         </el-form-item>
-        <el-form-item style="float:right;">
+        <!-- <el-form-item style="float:right;">
           <el-link type="primary" :underline="false" @click="handleAdd">异常申请</el-link>
-        </el-form-item>
+        </el-form-item> -->
       </el-form>
     </el-col>