Преглед на файлове

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

wutt преди 5 години
родител
ревизия
f3e12b099c
променени са 17 файла, в които са добавени 552 реда и са изтрити 219 реда
  1. BIN
      fhKeeper/formulahousekeeper/management-platform/opencv/opencv-420.jar
  2. BIN
      fhKeeper/formulahousekeeper/management-platform/opencv/x64/opencv_java420.dll
  3. BIN
      fhKeeper/formulahousekeeper/management-platform/opencv/x86/opencv_java420.dll
  4. 33 9
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  5. 0 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java
  6. 3 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeCalculation.java
  7. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  8. 16 12
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  9. 65 7
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ScreenshotServiceImpl.java
  10. 57 12
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TimeCalculationServiceImpl.java
  11. 120 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/ImageReconizeUtil.java
  12. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  13. 5 1
      fhKeeper/formulahousekeeper/mywork/home.cpp
  14. 7 0
      fhKeeper/formulahousekeeper/mywork/mainwindow.cpp
  15. 1 0
      fhKeeper/formulahousekeeper/mywork/mainwindow.h
  16. 5 0
      fhKeeper/formulahousekeeper/timesheet/src/port.js
  17. 236 172
      fhKeeper/formulahousekeeper/timesheet/src/views/system/index.vue

BIN
fhKeeper/formulahousekeeper/management-platform/opencv/opencv-420.jar


BIN
fhKeeper/formulahousekeeper/management-platform/opencv/x64/opencv_java420.dll


BIN
fhKeeper/formulahousekeeper/management-platform/opencv/x86/opencv_java420.dll


+ 33 - 9
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -11,6 +11,10 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * <p>
@@ -46,19 +50,39 @@ public class ReportController {
         return reportService.getReport(date, request);
     }
 
-
     /**
      * 新增或编辑报告
-     * id 报告id 编辑时传
-     * creatorId 报告上传者id 新增时不可为空
-     * projectId 报告相关项目id 新增时不可为空
-     * createDate 报告创建时间 新增时不可为空 yyyy-MM-dd
-     * workingTime 工作时间
-     * content 工作内容
+     * id 报告id 数组
+     * projectId 报告相关项目id 数组
+     * workingTime 工作时间 数组
+     * content 工作内容 数组
+     * createDate 报告日期 数组
      */
     @RequestMapping("/editReport")
