Browse Source

打卡记录数据功能开发

user5 10 months ago
parent
commit
1cf54cfd12

+ 32 - 0
src/main/java/com/jeeplus/modules/wexintheorder/Utils/OrderUtils.java

@@ -1,5 +1,6 @@
 package com.jeeplus.modules.wexintheorder.Utils;
 
+import com.jeeplus.common.utils.StringUtils;
 import com.jeeplus.modules.statement.entity.StatementDataInfo;
 import com.jeeplus.modules.wexinpackage.access.util.access.AccessTokenUtil;
 import com.jeeplus.modules.wexinpackage.access.util.access.RequestAccess;
@@ -447,6 +448,37 @@ public class OrderUtils {
         return map;
     }
 
+    /**
+     * 计算两个时间相差分钟数
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    public static String getMinuteByTwoTime(String startDate,String endDate) {
+        // 定义日期时间的解析格式
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        // 解析字符串为 LocalDateTime 对象
+        LocalDateTime dateTime1 = LocalDateTime.parse(startDate, formatter);
+        LocalDateTime dateTime2 = LocalDateTime.parse(endDate, formatter);
+
+        // 计算时间差
+        Duration duration = Duration.between(dateTime1, dateTime2);
+
+        // 计算分钟差并向上取整
+        long minutes = duration.toMinutes();
+        if (duration.getSeconds() % 60 != 0) {
+            minutes++;  // 如果有余数秒,则分钟数向上取整
+        }
+
+        // 输出结果
+        System.out.println("两个时间之间的分钟差(向上取整): " + minutes + " 分钟");
+
+        return String.valueOf(minutes);
+    }
+
+
+
 
     /**
      * 获取成员信息

+ 10 - 0
src/main/java/com/jeeplus/modules/wexintheorder/dao/ClockInRecordDao.java

@@ -5,6 +5,9 @@ import com.jeeplus.common.persistence.annotation.MyBatisDao;
 import com.jeeplus.modules.sys.entity.User;
 import com.jeeplus.modules.wexintheorder.entity.ClockInRecordInfo;
 import com.jeeplus.modules.wexintheorder.entity.ClockInRecordSummarizingInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 @MyBatisDao
 public interface ClockInRecordDao extends CrudDao<ClockInRecordInfo> {
@@ -42,4 +45,11 @@ public interface ClockInRecordDao extends CrudDao<ClockInRecordInfo> {
      * @param info
      */
     void updateSummarizing(ClockInRecordSummarizingInfo info);
+
+    /**
+     * 根据汇总表id查询数据信息
+     * @param summarizingId
+     * @return
+     */
+    List<ClockInRecordInfo> getListBySummarizingId(@Param("summarizingId") String summarizingId);
 }

+ 3 - 0
src/main/java/com/jeeplus/modules/wexintheorder/dao/ClockInRecordSummarizingDao.java

@@ -14,4 +14,7 @@ public interface ClockInRecordSummarizingDao extends CrudDao<ClockInRecordSummar
      * @return
      */
     User getUserByQwUSerId(String qwUserId);
+
+
+    ClockInRecordSummarizingInfo getBySummarizingId(String id);
 }

+ 107 - 0
src/main/java/com/jeeplus/modules/wexintheorder/entity/ClockInRecordSummarizingInfo.java

@@ -26,6 +26,23 @@ public class ClockInRecordSummarizingInfo extends DataEntity<ClockInRecordSummar
     private String SchCheckinStartTime; //打卡开始时间
     private String SchCheckinEndTime;   //打卡结束时间
 
+    private String beLateTime;         //迟到时间
+    private String beLateTimeCount;    //迟到次数
+    private String leaveEarlyTime;     //早退时间
+    private String leaveEarlyTimeCount;//早退次数
+    private String absenteeism;        //旷工次数
+    private String absenteeismTime;    //旷工时间
+    private String missingCard;        //缺卡次数
+    private String areaAbnormal;       //地点异常
+    private String allException;       //总异常次数
+    private String exceptionStr;       //汇总异常记录
+
+
+
+
+
+
+
     public String getUserId() {
         return userId;
     }
@@ -137,4 +154,94 @@ public class ClockInRecordSummarizingInfo extends DataEntity<ClockInRecordSummar
     public void setSchCheckinEndTime(String schCheckinEndTime) {
         SchCheckinEndTime = schCheckinEndTime;
     }