-    public HttpRespMsg editReport(Report report) {
-        return reportService.editReport(report);
+    public HttpRespMsg editReport(Integer[] id, Integer[] projectId, Double[] workingTime, String[] content,
+                                  String[] createDate) {
+        List<Report> reportList = new ArrayList<>();
+        try {
+            for (int i = 0; i < id.length; i++) {
+                reportList.add(new Report()
+                        .setId(id[i] == -1 ? null : id[i])
+                        .setProjectId(projectId[i])
+                        .setWorkingTime(workingTime[i])
+                        .setContent(content[i])
+                        .setCreateDate(LocalDate.parse(createDate[i], DateTimeFormatter.ofPattern("yyyy-MM-dd")))
+                        .setCreatorId(request.getHeader("Token")));
+                if (createDate[i] == null || projectId[i] == null) {
+                    HttpRespMsg httpRespMsg = new HttpRespMsg();
+                    httpRespMsg.setError("缺少数据");
+                    return httpRespMsg;
+                }
+            }
+        } catch (NullPointerException e) {
+            HttpRespMsg httpRespMsg = new HttpRespMsg();
+            httpRespMsg.setError("缺少数据");
+            return httpRespMsg;
+        }
+        return reportService.editReport(reportList);
     }
 
     /**

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

@@ -45,8 +45,6 @@ public class UserController {
      */
     @RequestMapping("/loginEmployee")
     public HttpRespMsg loginEmployee(@RequestParam String username, @RequestParam String password) {
-        String property = System.getProperty("java.io.tmpdir");
-        System.out.println("tomcat临时目录==" + property);
         return userService.loginEmployee(username, password);
     }
 

+ 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 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.management.platform.util.HttpRespMsg;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 
 /**
  * <p>
@@ -19,7 +20,7 @@ public interface ReportService extends IService<Report> {
 
     HttpRespMsg getReport(String date, HttpServletRequest request);
 
-    HttpRespMsg editReport(Report report);
+    HttpRespMsg editReport(List<Report> reportList);
 
     HttpRespMsg deleteReport(Integer reportId);
 }

+ 16 - 12
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -2,8 +2,10 @@ package com.management.platform.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.management.platform.entity.Project;
 import com.management.platform.entity.Report;
 import com.management.platform.entity.TimeCalculation;
+import com.management.platform.mapper.ProjectMapper;
 import com.management.platform.mapper.ReportMapper;
 import com.management.platform.mapper.TimeCalculationMapper;
 import com.management.platform.mapper.UserMapper;
@@ -42,6 +44,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     private UserMapper userMapper;
     @Resource
     private TimeCalculationMapper timeCalculationMapper;
+    @Resource
+    private ProjectMapper projectMapper;
 
     //获取报告列表
     @Override
@@ -67,11 +71,12 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     public HttpRespMsg getReport(String date, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
-            String userId = userMapper.selectById(request.getHeader("Token")).getId();
+            String userId = request.getHeader("Token");
             Map<String, Object> resultMap = new HashMap<>();
             //获取某日本人的所有日志
             resultMap.put("report", reportMapper.selectList(new QueryWrapper<Report>()
-                    .eq("user_id", userId)));
+                    .eq("creator_id", userId)
+                    .eq("create_date", LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")))));
             //顺便再获取一下可分配时间
             Double totalWorkingTime = 0.0;
             //此处认为0是工作时间
@@ -82,6 +87,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 totalWorkingTime += timeCalculation.getDuration();
             }
             resultMap.put("time", totalWorkingTime);
+            resultMap.put("project", projectMapper.selectList(new QueryWrapper<Project>()
+                    .eq("company_id", userMapper.selectById(userId).getCompanyId())));
             httpRespMsg.data = resultMap;
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
@@ -93,20 +100,17 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
     //新增或编辑报告
     @Override
-    public HttpRespMsg editReport(Report report) {
+    public HttpRespMsg editReport(List<Report> reportList) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
-        if (report.getId() == null) {
-            //新增报告时 需要检查项目和人员id
-            if (report.getCreatorId() == null || report.getProjectId() == null) {
-                httpRespMsg.setError("请填写完整信息");
-            } else {
+        for (Report report : reportList) {
+            if (report.getId() == null) {
                 if (reportMapper.insert(report) == 0) {
                     httpRespMsg.setError("操作失败");
                 }
-            }
-        } else {
-            if (reportMapper.updateById(report) == 0) {
-                httpRespMsg.setError("操作失败");
+            } else {
+                if (reportMapper.updateById(report) == 0) {
+                    httpRespMsg.setError("操作失败");
+                }
             }
         }
         return httpRespMsg;

+ 65 - 7
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ScreenshotServiceImpl.java

@@ -55,6 +55,9 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
 
     @Value(value = "${upload.path}")
     private String path;
+    @Value(value = "${picrecongnize.path}")
+    private static String picrecongnizeFolder;
+
     @Value("classpath:novel_words.data")
     private org.springframework.core.io.Resource novelWords;
     @Autowired
@@ -194,6 +197,21 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
                 screenshot.setPicType(7);
             }
         }
+        if (screenshot.getPicType() == null) {
+            //默认设置为查资料
+            try {
+                String browserName = isBrowser(new File(filePath));
+                System.out.println(
+                        "找到浏览器=="+browserName
+                );
+                if (browserName != null) {
+                    screenshot.setPicType(1);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+        }
         //将获取到的截图进行时间计算
         calculateTime(screenshot);
         screenshotMapper.insert(screenshot);
@@ -274,9 +292,19 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
     public static void main(String[] args) {
 //        boolean find = matchCategory("第22 重生");
 //        System.out.println(find);
-        String str = "中文";
-        System.out.println(str.toCharArray().length);
-        isEntertainment(new File("C://Users/seya/Desktop/1.jpg"));
+//        String str = "中文";
+//        System.out.println(str.toCharArray().length);
+//        isEntertainment(new File("C://Users/seya/Desktop/1.jpg"));
+        String browserName = null;
+        try {
+            browserName = isBrowser(new File("C://Users/seya/Desktop/360.jpg"));
+            System.out.println(
+                    "找到浏览器=="+browserName
+            );
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
     }
 
     //娱乐类: 电影+游戏; 画面比较丰富的
@@ -436,9 +464,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);
@@ -453,8 +481,8 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
                         //设置开始时间和结束时间都为当前时间
                         .setStartTime(currentTime)
                         .setEndTime(currentTime)
-                        //第一次的持续时间默认为最短的一次间隔 以后为开始时间和结束时间只差 以防看一眼不计入时间的现象
-                        .setDuration(0.0);
+                        //第一次的持续时间默认为最少单位1秒 不然我看一眼就成了0秒了
+                        .setDuration(1);
                 timeCalculationMapper.insert(timeCalculation);
             }
             /*之后可能还需要处理跨越一天的情况*/
@@ -463,4 +491,34 @@ public class ScreenshotServiceImpl extends ServiceImpl<ScreenshotMapper, Screens
             log.info("=====工作时长统计失败 缺少用户或时间数据=====");
         }
     }
+
+    //判断是否是浏览器
+    private static String isBrowser(File pic) throws Exception {
+        if (picrecongnizeFolder == null) {
+            picrecongnizeFolder = "C:\\picrecongnize";
+        }
+        File folder = new File(picrecongnizeFolder);
+        if (!folder.exists()) {
+            throw new Exception("没有设置图片上传的浏览器比对模板库");
+        } else {
+            File[] files = folder.listFiles();
+            String browserName = null;
+            for (File subFolder : files) {
+                File[] targetFile = subFolder.listFiles();
+                int matchCnt = 0;
+                for (File targetPic : targetFile) {
+                    System.out.println("targetPic=="+targetPic.getAbsolutePath());
+                    boolean matchPic = ImageReconizeUtil.isTemplateMatch(pic.getAbsolutePath(), targetPic.getAbsolutePath());
+                    if (matchPic) {
+                        matchCnt++;
+                    }
+                }
+                if (matchCnt >=4) {
+                    browserName = subFolder.getName();
+                    break;
+                }
+            }
+            return browserName;
+        }
+    }
 }

+ 57 - 12
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TimeCalculationServiceImpl.java

@@ -13,6 +13,7 @@ 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;
@@ -46,13 +47,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;
     }
@@ -91,15 +92,15 @@ 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};
+                Integer[] timeArray = {0, 0, 0, 0, 0, 0, 0, 0, 0};
                 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")] += (int) dataMap.get("duration");
                 }
-                map.put("statistics", doubleArray);
+                map.put("statistics", timeArray);
                 //最后是数组的和
-                Double sum = 0.0;
-                for (Double singleNumber : doubleArray) {
+                Integer sum = 0;
+                for (Integer singleNumber : timeArray) {
                     sum += singleNumber;
                 }
                 map.put("sum", sum);
@@ -117,11 +118,45 @@ public class TimeCalculationServiceImpl extends ServiceImpl<TimeCalculationMappe
     public HttpRespMsg getDuration(String startDate, String endDate, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
-            httpRespMsg.data = timeCalculationMapper.selectList(new QueryWrapper<TimeCalculation>()
+            LocalDate start = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+            LocalDate end = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+            //首先获取数据
+            List<TimeCalculation> dataList = timeCalculationMapper.selectList(new QueryWrapper<TimeCalculation>()
                     .eq("user_id", request.getHeader("Token"))
-                    .between("date",
-                            LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")),
-                            LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
+                    .eq("action_type", 0)
+                    .between("date", start, end)
+                    .orderByAsc("start_time"));
+            //先把所有的日期搞到一个list里面
+            ArrayList<String> dateList = new ArrayList<>();
+            LocalDate currentDate = start;
+            for (int i = 0; !currentDate.equals(end.plusDays(1)) || ++i >= 100; currentDate = currentDate.plusDays(1)) {
+                dateList.add(currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+            }
+            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<>();
+                for (TimeCalculation timeCalculation : dataList) {
+                    if (timeCalculation.getDate().toString().equals(date)) {
+                        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")));
+                        Integer todayTime = timeCalculation.getDuration();
+                        map.put("duration", convertSecond(todayTime));
+                        total += todayTime;
+                        list.add(map);
+                    }
+                }
+                dataMap.put("time", list);
+                //这里检查如果只有一天记录的话那就再多计算一个当天总工作时间
+                if (resultList.size() == 1) {
+                    dataMap.put("total", convertSecond(total));
+                }
+                resultList.add(dataMap);
+            }
+            httpRespMsg.data = resultList;
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
         } catch (DateTimeParseException e) {
@@ -129,4 +164,14 @@ public class TimeCalculationServiceImpl extends ServiceImpl<TimeCalculationMappe
         }
         return httpRespMsg;
     }
+
+    //秒数转化为时间字符串
+    private 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 + "秒";
+    }
 }