+
+    @ExcelField(title="迟到时长(分钟)", align=2, sort=11)
+    public String getBeLateTime() {
+        return beLateTime;
+    }
+
+    public void setBeLateTime(String beLateTime) {
+        this.beLateTime = beLateTime;
+    }
+
+    @ExcelField(title="迟到次数", align=2, sort=10)
+    public String getBeLateTimeCount() {
+        return beLateTimeCount;
+    }
+
+    public void setBeLateTimeCount(String beLateTimeCount) {
+        this.beLateTimeCount = beLateTimeCount;
+    }
+
+    @ExcelField(title="早退时长(分钟)", align=2, sort=13)
+    public String getLeaveEarlyTime() {
+        return leaveEarlyTime;
+    }
+
+    public void setLeaveEarlyTime(String leaveEarlyTime) {
+        this.leaveEarlyTime = leaveEarlyTime;
+    }
+
+    @ExcelField(title="早退次数", align=2, sort=12)
+    public String getLeaveEarlyTimeCount() {
+        return leaveEarlyTimeCount;
+    }
+
+    public void setLeaveEarlyTimeCount(String leaveEarlyTimeCount) {
+        this.leaveEarlyTimeCount = leaveEarlyTimeCount;
+    }
+
+    @ExcelField(title="旷工次数", align=2, sort=14)
+    public String getAbsenteeism() {
+        return absenteeism;
+    }
+
+    public void setAbsenteeism(String absenteeism) {
+        this.absenteeism = absenteeism;
+    }
+
+    @ExcelField(title="旷工时长(分钟)", align=2, sort=15)
+    public String getAbsenteeismTime() {
+        return absenteeismTime;
+    }
+
+    public void setAbsenteeismTime(String absenteeismTime) {
+        this.absenteeismTime = absenteeismTime;
+    }
+
+    @ExcelField(title="缺卡次数", align=2, sort=16)
+    public String getMissingCard() {
+        return missingCard;
+    }
+
+    public void setMissingCard(String missingCard) {
+        this.missingCard = missingCard;
+    }
+
+    @ExcelField(title="地点异常", align=2, sort=17)
+    public String getAreaAbnormal() {
+        return areaAbnormal;
+    }
+
+    public void setAreaAbnormal(String areaAbnormal) {
+        this.areaAbnormal = areaAbnormal;
+    }
+
+    @ExcelField(title="异常合计", align=2, sort=9)
+    public String getAllException() {
+        return allException;
+    }
+
+    public void setAllException(String allException) {
+        this.allException = allException;
+    }
+
+    @ExcelField(title="校准状态", align=2, sort=8)
+    public String getExceptionStr() {
+        return exceptionStr;
+    }
+
+    public void setExceptionStr(String exceptionStr) {
+        this.exceptionStr = exceptionStr;
+    }
 }

+ 193 - 2
src/main/java/com/jeeplus/modules/wexintheorder/service/ClockInRecordService.java