+ 120 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/ImageReconizeUtil.java

@@ -0,0 +1,120 @@
+package com.management.platform.util;
+
+import org.opencv.core.*;
+import org.opencv.features2d.DescriptorMatcher;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.imgproc.Imgproc;
+
+import java.io.File;
+
+import static java.lang.Math.E;
+
+public class ImageReconizeUtil {
+    public static final double YUZHI = Math.pow(0.1, 10);
+    static {
+        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+        //注意程序运行的时候需要在VM option添加该行 指明opencv的dll文件所在路径
+        //-Djava.library.path=$PROJECT_DIR$\opencv\x64
+    }
+    public static void main(String[] args) {
+//        boolean match = isTemplateMatch("C:\\Users\\seya\\Desktop\\360_2.jpg",
+//                "C:\\picrecongnize\\360Safe\\2.jpg");
+        boolean match = isTemplateMatch("C:\\Users\\seya\\Desktop\\qyt_2.jpg",
+                "C:\\\\picrecongnize\\\\360Safe\\\\2.jpg");
+    }
+
+    public static boolean isTemplateMatch(String sourcePic, String targetPic) {
+        double matchVal = templete(Imgproc.TM_SQDIFF_NORMED, sourcePic, targetPic);
+        if (Math.abs(matchVal) < YUZHI) {
+            System.out.println("找到啦");
+            return true;
+        } else {
+            System.out.println("没匹配上");
+            return false;
+        }
+    }
+
+    /**
+     * OpenCV-4.1.0 模板匹配
+     * <table border="1" cellpadding="8">
+     * <tr><th>输入参数</th><th>参数解释</th></tr>
+     * <tr><td align="left">TM_SQDIFF是平方差匹配、TM_SQDIFF_NORMED是标准平方差匹配</td><td>利用平方差来进行匹配,最好匹配为0.匹配越差,匹配值越大。</td></tr>
+     * <tr><td align="left">TM_CCORR是相关性匹配、TM_CCORR_NORMED是标准相关性匹配</td><td>采用模板和图像间的乘法操作,数越大表示匹配程度较高, 0表示最坏的匹配效果。</td></tr>
+     * <tr><td align="left">TM_CCOEFF是相关性系数匹配、TM_CCOEFF_NORMED是标准相关性系数匹配</td><td>将模版对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,-1表示糟糕的匹配,0表示没有任何相关性(随机序列)。</td></tr>
+     * <tr><td colspan="2">随着从简单的测量(平方差)到更复杂的测量(相关系数),我们可获得越来越准确的匹配(同时也意味着越来越大的计算代价)。</td></tr>
+     * <tr><td colspan="2">相关性是越接近1越大越好,平方差是越小越好,所以TM_SQDIFF在使用时和其他的是有所区别的。</td></tr>
+     * <tr><td colspan="2">模板匹配结果Mat要是32位的。</td></tr>
+     * </table>
+     * @return: void
+     * @date: 2019年5月7日12:16:55
+     */
+    public static double templete(int method, String sourcePic, String targetPic) {
+        // 1 获取待匹配图片
+        Mat templete=Imgcodecs.imread(sourcePic);
+        //将rgb灰化处理
+        Imgproc.cvtColor(templete, templete,Imgproc.COLOR_BGR2GRAY);
+
+        // 2 获取匹配模板
+        Mat demo=Imgcodecs.imread(targetPic);
+        Imgproc.cvtColor(demo, demo,Imgproc.COLOR_BGR2GRAY);
+
+        Core.MinMaxLocResult mmr = getLocResult(method, templete, demo);
+        // 7 绘制匹配到的结果
+        double x,y;
+        double matchVal = 0;
+        if (method==Imgproc.TM_SQDIFF_NORMED || method==Imgproc.TM_SQDIFF) {
+            x = mmr.minLoc.x;
+            y = mmr.minLoc.y;
+            matchVal = mmr.minVal;
+        } else {
+            x = mmr.maxLoc.x;
+            y = mmr.maxLoc.y;
+            matchVal = mmr.maxVal;
+        }
+        //if not match , resize the targetPic and try to match again!
+        if (Math.abs(matchVal) > YUZHI) {
+            System.out.println("第一次没匹配上, 尝试125%尺寸再次匹配~~");
+            Mat demoResize = demo.clone();
+            float scale=1.25f;
+            float widthT=demo.width();
+            float heightT=demo.height();
+            Imgproc.resize(demo, demoResize, new Size(widthT*scale,heightT*scale));
+            demo = demoResize;
+            mmr = getLocResult(method, templete, demo);
+            // 7 绘制匹配到的结果
+            matchVal = 0;
+            if (method==Imgproc.TM_SQDIFF_NORMED || method==Imgproc.TM_SQDIFF) {
+                x = mmr.minLoc.x;
+                y = mmr.minLoc.y;
+                matchVal = mmr.minVal;
+            } else {
+                x = mmr.maxLoc.x;
+                y = mmr.maxLoc.y;
+                matchVal = mmr.maxVal;
+            }
+        }
+        System.out.println("匹配度=="+matchVal);
+        System.out.println("x="+x+", y=" + y);
+        Imgproc.rectangle(templete,new Point(x,y),new Point(x+demo.cols(),y+demo.rows()),new Scalar( 0, 0, 255),2,Imgproc.LINE_AA);
+        Imgproc.putText(templete,"Match Success",new Point(x,y),Imgproc.FONT_HERSHEY_SCRIPT_COMPLEX, 1.0, new Scalar(0, 255, 0),1,Imgproc.LINE_AA);
+//        // 8 显示结果
+        HighGui.imshow("模板匹配", templete);
+        HighGui.waitKey(0);
+        return matchVal;
+    }
+
+    private static Core.MinMaxLocResult getLocResult(int method, Mat templete, Mat demo) {
+        int width=templete.cols()-demo.cols()+1;
+        int height=templete.rows()-demo.rows()+1;
+        // 3 创建32位模板匹配结果Mat
+        Mat result=new Mat(width,height,CvType.CV_32FC1);
+        // 4 调用 模板匹配函数
+        Imgproc.matchTemplate(templete, demo, result, method);
+        // 5 归一化
+        Core.normalize(result, result,0, 1, Core.NORM_MINMAX, -1, new Mat());
+        // 6 获取模板匹配结果
+        Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
+        return mmr;
+    }
+}

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