@@ -19,7 +19,7 @@ import net.sf.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
+import java.util.*;
 
 /**
  * 企业微信打卡Service
@@ -85,7 +85,7 @@ public class ClockInRecordService extends CrudService<ClockInRecordDao, ClockInR
         try {
             // 将 JSON 字符串转换为 List 集合
             List<ClockInRecordSaveInfo> checkinList = objectMapper.readValue(clockInData, new TypeReference<List<ClockInRecordSaveInfo>>() {});
-
+            Set<String> summarizingIdSet = new HashSet<>();
             // 打印结果
             for (ClockInRecordSaveInfo checkin : checkinList) {
                 ClockInRecordInfo info = new ClockInRecordInfo();
@@ -138,6 +138,7 @@ public class ClockInRecordService extends CrudService<ClockInRecordDao, ClockInR
                         summarizingInfo.preInsert();
                         clockInRecordSummarizingDao.insert(summarizingInfo);
                         info.setSummarizingId(summarizingInfo.getId());
+                        summarizingIdSet.add(summarizingInfo.getId());
                     }else{
                         //如果存在,则判定info是上班打卡 还是下班打卡,如果是上班打卡,则将打卡数据添加进去
                         if("上班打卡".equals(info.getCheckinType())){
@@ -161,6 +162,7 @@ public class ClockInRecordService extends CrudService<ClockInRecordDao, ClockInR
                         summarizingByCheckinDateAndUserId.preUpdate();
                         clockInRecordSummarizingDao.update(summarizingByCheckinDateAndUserId);
                         info.setSummarizingId(summarizingByCheckinDateAndUserId.getId());
+                        summarizingIdSet.add(summarizingByCheckinDateAndUserId.getId());
                     }
 
                     //根据userid和打卡时间查询是否存在打卡记录,若存在,则进行更新,若不存在,则进行新增
@@ -173,10 +175,199 @@ public class ClockInRecordService extends CrudService<ClockInRecordDao, ClockInR
                 }
 
             }
+
+            //对处理的打卡数据进行二次处理(即 进行迟到、早退、地点异常、未打卡等处理和时间计算)
+            List<String> summarizingIdList = new ArrayList<>(summarizingIdSet);
+            this.disposeExceptionBySummarizingId(summarizingIdList);
+
         } catch (Exception e) {
             e.printStackTrace();
         }
         return null;
     }
 
+
+    /**
+     * 对处理的打卡数据进行二次处理(即 进行迟到、早退、地点异常、未打卡等处理和时间计算)
+     * @param summarizingIdList
+     */
+    public void disposeExceptionBySummarizingId(List<String> summarizingIdList){
+        for (String summarizingId : summarizingIdList) {
+            //根据id查询汇总表中信息
+            ClockInRecordSummarizingInfo summarizingInfo = clockInRecordSummarizingDao.getBySummarizingId(summarizingId);
+
+
+            List<ClockInRecordInfo> infoList = dao.getListBySummarizingId(summarizingId);
+            if(infoList.size()>0){
+                //迟到时间
+                Integer beLateTime = 0;
+                //迟到次数
+                Integer beLateTimeCount = 0;
+                //早退时间
+                Integer leaveEarlyTime = 0;
+                //早退次数
+                Integer leaveEarlyTimeCount = 0;
+                //旷工状态(2次为旷工,1次为缺卡)
+                Integer absenteeism = 0;
+                //旷工时间
+                Integer absenteeismTime = 0;
+                //地点异常
+                Integer areaAbnormal = 0;
+                //总异常次数
+                Integer allException = 0;
+
+                String schCheckinStartTime = "";
+                String schCheckinEndTime = "";
+                for (ClockInRecordInfo clockInRecordInfo : infoList) {
+                    //判定打卡类型是什么状态
+                    switch (clockInRecordInfo.getCheckinType()){
+                        case "上班打卡":
+                            if(StringUtils.isNotBlank(clockInRecordInfo.getSchCheckinTime())){
+                                schCheckinStartTime = clockInRecordInfo.getSchCheckinTime();
+                            }
+                            //判定打卡异常状态:时间异常,地点异常,未打卡,wifi异常,非常用设备
+                            if(StringUtils.isNotBlank(clockInRecordInfo.getExceptionType())){
+                                List<String> ExceptionTypeList = Arrays.asList(clockInRecordInfo.getExceptionType().split(";"));
+                                for (String type : ExceptionTypeList) {
+                                    switch (type){
+                                        case "时间异常":
+                                            //计算打卡时间和正常上班时间进行对比,并进行计算(分钟)
+                                            beLateTime = Integer.parseInt( OrderUtils.getMinuteByTwoTime(clockInRecordInfo.getSchCheckinTime(),clockInRecordInfo.getCheckinTime()));
+                                            break;
+                                        case "地点异常":
+                                            areaAbnormal = areaAbnormal + 1;
+                                            break;
+                                        case "未打卡":
+                                            //如果是未打卡,先进行记录,若下班也是未打卡,则记录为旷工,并进行计算(分钟)
+                                            absenteeism = absenteeism + 1;
+                                            break;
+                                        case "wifi异常":
+                                            break;
+                                        case "非常用设备":
+                                            break;
+                                    }
+                                }
+                            }
+
+                            break;
+                        case "下班打卡":
+                            if(StringUtils.isNotBlank(clockInRecordInfo.getSchCheckinTime())){
+                                schCheckinEndTime = clockInRecordInfo.getSchCheckinTime();
+                            }
+                            //判定打卡异常状态:时间异常,地点异常,未打卡,wifi异常,非常用设备
+                            if(StringUtils.isNotBlank(clockInRecordInfo.getExceptionType())){
+                                List<String> ExceptionTypeList = Arrays.asList(clockInRecordInfo.getExceptionType().split(";"));
+                                for (String type : ExceptionTypeList) {
+                                    switch (type){
+                                        case "时间异常":
+                                            //计算打卡时间和正常上班时间进行对比,并进行计算(分钟)
+                                            leaveEarlyTime = Integer.parseInt( OrderUtils.getMinuteByTwoTime(clockInRecordInfo.getCheckinTime(),clockInRecordInfo.getSchCheckinTime()));
+                                            break;
+                                        case "地点异常":
+                                            areaAbnormal = areaAbnormal + 1;
+                                            break;
+                                        case "未打卡":
+                                            //如果是未打卡,先进行记录,若下班也是未打卡,则记录为旷工,并进行计算(分钟)
+                                            absenteeism = absenteeism + 1;
+                                            break;
+                                        case "wifi异常":
+                                            break;
+                                        case "非常用设备":
+                                            break;
+                                    }
+                                }
+                            }
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                //如果出现两次未打卡,则表示当天旷工,需要计算当日旷工时间
+                if(absenteeism == 2 && StringUtils.isNotBlank(schCheckinStartTime) && StringUtils.isNotBlank(schCheckinEndTime)){
+                    absenteeismTime = Integer.parseInt( OrderUtils.getMinuteByTwoTime(schCheckinStartTime,schCheckinEndTime));
+                }
+
+                //汇总异常状态(以及次数)
+                StringBuilder exceptionStr = new StringBuilder();
+                if(beLateTime > 0 ){
+                    allException ++ ;
+                    beLateTimeCount = 1;
+                    exceptionStr.append("迟到").append(String.valueOf(beLateTime)).append("分钟。");
+                }
+                if(leaveEarlyTime > 0 ){
+                    allException ++ ;
+                    leaveEarlyTimeCount = 1;
+                    exceptionStr.append("早退").append(String.valueOf(leaveEarlyTime)).append("分钟。");
+                }
+                if(areaAbnormal > 0 ){
+                    allException = allException + areaAbnormal ;
+                    exceptionStr.append("地点异常").append(String.valueOf(areaAbnormal)).append("次。");
+                }
+                if(absenteeism == 1){
+                    exceptionStr.append("缺卡").append(String.valueOf(absenteeism)).append("次。");
+                }
+                if(absenteeism == 2){
+                    exceptionStr.append("旷工").append(String.valueOf(absenteeismTime)).append("分钟。");
+                }
+                //旷工和缺卡均算作一次
+                if(absenteeism != 0){
+                    allException = allException + 1;
+                }
+                //将汇总后的异常和各个异常次数以及时间进行保存。方便调用查看
+                if(null != summarizingInfo){
+                    if(0 == beLateTime){
+                        summarizingInfo.setBeLateTime("");
+                    }else{
+                        summarizingInfo.setBeLateTime(String.valueOf(beLateTime));
+                    }
+                    if(0 == beLateTimeCount){
+                        summarizingInfo.setBeLateTimeCount("");
+                    }else{
+                        summarizingInfo.setBeLateTimeCount(String.valueOf(beLateTimeCount));
+                    }
+                    if(0 == leaveEarlyTime){
+                        summarizingInfo.setLeaveEarlyTime("");
+                    }else{
+                        summarizingInfo.setLeaveEarlyTime(String.valueOf(leaveEarlyTime));
+                    }
+
+                    if(0 == leaveEarlyTimeCount){
+                        summarizingInfo.setLeaveEarlyTimeCount("");
+                    }else{
+                        summarizingInfo.setLeaveEarlyTimeCount(String.valueOf(leaveEarlyTimeCount));
+                    }
+
+                    if(absenteeism == 2){
+                        summarizingInfo.setAbsenteeism("1");
+                        summarizingInfo.setAbsenteeismTime(String.valueOf(absenteeismTime));
+                    } else{
+                        summarizingInfo.setAbsenteeism("");
+                        summarizingInfo.setAbsenteeismTime("");
+                    }
+                    if(absenteeism == 0){
+                        summarizingInfo.setMissingCard("");
+                    }else if(absenteeism == 1){
+                        summarizingInfo.setMissingCard(String.valueOf(absenteeism));
+                    }
+
+                    if(0 == areaAbnormal){
+                        summarizingInfo.setAreaAbnormal("");
+                    }else{
+                        summarizingInfo.setAreaAbnormal(String.valueOf(areaAbnormal));
+                    }
+
+                    if(0 == allException){
+                        summarizingInfo.setAllException("");
+                    }else{
+                        summarizingInfo.setAllException(String.valueOf(allException));
+                    }
+
+                    summarizingInfo.setExceptionStr(String.valueOf(exceptionStr));
+
+                    clockInRecordSummarizingDao.update(summarizingInfo);
+                }
+            }
+        }
+    }
+
 }

+ 33 - 1
src/main/java/com/jeeplus/modules/wexintheorder/web/ClockInRecordController.java

@@ -64,7 +64,7 @@ public class ClockInRecordController extends BaseController {
     /**
      * 客户管理列表页面
      */
-    //@RequiresPermissions("clockInRecord:clockInRecord:list")
+    @RequiresPermissions("clockInRecord:clockInRecord:list")
     @RequestMapping(value = {"list", ""})
     public String list(ClockInRecordInfo clockInRecordInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
         //进行查询之后进行任何操作,返回还是查询之后的数据页面
@@ -90,6 +90,38 @@ public class ClockInRecordController extends BaseController {
     }
 
     /**
+     * 查询详情
+     * @param clockInRecordInfo
+     * @param request
+     * @param response
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = "viewList")
+    public String viewList(ClockInRecordInfo clockInRecordInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
+        //进行查询之后进行任何操作,返回还是查询之后的数据页面
+        if (StringUtils.isNotBlank(clockInRecordInfo.getToflag())){
+            if (clockInRecordInfo.getToflag().equals("1")){
+                request.getSession().removeAttribute("clockInRecordInfo");
+                ClockInRecordInfo search=clockInRecordInfo;
+                request.getSession().setAttribute("clockInRecordInfo",search);
+            }
+        }else{
+            if (request.getSession().getAttribute("clockInRecordInfo")!=null){
+                clockInRecordInfo= (ClockInRecordInfo) request.getSession().getAttribute("clockInRecordInfo");
+                model.addAttribute("clockInRecordInfo", clockInRecordInfo);
+            }
+        }
+
+        if(UserUtils.isManager()){
+            model.addAttribute("flag","1");
+        }
+        Page<ClockInRecordInfo> page = clockInRecordService.findPage(new Page<ClockInRecordInfo>(request, response), clockInRecordInfo);
+        model.addAttribute("page", page);
+        return "modules/qw/clickInRecode/ClickInRecordFormList";
+    }
+
+    /**
      * 查询打卡记录信息
      * @return
      */

+ 19 - 0
src/main/resources/mappings/modules/wexintheorder/ClockInRecordDao.xml

@@ -330,4 +330,23 @@
 		</where>
 	</select>
 
+
+
+	<select id="getListBySummarizingId" resultType="com.jeeplus.modules.wexintheorder.entity.ClockInRecordInfo" >
+		SELECT
+		<include refid="lockInRecordColumns"/>
+		,su.name as "userName"
+		,so.name as "office.name"
+		from qw_clock_in_record_info a
+		left join sys_user su on su.id = a.sys_user_id
+		left join sys_office so on so.id = su.office_id
+		<where>
+			a.del_flag = 0
+			<if test="summarizingId !=null and summarizingId != ''">
+				AND a.summarizing_id = #{summarizingId}
+			</if>
+		</where>
+		ORDER BY checkin_type, sch_checkin_time desc,user_id asc
+	</select>
+
 </mapper>

+ 71 - 1
src/main/resources/mappings/modules/wexintheorder/ClockInRecordSummarizingDao.xml

@@ -18,9 +18,47 @@
 		a.work_time as "workTime",
 		a.sys_user_id as "sysUserId",
 		a.sch_checkin_start_time as "schCheckinStartTime",
-		a.sch_checkin_end_time as "schCheckinEndTime"
+		a.sch_checkin_end_time as "schCheckinEndTime",
+		a.be_late_time as "beLateTime",
+		a.be_late_time_count as "beLateTimeCount",
+		a.leave_early_time as "leaveEarlyTime",
+		a.leave_early_time_count as "leaveEarlyTimeCount",
+		a.absenteeism as "absenteeism",
+		a.absenteeism_time as "absenteeismTime",
+		a.missing_card as "missingCard",
+		a.area_abnormal as "areaAbnormal",
+		a.all_exception as "allException",
+		a.exception_str as "exceptionStr"
 	</sql>
 
+	<select id="get" resultType="com.jeeplus.modules.wexintheorder.entity.ClockInRecordSummarizingInfo">
+		SELECT
+		<include refid="lockInRecordSummarizingColumns"/>
+		,su.name as "userName"
+		,so.name as "office.name"
+		from qw_clock_in_record_summarizing_info a
+		left join sys_user su on su.id = a.sys_user_id
+		left join sys_office so on so.id = su.office_id
+		<where>
+			a.del_flag = #{DEL_FLAG_NORMAL}
+			and a.id = #{id}
+		</where>
+	</select>
+
+	<select id="getBySummarizingId" resultType="com.jeeplus.modules.wexintheorder.entity.ClockInRecordSummarizingInfo">
+		SELECT
+		<include refid="lockInRecordSummarizingColumns"/>
+		,su.name as "userName"
+		,so.name as "office.name"
+		from qw_clock_in_record_summarizing_info a
+		left join sys_user su on su.id = a.sys_user_id
+		left join sys_office so on so.id = su.office_id
+		<where>
+			a.del_flag = 0
+			and a.id = #{id}
+		</where>
+	</select>
+
 	<select id="findList" resultType="com.jeeplus.modules.wexintheorder.entity.ClockInRecordSummarizingInfo" >
 		SELECT
 		<include refid="lockInRecordSummarizingColumns"/>
@@ -172,6 +210,38 @@
 			<if test="schCheckinEndTime != null and schCheckinEndTime != ''">
 				sch_checkin_end_time = #{schCheckinEndTime},
 			</if>
+
+			<if test="beLateTime != null and beLateTime != ''">
+				be_late_time = #{beLateTime},
+			</if>
+			<if test="beLateTimeCount != null">
+				be_late_time_count = #{beLateTimeCount},
+			</if>
+			<if test="leaveEarlyTime != null and leaveEarlyTime != ''">
+				leave_early_time = #{leaveEarlyTime},
+			</if>
+			<if test="leaveEarlyTimeCount != null">
+				leave_early_time_count = #{leaveEarlyTimeCount},
+			</if>
+			<if test="absenteeism != null">
+				absenteeism = #{absenteeism},
+			</if>
+			<if test="absenteeismTime != null and absenteeismTime != ''">
+				absenteeism_time = #{absenteeismTime},
+			</if>
+			<if test="missingCard != null">
+				missing_card = #{missingCard},
+			</if>
+			<if test="areaAbnormal != null">
+				area_abnormal = #{areaAbnormal},
+			</if>
+
+			<if test="allException != null">
+				all_exception = #{allException},
+			</if>
+			<if test="exceptionStr != null and exceptionStr != ''">
+				exception_str = #{exceptionStr},
+			</if>
 			sys_user_id = #{sysUserId}
 		WHERE id = #{id}
 	</update>

+ 266 - 0
src/main/webapp/webpage/modules/qw/clickInRecode/ClickInRecordFormList.jsp

@@ -0,0 +1,266 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ page isELIgnored="false"%>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<html>
+<head>
+	<title>企业微信员工打卡记录</title>
+	<meta name="decorator" content="default"/>
+	<style>
+		/*body{
+			background-color:transparent;
+			filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#26FFFFFF, endColorstr=#26FFFFFF);
+			color:#ffffff;
+			background-color:rgba(255,255,255,0);
+			height:100%;
+		}*/
+		.layui-layer-btn1:hover{
+			color: #c2c2c2;
+		}
+	</style>
+	<script type="text/javascript">
+		$(document).ready(function() {
+            $("#cus_name").show();
+            $("#cus_name").siblings().hide();
+            //搜索框收放
+            $('#moresee').click(function(){
+                if($('#moresees').is(':visible'))
+                {
+                    $('#moresees').slideUp(0,resizeListWindow1);
+                    $('#moresee i').removeClass("glyphicon glyphicon-menu-up").addClass("glyphicon glyphicon-menu-down");
+                }else{
+                    $('#moresees').slideDown(0,resizeListWindow1);
+                    $('#moresee i').removeClass("glyphicon glyphicon-menu-down").addClass("glyphicon glyphicon-menu-up");
+                }
+            });
+            laydate.render({
+                elem: '#beginDate', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+, trigger: 'click'
+            });
+            laydate.render({
+                elem: '#endDate', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+, trigger: 'click'
+            });
+		});
+        function switchInput(obj){
+            $("#"+obj).show();
+            $("#"+obj).siblings().hide();
+        }
+        //打开对话框(查看)
+        function openDialogNow(title,url,width,height){
+            if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)){//如果是移动端,就使用自适应大小弹窗
+                width='auto';
+                height='auto';
+            }else{//如果是PC端,根据用户设置的width和height显示。
+
+            }
+            top.layer.open({
+                type: 2,
+                area: [width, height],
+                title: title,
+                maxmin: true, //开启最大化最小化按钮
+                content: url ,
+                btn: ['关闭'],
+                cancel: function(index){
+                }
+            });
+        }
+
+
+        //打开对话框(查看)
+        function deleteFun(url){
+            if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)){//如果是移动端,就使用自适应大小弹窗
+                width='auto';
+                height='auto';
+            }else{//如果是PC端,根据用户设置的width和height显示。
+
+            }
+
+			layer.confirm('确定要删除该客户信息吗?', {
+				title: "删除",
+				btn: ['确定','关闭'] //可以无限个按钮
+			},function(index, layero){
+				$.ajax({
+					type: 'post',
+					url:url,
+					dataType: "json",
+					cache: false,
+					processData: false,
+					contentType: false,
+				}).success(function (result) {
+					if(result.result == "1"){
+						layer.close(index);
+						top.layer.msg(result.msg, {icon: 1});
+						window.location.reload();
+					}else{
+						layer.close(index);
+						top.layer.msg(result.msg, {icon: 2});
+					}
+				});
+			}, function(index){
+				layer.close(index);
+			});
+		}
+
+		function cBlur(obj) {
+			var id = $("#createId").val();
+			if(undefined != obj.value && null != obj.value && '' != obj.value){
+				$.ajax({
+					url:'${ctx}/sys/user/getUserByName?name='+obj.value,
+					type:"post",
+					success:function(data){
+						var user = data.body.data;
+						if(undefined == user || null == user || '' == user){
+							$("#createId").val("");
+						}else{
+							if(data.body.data.id != id){
+								if(undefined != id && null != id && '' != id){
+									$("#createId").val("");
+								}
+							}
+						}
+					}
+				});
+			}else{
+				$("#createId").val("");
+			}
+
+		}
+	</script>
+</head>
+<body class="gray-bg">
+<div class="wrapper wrapper-content">
+	<sys:message content="${message}"/>
+	<div class="layui-row">
+		<div class="full-width fl">
+			<div class="layui-row contentShadow shadowLR" id="queryDiv">
+				<form:form id="searchForm" modelAttribute="clockInRecordInfo" action="${ctx}/clockInRecordController/list" method="post" class="form-inline">
+					<input id="pageNo" name="pageNo" type="hidden" value="${page.pageNo}"/>
+					<input id="pageSize" name="pageSize" type="hidden" value="${page.pageSize}"/>
+					<input id="toflag" name="toflag" type="hidden" value="1"/>
+					<%--<table:sortColumn id="orderBy" name="orderBy" value="${page.orderBy}" callback="sortOrRefresh();"/><!-- 支持排序 -->--%>
+					<%--<div class="commonQuery lw7">
+						<div class="layui-item query athird ">
+							<label class="layui-form-label">姓名:</label>
+							<div class="layui-input-block with-icon">
+								<sys:inquireselectUserNotReadolnyTow id="sysUser" name="sysUserId" value="${clockInRecordInfo.sysUserId}" labelName="userName" labelValue="${clockInRecordInfo.userName}" cssStyle="background-color: #fff"
+																	 title="姓名" url="/sys/office/treeDataAll?type=3" cssClass="form-control layui-input" allowClear="true" notAllowSelectParent="true"/>
+							</div>
+						</div>
+
+						<div class="layui-item query athird">
+							<label class="layui-form-label">部门:</label>
+							<div class="layui-input-block with-icon">
+								<sys:treeselectMoHu id="officeId" name="office.id" value="${clockInRecordInfo.office.id}" labelName="office.name" labelValue="${clockInRecordInfo.office.name}"
+													title="部门" url="/sys/office/treeDataAll?type=6" cssClass="form-control layui-input" allowClear="true" notAllowSelectParent="false"/>
+							</div>
+						</div>
+
+						<div class="layui-item athird">
+							<div class="input-group">
+								<a href="#" id="moresee"><i class="glyphicon glyphicon-menu-down"></i></a>
+								<div class="layui-btn-group search-spacing">
+									<button id="searchQuery" class="layui-btn layui-btn-sm layui-bg-blue" onclick="search()">查询</button>
+									<button id="searchReset" class="layui-btn layui-btn-sm " onclick="resetSearch()">重置</button>
+								</div>
+							</div>
+						</div>
+						<div style="    clear:both;"></div>
+					</div>--%>
+					<%--<div id="moresees" style="clear:both;display:none;" class="lw7">
+						<div class="layui-item query athird">
+							<label class="layui-form-label">打卡时间:</label>
+							<div class="layui-input-block readOnlyFFF">
+								<input id="beginDate" placeholder="开始时间" name="beginDate" type="text" readonly="readonly" maxlength="20" class="laydate-icondate form-control layer-date layui-input laydate-icon query-group"
+									   value="<fmt:formatDate value="${clockInRecordInfo.beginDate}" pattern="yyyy-MM-dd"/>"/>
+								</input>
+								<span class="group-sep">-</span>
+								<input id="endDate" placeholder="结束时间" name="endDate" type="text" readonly="readonly" maxlength="20" class="laydate-icondate form-control layer-date layui-input laydate-icon query-group"
+									   value="<fmt:formatDate value="${clockInRecordInfo.endDate}" pattern="yyyy-MM-dd"/>"/>
+								</input>
+							</div>
+						</div>
+
+					</div>--%>
+				</form:form>
+			</div>
+		</div>
+
+		<div class="full-width fl">
+			<div class="contentShadow layui-form contentDetails">
+				<%--<div class="nav-btns">
+					<div class="layui-btn-group">
+						<shiro:hasPermission name="clockInRecord:clockInRecord:export">
+							<table:exportExcel url="${ctx}/clockInRecordController/export"></table:exportExcel><!-- 导出按钮 -->
+						</shiro:hasPermission>
+						<button class="layui-btn layui-btn-sm" data-toggle="tooltip" data-placement="left" onclick="sortOrRefresh()" title="刷新"> 刷新</button>
+					</div>
+					<div style="clear: both;"></div>
+				</div>--%>
+				<table class="oa-table layui-table" id="contentTable"></table>
+
+				<!-- 分页代码 -->
+				<%--<table:page page="${page}"></table:page>
+				<div style="clear: both;"></div>--%>
+			</div>
+		</div>
+	</div>
+	<div id="changewidth"></div>
+</div>
+<script src="${ctxStatic}/layer-v2.3/layui/layui.all.js" charset="utf-8"></script>
+<script>
+    layui.use('table', function(){
+        layui.table.render({
+            limit:${ page.pageSize }
+            ,elem: '#contentTable'
+            ,page: false
+            ,cols: [[
+				{field:'index',align:'center', title: '序号',width:40}
+				,{field:'userName',align:'center', title: '姓名',width:100}
+				,{field:'officeName',align:'center', title: '部门',width:100}
+                ,{field:'checkinType',align:'center', title: '打卡类型',width:100}
+                ,{field:'exceptionType',align:'center', title: '异常类型', width:100}
+                ,{field:'locationDetail',align:'center', title: '打卡地点', minWidth:100}
+                ,{field:'checkinTime', align:'center',title: '实际打卡时间',width:150}
+                ,{field:'wifiName',align:'center', title: '打卡wifi名称', width:120}
+            ]]
+            ,data: [
+                <c:if test="${ not empty page.list}">
+                <c:forEach items="${page.list}" var="clockInRecordInfo" varStatus="index">
+                <c:if test="${index.index != 0}">,</c:if>
+                {
+                    "index":"${index.index+1}"
+                    ,"id":"${clockInRecordInfo.id}"
+                    ,"userName":"${clockInRecordInfo.userName}"
+					,"checkinType":"${clockInRecordInfo.checkinType}"
+					,"exceptionType":"${clockInRecordInfo.exceptionType}"
+					,"locationDetail":"${clockInRecordInfo.locationDetail}"
+					,"checkinTime":"${clockInRecordInfo.checkinTime}"
+					,"schCheckinTime":"${clockInRecordInfo.schCheckinTime}"
+                    ,"wifiName":"${clockInRecordInfo.wifiName}"
+                    ,"officeName":"${clockInRecordInfo.office.name}"
+                }
+                </c:forEach>
+                </c:if>
+            ]
+        });
+
+    })
+
+    resizeListTable();/*消除由于有竖向滚动条造成table出现横向滚动条*/
+    $("a").on("click",addLinkVisied);
+</script>
+
+<script type="text/javascript">
+    resizeListWindow1();
+    $(window).resize(function(){
+        resizeListWindow1();
+    });
+</script>
+</body>
+
+</html>
+

+ 8 - 8
src/main/webapp/webpage/modules/qw/clickInRecode/ClickInRecordList.jsp

@@ -142,7 +142,7 @@
 					<input id="pageSize" name="pageSize" type="hidden" value="${page.pageSize}"/>
 					<input id="toflag" name="toflag" type="hidden" value="1"/>
 					<%--<table:sortColumn id="orderBy" name="orderBy" value="${page.orderBy}" callback="sortOrRefresh();"/><!-- 支持排序 -->--%>
-					<%--<div class="commonQuery lw7">
+					<div class="commonQuery lw7">
 						<div class="layui-item query athird ">
 							<label class="layui-form-label">姓名:</label>
 							<div class="layui-input-block with-icon">
@@ -169,8 +169,8 @@
 							</div>
 						</div>
 						<div style="    clear:both;"></div>
-					</div>--%>
-					<%--<div id="moresees" style="clear:both;display:none;" class="lw7">
+					</div>
+					<div id="moresees" style="clear:both;display:none;" class="lw7">
 						<div class="layui-item query athird">
 							<label class="layui-form-label">打卡时间:</label>
 							<div class="layui-input-block readOnlyFFF">
@@ -184,14 +184,14 @@
 							</div>
 						</div>
 
-					</div>--%>
+					</div>
 				</form:form>
 			</div>
 		</div>
 
 		<div class="full-width fl">
 			<div class="contentShadow layui-form contentDetails">