@@ -81,5 +81,7 @@ mybatis:
 #####配置图片上传路径####
 upload:
   path: C:/upload/
+picrecongnize:
+  path: C:/picrecongnize/
 
 

+ 5 - 1
fhKeeper/formulahousekeeper/mywork/home.cpp

@@ -46,7 +46,11 @@ Home::Home(QWidget *parent) :
   this->setCentralWidget(widget);
 
   setWindowState(Qt::WindowMaximized);//最大化
-  QString str = "http://118.190.47.230:9095/#/login";
+  QSettings *qs = new QSettings("MyManager",QSettings::IniFormat,this);
+  qs->beginGroup("user");
+  QString id = qs->value("id").toString();
+  qDebug() << "id=="<<id<<", phone="<<qs->value("name").toString();
+  QString str = "http://118.190.47.230:9092/#/desktop/" + id;
   loadNavigate(str);
 
 

+ 7 - 0
fhKeeper/formulahousekeeper/mywork/mainwindow.cpp

@@ -13,6 +13,7 @@ MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent)
     , ui(new Ui::MainWindow)
 {
+    m_setting = new QSettings("MyManager",QSettings::IniFormat,this);
     ui->setupUi(this);
     connect(ui->loginBtn,SIGNAL(clicked()),this,SLOT(login_in()));
 //    connect(ui->loginBtn, &QAction::triggered, this, &MainWindow::login_in);
@@ -32,6 +33,12 @@ void MainWindow::login_in(void){//登陆
             qDebug()<<"request success==";
             if (json.value("code").toString() == "ok") {
                 myWin->close();
+                QJsonObject obj = json.value("data").toObject();
+                m_setting->beginGroup("user");
+                m_setting->setValue("id", obj.value("id"));
+                m_setting->setValue("name", obj.value("name"));
+                m_setting->setValue("phone", obj.value("phone"));
+                m_setting->endGroup();
                 //enter home page
                 home = new Home();
                 home->show();

+ 1 - 0
fhKeeper/formulahousekeeper/mywork/mainwindow.h

@@ -22,5 +22,6 @@ public slots:                   //新增
 
 private:
     Ui::MainWindow *ui;
+    QSettings *m_setting;
 };
 #endif // MAINWINDOW_H

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

@@ -1,4 +1,9 @@
 export default {
+    test:{
+      test1:'/time-calculation/getDuration'
+    },
+
+
     manage: {
         login: '/user/loginAdmin', // 登录
         list: '/user/getEmployeeList', //获取员工列表

+ 236 - 172
fhKeeper/formulahousekeeper/timesheet/src/views/system/index.vue

@@ -1,192 +1,256 @@
 <template>
-	<section>
-		<!--工具条-->
-		<el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
-			<el-form :inline="true">
-				<el-form-item>
-					<el-date-picker v-model="date" :editable="false" format="yyyy-MM-dd" value-format="yyyy-MM-dd" @change='getList' :clearable="false" type="date" placeholder="选择日期"></el-date-picker>
-				</el-form-item>
-				<el-form-item style="float:right;">
-                    <el-link type="primary" :underline="false" @click="handleAdd">异常申请</el-link>
-				</el-form-item>
-			</el-form>
-		</el-col>
+  <section>
+    <!--工具条-->
+    <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
+      <el-form :inline="true">
+        <el-form-item>
+          <el-date-picker
+            v-model="date"
+            :editable="false"
+            format="yyyy-MM-dd"
+            value-format="yyyy-MM-dd"
+            @change="getList"
+            :clearable="false"
+            type="date"
+            placeholder="选择日期"
+          ></el-date-picker>
+        </el-form-item>
+        <el-form-item style="float:right;">
+          <el-link type="primary" :underline="false" @click="handleAdd">异常申请</el-link>
+        </el-form-item>
+      </el-form>
+    </el-col>
 
-		<!--列表-->
-		<el-table :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
-			<el-table-column type="index" width="60"></el-table-column>
-			<el-table-column prop="projectName" label="姓名" width="140" sortable></el-table-column>
-            <el-table-column prop="ownerCompanyName" label="手机" width="180"></el-table-column>
-            <el-table-column prop="customCompaniesStr" label="编程"></el-table-column>
-            <el-table-column prop="manager" label="设计" sortable></el-table-column>
-            <el-table-column prop="manager" label="办公" sortable></el-table-column>
-            <el-table-column prop="manager" label="娱乐" sortable></el-table-column>
-            <el-table-column prop="manager" label="浏览" sortable></el-table-column>
-			<el-table-column prop="indate" label="总时长" width="180" sortable></el-table-column>
-		</el-table>
+    <!--列表-->
+    <el-table
+      :data="list"
+      highlight-current-row
+      v-loading="listLoading"
+      :height="tableHeight"
+      style="width: 100%;"
+    >
+      <el-table-column type="index" width="60"></el-table-column>
+      <el-table-column prop="projectName" label="姓名" width="140" sortable></el-table-column>
+      <el-table-column prop="ownerCompanyName" label="手机" width="180"></el-table-column>
+      <el-table-column prop="customCompaniesStr" label="编程"></el-table-column>
+      <el-table-column prop="manager" label="设计" sortable></el-table-column>
+      <el-table-column prop="manager" label="办公" sortable></el-table-column>
+      <el-table-column prop="manager" label="娱乐" sortable></el-table-column>
+      <el-table-column prop="manager" label="浏览" sortable></el-table-column>
+      <el-table-column prop="indate" label="总时长" width="180" sortable></el-table-column>
+    </el-table>
 
-		<!--工具条-->
-		<el-col :span="24" class="toolbar">
-			<el-pagination
-                @size-change="handleSizeChange"
-                @current-change="handleCurrentChange"
-                :page-sizes="[20 , 50 , 80 , 100]"
-                :page-size="20"
-                layout="total, sizes, prev, pager, next"
-                :total="total"
-                style="float:right;">
-            </el-pagination>
-		</el-col>
+    <!--工具条-->
+    <el-col :span="24" class="toolbar">
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :page-sizes="[20 , 50 , 80 , 100]"
+        :page-size="20"
+        layout="total, sizes, prev, pager, next"
+        :total="total"
+        style="float:right;"
+      ></el-pagination>
+    </el-col>
 
-        <!--新增界面-->
-		<el-dialog title="异常申请列表" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass='customWidth'>
-			<el-table :data="list" highlight-current-row v-loading="listLoading" height="400" style="width: 100%;">
-                <el-table-column type="index" width="60"></el-table-column>
-                <el-table-column prop="projectName" label="姓名" width="140" sortable></el-table-column>
-                <el-table-column prop="indate" label="工作时长" width="100" sortable></el-table-column>
-                <el-table-column prop="indate" label="异常原因" width="180" sortable></el-table-column>
-                <el-table-column prop="indate" label="时间" sortable></el-table-column>
-            </el-table>
-			<div slot="footer" class="dialog-footer">
-				<el-button @click.native="addFormVisible = false">取消</el-button>
-			</div>
-		</el-dialog>
-	</section>
+    <!--新增界面-->
+    <el-dialog
+      title="异常申请列表"
+      v-if="addFormVisible"
+      :visible.sync="addFormVisible"
+      :close-on-click-modal="false"
+      customClass="customWidth"
+    >
+      <el-table
+        :data="list"
+        highlight-current-row
+        v-loading="listLoading"
+        height="400"
+        style="width: 100%;"
+      >
+        <el-table-column type="index" width="60"></el-table-column>
+        <el-table-column prop="projectName" label="姓名" width="140" sortable></el-table-column>
+        <el-table-column prop="indate" label="工作时长" width="100" sortable></el-table-column>
+        <el-table-column prop="indate" label="异常原因" width="180" sortable></el-table-column>
+        <el-table-column prop="indate" label="时间" sortable></el-table-column>
+      </el-table>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click.native="addFormVisible = false">取消</el-button>
+      </div>
+    </el-dialog>
+  </section>
 </template>
 
 <script>
-	import util from '../../common/js/util'
+import util from "../../common/js/util";
 
-	export default {
-		data() {
-			return {
-                user: JSON.parse(sessionStorage.getItem('user')),
+export default {
+  data() {
+    return {
+      user: JSON.parse(sessionStorage.getItem("user")),
 
-                date: new Date(),
+      date: new Date(),
 
-                tableHeight: 0,
-                listLoading: false,
-				total: 0,
-                page: 1,
-                size: 20,
-                list: [],
-                
-                addFormVisible: false,
-				addLoading: false,
-			}
-		},
-		methods: {
-			//分页
-			handleCurrentChange(val) {
-				this.page = val;
-				this.getList();
-            },
+      tableHeight: 0,
+      listLoading: false,
+      total: 0,
+      page: 1,
+      size: 20,
+      list: [],
 
-            handleSizeChange(val) {
-                this.size = val;
-				this.getList();
-            },
-            
-			//获取项目列表
-			getList() {
-				this.listLoading = true;
-				this.http.post(this.port.project.projectList, {
-                    keyName: '',
-                    pageNum: this.page,
-                    pageSize: this.size,
-                }, res => {
-                    this.listLoading = false;
-                    if (res.code == "ok") {
-                        var list = res.data.list;
-                        for(var i in list){
-                            var customCompaniesStr = "";
-                            for(var j in list[i].customCompanies){
-                                if(j == list[i].customCompanies.length -1){
-                                    customCompaniesStr += list[i].customCompanies[j].companyName;
-                                } else {
-                                    customCompaniesStr += list[i].customCompanies[j].companyName + "、";
-                                }
-                            }
-                            list[i].customCompaniesStr = customCompaniesStr;
-                        }
-                        this.list = list;
-                        this.total = res.data.total;
-                    } else {
-                        this.$message({
-                            message: res.msg,
-                            type: 'error'
-                        });
-                    }
-                }, error => {
-                    this.listLoading = false;
-                    this.$message({
-                        message: error,
-                        type: 'error'
-                    });
-                })
-            },
+      addFormVisible: false,
+      addLoading: false
+    };
+  },
+  methods: {
+    //分页
+    handleCurrentChange(val) {
+      this.page = val;
+      this.getList();
+    },
 
-            //显示新增界面
-			handleAdd() {
-                this.getUnusual();
-				this.addFormVisible = true;
-            },
-
-            // 获取异常列表
-            getUnusual() {
-                this.listLoading = true;
-				this.http.post(this.port.project.projectList, {
-                    keyName: '',
-                    pageNum: this.page,
-                    pageSize: this.size,
-                }, res => {
-                    this.listLoading = false;
-                    if (res.code == "ok") {
-                        var list = res.data.list;
-                        for(var i in list){
-                            var customCompaniesStr = "";
-                            for(var j in list[i].customCompanies){
-                                if(j == list[i].customCompanies.length -1){
-                                    customCompaniesStr += list[i].customCompanies[j].companyName;
-                                } else {
-                                    customCompaniesStr += list[i].customCompanies[j].companyName + "、";
-                                }
-                            }
-                            list[i].customCompaniesStr = customCompaniesStr;
-                        }
-                        this.list = list;
-                        this.total = res.data.total;
-                    } else {
-                        this.$message({
-                            message: res.msg,
-                            type: 'error'
-                        });
-                    }
-                }, error => {
-                    this.listLoading = false;
-                    this.$message({
-                        message: error,
-                        type: 'error'
-                    });
-                })
-            },
+    handleSizeChange(val) {
+      this.size = val;
+      this.getList();
+    },
 
+    //获取项目列表
+    getList() {
+      this.listLoading = true;
+      this.http.post(
+        this.port.project.projectList,
+        {
+          keyName: "",
+          pageNum: this.page,
+          pageSize: this.size
         },
-        created() {
-            let height = window.innerHeight;
-            this.tableHeight = height - 195;
-            const that = this;
-            window.onresize = function temp() {
-                that.tableHeight = window.innerHeight - 195;    
-            };
+        res => {
+          this.listLoading = false;
+          if (res.code == "ok") {
+            var list = res.data.list;
+            for (var i in list) {
+              var customCompaniesStr = "";
+              for (var j in list[i].customCompanies) {
+                if (j == list[i].customCompanies.length - 1) {
+                  customCompaniesStr += list[i].customCompanies[j].companyName;
+                } else {
+                  customCompaniesStr +=
+                    list[i].customCompanies[j].companyName + "、";
+                }
+              }
+              list[i].customCompaniesStr = customCompaniesStr;
+            }
+            this.list = list;
+            this.total = res.data.total;
+          } else {
+            this.$message({
+              message: res.msg,
+              type: "error"
+            });
+          }
         },
-		mounted() {
-            // this.getList();
-		}
-	}
+        error => {
+          this.listLoading = false;
+          this.$message({
+            message: error,
+            type: "error"
+          });
+        }
+      );
+    },
+
+    //显示新增界面
+    handleAdd() {
+      this.getUnusual();
+      this.addFormVisible = true;
+    },
 
+    // 获取异常列表
+    getUnusual() {
+      this.listLoading = true;
+      this.http.post(
+        this.port.project.projectList,
+        {
+          keyName: "",
+          pageNum: this.page,
+          pageSize: this.size
+        },
+        res => {
+          this.listLoading = false;
+          if (res.code == "ok") {
+            var list = res.data.list;
+            for (var i in list) {
+              var customCompaniesStr = "";
+              for (var j in list[i].customCompanies) {
+                if (j == list[i].customCompanies.length - 1) {
+                  customCompaniesStr += list[i].customCompanies[j].companyName;
+                } else {
+                  customCompaniesStr +=
+                    list[i].customCompanies[j].companyName + "、";
+                }
+              }
+              list[i].customCompaniesStr = customCompaniesStr;
+            }
+            this.list = list;
+            this.total = res.data.total;
+          } else {
+            this.$message({
+              message: res.msg,
+              type: "error"
+            });
+          }
+        },
+        error => {
+          this.listLoading = false;
+          this.$message({
+            message: error,
+            type: "error"
+          });
+        }
+      );
+    },
+    //测试用的 没事就删掉吧
+    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() {
+    let height = window.innerHeight;
+    this.tableHeight = height - 195;
+    const that = this;
+    window.onresize = function temp() {
+      that.tableHeight = window.innerHeight - 195;
+    };
+  },
+  mounted() {
+    this.getTest();
+  }
+};
 </script>
 
 <style lang="scss" scoped>
-
 </style>