-				<%--<div class="nav-btns">
+				<div class="nav-btns">
 					<div class="layui-btn-group">
 						<shiro:hasPermission name="clockInRecord:clockInRecord:export">
 							<table:exportExcel url="${ctx}/clockInRecordController/export"></table:exportExcel><!-- 导出按钮 -->
@@ -199,12 +199,12 @@
 						<button class="layui-btn layui-btn-sm" data-toggle="tooltip" data-placement="left" onclick="sortOrRefresh()" title="刷新"> 刷新</button>
 					</div>
 					<div style="clear: both;"></div>
-				</div>--%>
+				</div>
 				<table class="oa-table layui-table" id="contentTable"></table>
 
 				<!-- 分页代码 -->
-				<%--<table:page page="${page}"></table:page>
-				<div style="clear: both;"></div>--%>
+				<table:page page="${page}"></table:page>
+				<div style="clear: both;"></div>
 			</div>
 		</div>
 	</div>

+ 30 - 9
src/main/webapp/webpage/modules/qw/clickInRecode/ClickInRecordSummarizingList.jsp

@@ -219,15 +219,25 @@
             ,page: false
             ,cols: [[
 				{field:'index',align:'center', title: '序号',width:40}
-				,{field:'userName',align:'center', title: '姓名',minWidth:150,templet:function(d){
-						return "<a class=\"attention-info\" title=\"" + d.userName + "\" href=\"javascript:void(0);\" onclick=\"openDialogView('查看打卡记录', '${ctx}/clockInRecordController/list?summarizingId=" + d.id +"','1000px', '300px')\">" + d.userName + "</a>";
+				,{field:'userName',align:'center', title: '姓名',width:100,templet:function(d){
+						return "<a class=\"attention-info\" title=\"" + d.userName + "\" href=\"javascript:void(0);\" onclick=\"openDialogView('查看打卡记录', '${ctx}/clockInRecordController/viewList?summarizingId=" + d.id +"','1000px', '300px')\">" + d.userName + "</a>";
 					}}
-				,{field:'officeName',align:'center', title: '部门',minWidth:150}
-                ,{field:'checkinDate',align:'center', title: '打卡日期',minWidth:150}
-                ,{field:'workClass',align:'center', title: '上班班次', minWidth:150}
-                ,{field:'earliestTime',align:'center', title: '上班打卡时间', minWidth:150}
-                ,{field:'latestTime', align:'center',title: '下班打卡时间',minWidth:150}
-                ,{field:'workTime',align:'center', title: '上班工作时长(小时)', minWidth:150}
+				,{field:'officeName',align:'center', title: '部门',width:100}
+                ,{field:'checkinDate',align:'center', title: '打卡日期',width:100}
+                ,{field:'workClass',align:'center', title: '上班班次', width:120}
+                ,{field:'earliestTime',align:'center', title: '上班打卡时间', width:150}
+                ,{field:'latestTime', align:'center',title: '下班打卡时间',width:150}
+                ,{field:'workTime',align:'center', title: '上班工作时长(小时)', width:150}
+                ,{field:'exceptionStr',align:'center', title: '校准状态', minWidth:150}
+                ,{field:'allException',align:'center', title: '异常合计', width:100}
+                ,{field:'beLateTimeCount',align:'center', title: '迟到次数', width:80}
+                ,{field:'beLateTime',align:'center', title: '迟到时长(分钟)', width:150}
+				,{field:'leaveEarlyTimeCount',align:'center', title: '早退次数', width:80}
+				,{field:'leaveEarlyTime',align:'center', title: '早退时长(分钟)', width:150}
+				,{field:'absenteeism',align:'center', title: '旷工次数', width:80}
+				,{field:'absenteeismTime',align:'center', title: '旷工时长(分钟)', width:150}
+				,{field:'missingCard',align:'center', title: '缺卡次数', width:80}
+				,{field:'areaAbnormal',align:'center', title: '地点异常', width:80}
             ]]
             ,data: [
                 <c:if test="${ not empty page.list}">
@@ -243,7 +253,18 @@
 					,"earliestTime":"${clockInRecordSummarizingInfo.earliestTime}"
 					,"latestTime":"${clockInRecordSummarizingInfo.latestTime}"
 					,"workTime":"${clockInRecordSummarizingInfo.workTime}"
-                }
+					,"exceptionStr":"${clockInRecordSummarizingInfo.exceptionStr}"
+					,"allException":"${clockInRecordSummarizingInfo.allException}"
+					,"beLateTime":"${clockInRecordSummarizingInfo.beLateTime}"
+					,"beLateTimeCount":"${clockInRecordSummarizingInfo.beLateTimeCount}"
+					,"leaveEarlyTime":"${clockInRecordSummarizingInfo.leaveEarlyTime}"
+					,"leaveEarlyTimeCount":"${clockInRecordSummarizingInfo.leaveEarlyTimeCount}"
+					,"absenteeism":"${clockInRecordSummarizingInfo.absenteeism}"
+					,"absenteeismTime":"${clockInRecordSummarizingInfo.absenteeismTime}"
+					,"missingCard":"${clockInRecordSummarizingInfo.missingCard}"
+					,"areaAbnormal":"${clockInRecordSummarizingInfo.areaAbnormal}"
+
+				}
                 </c:forEach>
                 </c:if>
             ]