瀏覽代碼

打卡记录数据功能开发

user5 10 月之前
父節點
當前提交
73a85a462b

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

@@ -316,6 +316,111 @@ public class OrderUtils {
         return formattedDateTime;
     }
 
+    /**
+     * 时间戳转时间 保留年月日
+     * @param dateStamp
+     * @return
+     */
+    public static String getDateDayByTimestamp(long dateStamp) {// 示例Unix时间戳(10位)
+
+        // 转换为Instant对象
+        Instant instant = Instant.ofEpochSecond(dateStamp);
+
+        // 转换为系统默认时区的LocalDateTime对象
+        LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+
+        // 定义日期时间格式化器
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+        // 格式化日期时间
+        String formattedDateTime = dateTime.format(formatter);
+
+        // 输出结果
+        System.out.println("Unix时间戳: " + dateStamp);
+        System.out.println("格式化后的日期时间: " + formattedDateTime);
+        return formattedDateTime;
+    }
+
+    /**
+     * 时间戳转时间 保留时分
+     * @param dateStamp
+     * @return
+     */
+    public static String getDateHourByTimestamp(long dateStamp) {// 示例Unix时间戳(10位)
+
+        // 将时间戳转换为 LocalTime(只保留时分)
+        LocalTime time = Instant.ofEpochSecond(dateStamp)
+                .atZone(ZoneId.systemDefault())
+                .toLocalTime();
+
+        // 格式化输出时间
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
+        String formattedTime = time.format(formatter);
+
+        // 打印结果
+        System.out.println("当前时间(时:分): " + formattedTime);
+        return formattedTime;
+    }
+
+    /**
+     * 字符串date转时间 保留时分
+     * @param dateTimeStr
+     * @return
+     */
+    public static String getDateHourByDateStr(String dateTimeStr) {
+// 定义日期时间的解析格式
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        // 解析字符串为 LocalDateTime 对象
+        LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, dateTimeFormatter);
+
+        // 定义仅保留时分的格式
+        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
+
+        // 将 LocalDateTime 格式化为仅保留时分的字符串
+        String timeStr = dateTime.format(timeFormatter);
+
+        // 输出结果
+        System.out.println("转换后的时间(时:分): " + timeStr);
+        return timeStr;
+    }
+
+    /**
+     * 计算两个时间之间相差几点几个小时(保留一位小数)
+     * @param startDate 开始时间
+     * @param endDate   结束时间
+     * @return
+     */
+    public static String getTowDateHourIntervalPercentage(String startDate,String endDate) {
+
+        // 定义时间格式
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        // 将字符串时间解析为 LocalTime 对象
+        LocalTime startTime = LocalTime.parse(startDate, formatter);
+        LocalTime endTime = LocalTime.parse(endDate, formatter);
+
+        // 计算时间差
+        Duration duration = Duration.between(startTime, endTime);
+
+        // 获取小时和分钟
+        long hours = duration.toHours();
+        long minutes = duration.toMinutes() % 60;
+
+        // 计算分钟对应的小数部分
+        double fractionalHours = minutes / 60.0;
+
+        // 计算总的时间差,保留一位小数并四舍五入
+        double totalHours = hours + fractionalHours;
+        totalHours = Math.round(totalHours * 10.0) / 10.0;
+
+        // 打印结果
+        System.out.println("从 " + startDate + " 到 " + endDate + " 的时间差是:");
+        System.out.println(totalHours + " 小时");
+
+        return String.valueOf(totalHours);
+    }
+
     public static Map<String,String> getBeforeDayDate(Integer day) {
         Map<String,String> map = new HashMap<>();
         // 获取当前日期

+ 22 - 1
src/main/java/com/jeeplus/modules/wexintheorder/dao/ClockInRecordDao.java

@@ -4,6 +4,7 @@ import com.jeeplus.common.persistence.CrudDao;
 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;
 
 @MyBatisDao
 public interface ClockInRecordDao extends CrudDao<ClockInRecordInfo> {
@@ -13,7 +14,7 @@ public interface ClockInRecordDao extends CrudDao<ClockInRecordInfo> {
      * @param info
      * @return
      */
-    ClockInRecordInfo getByUserIdAndCheckinTime(ClockInRecordInfo info);
+    ClockInRecordInfo getByUserIdAndCheckinTypeAndSchCheckinTime(ClockInRecordInfo info);
 
     /**
      * 根据企业微信用户id查询系统用户信息
@@ -21,4 +22,24 @@ public interface ClockInRecordDao extends CrudDao<ClockInRecordInfo> {
      * @return
      */
     User getUserByQwUSerId(String qwUserId);
+
+
+    /**
+     * 根据userid和打卡时间查询是否存在打卡记录
+     * @param info
+     * @return
+     */
+    ClockInRecordSummarizingInfo getSummarizingByCheckinDateAndUserId(ClockInRecordSummarizingInfo info);
+
+    /**
+     * 保存打卡记录
+     * @param info
+     */
+    void insertSummarizing(ClockInRecordSummarizingInfo info);
+
+    /**
+     * 修改打卡记录
+     * @param info
+     */
+    void updateSummarizing(ClockInRecordSummarizingInfo info);
 }

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

@@ -0,0 +1,17 @@
+package com.jeeplus.modules.wexintheorder.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.wexintheorder.entity.ClockInRecordSummarizingInfo;
+
+@MyBatisDao
+public interface ClockInRecordSummarizingDao extends CrudDao<ClockInRecordSummarizingInfo> {
+
+    /**
+     * 根据企业微信用户id查询系统用户信息
+     * @param qwUserId
+     * @return
+     */
+    User getUserByQwUSerId(String qwUserId);
+}

+ 38 - 1
src/main/java/com/jeeplus/modules/wexintheorder/entity/ClockInRecordInfo.java

@@ -2,8 +2,9 @@ package com.jeeplus.modules.wexintheorder.entity;
 
 import com.jeeplus.common.persistence.DataEntity;
 import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.entity.Office;
 
-import java.util.List;
+import java.util.Date;
 
 /**
  * 打卡记录表
@@ -31,6 +32,10 @@ public class ClockInRecordInfo  extends DataEntity<ClockInRecordInfo> {
     private String timelineId; //时段id,表示打卡记录所属规则中,某一班次中的某一时段的id,如上下班时间为9:00-12:00、13:00-18:00的班次中,9:00-12:00为其中一组时段
     private String sysUserId; //系统用户id
     private String userName; //系统用户名称
+    private Office office; //系统用户隶属部门
+    private Date beginDate;
+    private Date endDate;
+    private String summarizingId;
 
     public String getUserId() {
         return userId;
@@ -198,4 +203,36 @@ public class ClockInRecordInfo  extends DataEntity<ClockInRecordInfo> {
     public void setUserName(String userName) {
         this.userName = userName;
     }
+
+    public Office getOffice() {
+        return office;
+    }
+
+    public void setOffice(Office office) {
+        this.office = office;
+    }
+
+    public Date getBeginDate() {
+        return beginDate;
+    }
+
+    public void setBeginDate(Date beginDate) {
+        this.beginDate = beginDate;
+    }
+
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    public void setEndDate(Date endDate) {
+        this.endDate = endDate;
+    }
+
+    public String getSummarizingId() {
+        return summarizingId;
+    }
+
+    public void setSummarizingId(String summarizingId) {
+        this.summarizingId = summarizingId;
+    }
 }

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

@@ -0,0 +1,140 @@
+package com.jeeplus.modules.wexintheorder.entity;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.entity.Office;
+
+import java.util.Date;
+
+/**
+ * 打卡记录表
+ * @author: 徐滕
+ * @version: 2024-08-08 16:02
+ */
+public class ClockInRecordSummarizingInfo extends DataEntity<ClockInRecordSummarizingInfo> {
+    private String userId;  //用户id
+    private String checkinDate; //打卡日期
+    private String workClass;    //上班班次
+    private String earliestTime;    //最早上班时间
+    private String latestTime;    //最晚下班时间
+    private String workTime;    //上班工作时长
+    private String sysUserId; //系统用户id
+    private String userName; //系统用户名称
+    private Office office; //系统用户隶属部门
+    private Date beginDate;
+    private Date endDate;
+    private String SchCheckinStartTime; //打卡开始时间
+    private String SchCheckinEndTime;   //打卡结束时间
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    @ExcelField(title="打卡日期", align=2, sort=3)
+    public String getCheckinDate() {
+        return checkinDate;
+    }
+
+    public void setCheckinDate(String checkinDate) {
+        this.checkinDate = checkinDate;
+    }
+
+
+    @ExcelField(title="上班班次", align=2, sort=4)
+    public String getWorkClass() {
+        return workClass;
+    }
+
+    public void setWorkClass(String workClass) {
+        this.workClass = workClass;
+    }
+
+    @ExcelField(title="上班打卡时间", align=2, sort=5)
+    public String getEarliestTime() {
+        return earliestTime;
+    }
+
+    public void setEarliestTime(String earliestTime) {
+        this.earliestTime = earliestTime;
+    }
+
+    @ExcelField(title="下班打卡时间", align=2, sort=6)
+    public String getLatestTime() {
+        return latestTime;
+    }
+
+    public void setLatestTime(String latestTime) {
+        this.latestTime = latestTime;
+    }
+
+    @ExcelField(title="上班工作时长(小时)", align=2, sort=7)
+    public String getWorkTime() {
+        return workTime;
+    }
+
+    public void setWorkTime(String workTime) {
+        this.workTime = workTime;
+    }
+
+    public String getSysUserId() {
+        return sysUserId;
+    }
+
+    public void setSysUserId(String sysUserId) {
+        this.sysUserId = sysUserId;
+    }
+
+    @ExcelField(title="姓名", align=2, sort=1)
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    @ExcelField(title="部门", fieldType=Office.class, value="office.name", align=2, sort=2)
+    public Office getOffice() {
+        return office;
+    }
+
+    public void setOffice(Office office) {
+        this.office = office;
+    }
+
+    public Date getBeginDate() {
+        return beginDate;
+    }
+
+    public void setBeginDate(Date beginDate) {
+        this.beginDate = beginDate;
+    }
+
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    public void setEndDate(Date endDate) {
+        this.endDate = endDate;
+    }
+
+    public String getSchCheckinStartTime() {
+        return SchCheckinStartTime;
+    }
+
+    public void setSchCheckinStartTime(String schCheckinStartTime) {
+        SchCheckinStartTime = schCheckinStartTime;
+    }
+
+    public String getSchCheckinEndTime() {
+        return SchCheckinEndTime;
+    }
+
+    public void setSchCheckinEndTime(String schCheckinEndTime) {
+        SchCheckinEndTime = schCheckinEndTime;
+    }
+}

+ 86 - 16
src/main/java/com/jeeplus/modules/wexintheorder/service/ClockInRecordService.java

@@ -6,12 +6,17 @@ import com.google.common.collect.Lists;
 import com.jeeplus.common.persistence.Page;
 import com.jeeplus.common.service.CrudService;
 import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.sys.entity.Office;
 import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.service.OfficeService;
 import com.jeeplus.modules.wexintheorder.Utils.OrderUtils;
 import com.jeeplus.modules.wexintheorder.dao.ClockInRecordDao;
+import com.jeeplus.modules.wexintheorder.dao.ClockInRecordSummarizingDao;
 import com.jeeplus.modules.wexintheorder.entity.ClockInRecordInfo;
 import com.jeeplus.modules.wexintheorder.entity.ClockInRecordSaveInfo;
+import com.jeeplus.modules.wexintheorder.entity.ClockInRecordSummarizingInfo;
 import net.sf.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
@@ -24,18 +29,38 @@ import java.util.List;
 @Service
 public class ClockInRecordService extends CrudService<ClockInRecordDao, ClockInRecordInfo> {
 
+    @Autowired
+    private OfficeService officeService;
+    @Autowired
+    private ClockInRecordSummarizingDao clockInRecordSummarizingDao;
 
 
     /**
-     * 获取一个客户信息
+     * 获取信息
      * @param page 分页对象
-     * @param workClientInfo
+     * @param clockInRecordInfo
      * @return
      */
     public Page<ClockInRecordInfo> findPage(Page<ClockInRecordInfo> page, ClockInRecordInfo clockInRecordInfo) {
         /*if(!UserUtils.getUser().isAdmin()) {
             clockInRecordInfo.getSqlMap().put("dsf", dataScopeFilter(clockInRecordInfo.getCurrentUser(), "o", "u", "s", MenuStatusEnum.WORK_CLIENT_INFO.getValue()));
         }*/
+
+
+        if(null!= clockInRecordInfo.getOffice() && org.apache.commons.lang3.StringUtils.isNotBlank(clockInRecordInfo.getOffice().getId())){
+            if ("一部本部".equals(clockInRecordInfo.getOffice().getId())) {
+                List<String> officeIdList = Lists.newArrayList();
+                Office office = officeService.getByName("工程一部");
+                officeIdList.add(office.getId());
+                clockInRecordInfo.setOfficeIdList(officeIdList);
+            } else {
+                //查询该选择节点下所有的部门Id
+                List<String> officeIdList = officeService.getChildrenOffice(clockInRecordInfo.getOffice().getId());
+                officeIdList.add(clockInRecordInfo.getOffice().getId());
+                clockInRecordInfo.setOfficeIdList(officeIdList);
+            }
+
+        }
         //根据项目类型获取对应的客户id个数
         int count = dao.queryCount(clockInRecordInfo);
         page.setCount(count);
@@ -61,8 +86,6 @@ public class ClockInRecordService extends CrudService<ClockInRecordDao, ClockInR
             // 将 JSON 字符串转换为 List 集合
             List<ClockInRecordSaveInfo> checkinList = objectMapper.readValue(clockInData, new TypeReference<List<ClockInRecordSaveInfo>>() {});
 
-            List<ClockInRecordInfo> checkInInfoList = Lists.newArrayList();
-
             // 打印结果
             for (ClockInRecordSaveInfo checkin : checkinList) {
                 ClockInRecordInfo info = new ClockInRecordInfo();
@@ -88,20 +111,67 @@ public class ClockInRecordService extends CrudService<ClockInRecordDao, ClockInR
                 info.setGroupId(checkin.getGroupid());
                 info.setScheduleId(checkin.getSchedule_id());
                 info.setTimelineId(checkin.getTimeline_id());
-                //根据userId查询对应用户id 进行关联
-                User userByQwUSerId = dao.getUserByQwUSerId(info.getUserId());
-                if(null != userByQwUSerId){
-                    info.setSysUserId(userByQwUSerId.getId());
-                }
-                //根据userid和打卡时间查询是否存在打卡记录,若存在,则进行更新,若不存在,则进行新增
-                ClockInRecordInfo userCheckinInfo = dao.getByUserIdAndCheckinTime(info);
-                if(null == userCheckinInfo){
-                }else{
-                    info.setId(userCheckinInfo.getId());
+
+                if(StringUtils.isNotBlank(info.getTimelineId()) && "1".equals(info.getTimelineId())){
+                    //根据userId查询对应用户id 进行关联
+                    User userByQwUSerId = dao.getUserByQwUSerId(info.getUserId());
+                    if(null != userByQwUSerId){
+                        info.setSysUserId(userByQwUSerId.getId());
+                    }
+
+                    //将打开时间转换为日期
+                    ClockInRecordSummarizingInfo summarizingInfo = new ClockInRecordSummarizingInfo();
+                    summarizingInfo.setCheckinDate(OrderUtils.getDateDayByTimestamp(Long.parseLong(checkin.getSch_checkin_time())));
+                    summarizingInfo.setUserId(info.getUserId());
+                    //根据打卡用户id和打卡日期查询是否存在,若存在 则直接修改,否则进行新增
+                    ClockInRecordSummarizingInfo summarizingByCheckinDateAndUserId = dao.getSummarizingByCheckinDateAndUserId(summarizingInfo);
+                    if(null == summarizingByCheckinDateAndUserId){
+                        //如果不存在,则判定info是上班打卡 还是下班打卡,如果是上班打卡,则将打卡数据添加进去
+                        if("上班打卡".equals(info.getCheckinType())){
+                            summarizingInfo.setEarliestTime(info.getCheckinTime());
+                            summarizingInfo.setSchCheckinStartTime(OrderUtils.getDateHourByTimestamp(Long.parseLong(checkin.getCheckin_time())));
+                        }else if("下班打卡".equals(info.getCheckinType())){
+                            summarizingInfo.setLatestTime(info.getCheckinTime());
+                            summarizingInfo.setSchCheckinEndTime(OrderUtils.getDateHourByTimestamp(Long.parseLong(checkin.getCheckin_time())));
+                        }
+                        summarizingInfo.setSysUserId(info.getSysUserId());
+                        summarizingInfo.preInsert();
+                        clockInRecordSummarizingDao.insert(summarizingInfo);
+                        info.setSummarizingId(summarizingInfo.getId());
+                    }else{
+                        //如果存在,则判定info是上班打卡 还是下班打卡,如果是上班打卡,则将打卡数据添加进去
+                        if("上班打卡".equals(info.getCheckinType())){
+                            summarizingByCheckinDateAndUserId.setEarliestTime(info.getCheckinTime());
+                            summarizingByCheckinDateAndUserId.setSchCheckinStartTime(OrderUtils.getDateHourByTimestamp(Long.parseLong(checkin.getSch_checkin_time())));
+                        }else if("下班打卡".equals(info.getCheckinType())){
+                            summarizingByCheckinDateAndUserId.setLatestTime(info.getCheckinTime());
+                            summarizingByCheckinDateAndUserId.setSchCheckinEndTime(OrderUtils.getDateHourByTimestamp(Long.parseLong(checkin.getSch_checkin_time())));
+                        }
+                        //判定上班打卡时间和下班打卡时间是否都存在,都存在则进行工作时长处理
+                        if(StringUtils.isNotBlank(summarizingByCheckinDateAndUserId.getEarliestTime()) && StringUtils.isNotBlank(summarizingByCheckinDateAndUserId.getLatestTime())){
+                            summarizingByCheckinDateAndUserId.setWorkTime(OrderUtils.getTowDateHourIntervalPercentage(summarizingByCheckinDateAndUserId.getEarliestTime(),summarizingByCheckinDateAndUserId.getLatestTime()));
+                        }
+
+                        //判定上班打卡时间和下班打卡时间是否都存在,都存在则进行工作时长处理
+                        if(StringUtils.isNotBlank(summarizingByCheckinDateAndUserId.getSchCheckinStartTime()) && StringUtils.isNotBlank(summarizingByCheckinDateAndUserId.getSchCheckinEndTime())){
+                            summarizingByCheckinDateAndUserId.setWorkClass(summarizingByCheckinDateAndUserId.getSchCheckinStartTime() + "-" + summarizingByCheckinDateAndUserId.getSchCheckinEndTime());
+                        }
+
+                        summarizingByCheckinDateAndUserId.setSysUserId(info.getSysUserId());
+                        summarizingByCheckinDateAndUserId.preUpdate();
+                        clockInRecordSummarizingDao.update(summarizingByCheckinDateAndUserId);
+                        info.setSummarizingId(summarizingByCheckinDateAndUserId.getId());
+                    }
+
+                    //根据userid和打卡时间查询是否存在打卡记录,若存在,则进行更新,若不存在,则进行新增
+                    ClockInRecordInfo userCheckinInfo = dao.getByUserIdAndCheckinTypeAndSchCheckinTime(info);
+                    if(null == userCheckinInfo){
+                    }else{
+                        info.setId(userCheckinInfo.getId());
+                    }
+                    super.save(info);
                 }
-                super.save(info);
 
-                checkInInfoList.add(info);
             }
         } catch (Exception e) {
             e.printStackTrace();

+ 72 - 0
src/main/java/com/jeeplus/modules/wexintheorder/service/ClockInRecordSummarizingService.java

@@ -0,0 +1,72 @@
+package com.jeeplus.modules.wexintheorder.service;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.service.OfficeService;
+import com.jeeplus.modules.wexintheorder.Utils.OrderUtils;
+import com.jeeplus.modules.wexintheorder.dao.ClockInRecordDao;
+import com.jeeplus.modules.wexintheorder.dao.ClockInRecordSummarizingDao;
+import com.jeeplus.modules.wexintheorder.entity.ClockInRecordInfo;
+import com.jeeplus.modules.wexintheorder.entity.ClockInRecordSaveInfo;
+import com.jeeplus.modules.wexintheorder.entity.ClockInRecordSummarizingInfo;
+import net.sf.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 企业微信打卡Service
+ * @author: 徐滕
+ * @version: 2024-08-08 16:14
+ */
+@Service
+public class ClockInRecordSummarizingService extends CrudService<ClockInRecordSummarizingDao, ClockInRecordSummarizingInfo> {
+
+    @Autowired
+    private OfficeService officeService;
+
+
+    /**
+     * 获取信息
+     * @param page 分页对象
+     * @param clockInRecordInfo
+     * @return
+     */
+    public Page<ClockInRecordSummarizingInfo> findPage(Page<ClockInRecordSummarizingInfo> page, ClockInRecordSummarizingInfo clockInRecordInfo) {
+        /*if(!UserUtils.getUser().isAdmin()) {
+            clockInRecordInfo.getSqlMap().put("dsf", dataScopeFilter(clockInRecordInfo.getCurrentUser(), "o", "u", "s", MenuStatusEnum.WORK_CLIENT_INFO.getValue()));
+        }*/
+
+
+        if(null!= clockInRecordInfo.getOffice() && StringUtils.isNotBlank(clockInRecordInfo.getOffice().getId())){
+            if ("一部本部".equals(clockInRecordInfo.getOffice().getId())) {
+                List<String> officeIdList = Lists.newArrayList();
+                Office office = officeService.getByName("工程一部");
+                officeIdList.add(office.getId());
+                clockInRecordInfo.setOfficeIdList(officeIdList);
+            } else {
+                //查询该选择节点下所有的部门Id
+                List<String> officeIdList = officeService.getChildrenOffice(clockInRecordInfo.getOffice().getId());
+                officeIdList.add(clockInRecordInfo.getOffice().getId());
+                clockInRecordInfo.setOfficeIdList(officeIdList);
+            }
+
+        }
+        //根据项目类型获取对应的客户id个数
+        int count = dao.queryCount(clockInRecordInfo);
+        page.setCount(count);
+        page.setCountFlag(false);
+        clockInRecordInfo.setPage(page);
+        List<ClockInRecordSummarizingInfo> list = findList(clockInRecordInfo);
+        page.setList(list);
+        return page;
+    }
+
+}

+ 1 - 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) {
         //进行查询之后进行任何操作,返回还是查询之后的数据页面

+ 88 - 0
src/main/java/com/jeeplus/modules/wexintheorder/web/ClockInRecordSummarizingController.java

@@ -0,0 +1,88 @@
+package com.jeeplus.modules.wexintheorder.web;
+
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.wexintheorder.entity.ClockInRecordSummarizingInfo;
+import com.jeeplus.modules.wexintheorder.service.ClockInRecordSummarizingService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/**
+ * 企业微信打卡controller
+ * @author: 徐滕
+ * @version: 2024-08-07 13:43
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/clockInRecordSummarizingController")
+public class ClockInRecordSummarizingController extends BaseController {
+
+
+    @Autowired
+    private ClockInRecordSummarizingService clockInRecordSummarizingService;
+
+
+    /**
+     * 客户管理列表页面
+     */
+    @RequiresPermissions("clockInRecordSummarizing:clockInRecordSummarizing:list")
+    @RequestMapping(value = {"list", ""})
+    public String list(ClockInRecordSummarizingInfo clockInRecordSummarizingInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
+        //进行查询之后进行任何操作,返回还是查询之后的数据页面
+        if (StringUtils.isNotBlank(clockInRecordSummarizingInfo.getToflag())){
+            if (clockInRecordSummarizingInfo.getToflag().equals("1")){
+                request.getSession().removeAttribute("clockInRecordSummarizingInfo");
+                ClockInRecordSummarizingInfo search=clockInRecordSummarizingInfo;
+                request.getSession().setAttribute("clockInRecordSummarizingInfo",search);
+            }
+        }else{
+            if (request.getSession().getAttribute("clockInRecordSummarizingInfo")!=null){
+                clockInRecordSummarizingInfo = (ClockInRecordSummarizingInfo) request.getSession().getAttribute("clockInRecordSummarizingInfo");
+                model.addAttribute("clockInRecordSummarizingInfo", clockInRecordSummarizingInfo);
+            }
+        }
+
+        if(UserUtils.isManager()){
+            model.addAttribute("flag","1");
+        }
+        Page<ClockInRecordSummarizingInfo> page = clockInRecordSummarizingService.findPage(new Page<ClockInRecordSummarizingInfo>(request, response), clockInRecordSummarizingInfo);
+        model.addAttribute("page", page);
+        return "modules/qw/clickInRecode/ClickInRecordSummarizingList";
+    }
+
+
+
+
+
+    /**
+     * 导出excel文件
+     */
+    @RequiresPermissions("clockInRecordSummarizing:clockInRecordSummarizing:export")
+    @RequestMapping(value = "export", method= RequestMethod.POST)
+    public String exportFile(ClockInRecordSummarizingInfo clockInRecordSummarizingInfo, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        try {
+            String fileName = "打卡记录"+ DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<ClockInRecordSummarizingInfo> page = clockInRecordSummarizingService.findPage(new Page<ClockInRecordSummarizingInfo>(request, response, -1), clockInRecordSummarizingInfo);
+            new ExportExcel("打卡记录", ClockInRecordSummarizingInfo.class).setDataList(page.getList()).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            logger.error("Exception e:"+e);
+            addMessage(redirectAttributes, "导出打卡记录失败!失败信息:"+e.getMessage());
+        }
+        return "redirect:"+ Global.getAdminPath()+"/clockInRecordController/?repage";
+    }
+
+}

+ 169 - 8
src/main/resources/mappings/modules/wexintheorder/ClockInRecordDao.xml

@@ -27,17 +27,65 @@
 		a.group_id as "groupId",
 		a.schedule_id as "scheduleId",
 		a.timeline_id as "timelineId",
-		a.sys_user_id as "sysUserId"
+		a.sys_user_id as "sysUserId",
+		a.summarizing_id as "summarizingId"
+	</sql>
+
+	<sql id="lockInRecordSummarizingColumns">
+		a.id,
+		a.create_by AS "createBy.id",
+		a.create_date as "createDate",
+		a.update_by AS "updateBy.id",
+		a.update_date as "updateDate",
+		a.del_flag as "",
+		a.remarks,
+		a.user_id as "userId",
+		a.checkin_date as "checkinDate",
+		a.work_class as "workClass",
+		a.earliest_time as "earliestTime",
+		a.latest_time as "latestTime",
+		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"
 	</sql>
 
 	<select id="findList" 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 = #{DEL_FLAG_NORMAL}
+
+			<if test="(userName != null and userName != '') or (sysUserId != null and sysUserId != '')">
+				AND su.name like concat('%',#{userName},'%')
+			</if>
+
+			<if test="office!=null and office.id=='' and office.name!=null and office.name!='' ">
+				and  so.name like concat('%',#{office.name},'%')
+			</if>
+
+			<if test="officeIdList!=null and officeIdList.size!=0">
+				and su.office_id in
+				<foreach collection="officeIdList" item="officeId" separator="," open="(" close=")">
+					#{officeId}
+				</foreach>
+			</if>
+
+			<if test="beginDate !=null">
+				AND a.create_date >= #{beginDate}
+			</if>
+			<if test="endDate !=null">
+				AND a.create_date &lt;= #{endDate}
+			</if>
+			<if test="summarizingId !=null and summarizingId != ''">
+				AND a.summarizing_id = #{summarizingId}
+			</if>
+
 			<if test="sqlMap.dsf !=null and sqlMap.dsf!=''">
 				${sqlMap.dsf}
 			</if>
@@ -47,7 +95,7 @@
 				ORDER BY ${page.orderBy}
 			</when>
 			<otherwise>
-				ORDER BY sch_checkin_time desc,user_id asc
+				ORDER BY checkin_type, sch_checkin_time desc,user_id asc
 			</otherwise>
 		</choose>
 	</select>
@@ -56,8 +104,36 @@
 		SELECT
 		count(distinct a.id)
 		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 = #{DEL_FLAG_NORMAL}
+
+
+			<if test="(userName != null and userName != '') or (sysUserId != null and sysUserId != '')">
+				AND su.name like concat('%',#{userName},'%')
+			</if>
+
+			<if test="office!=null and office.id=='' and office.name!=null and office.name!='' ">
+				and  so.name like concat('%',#{office.name},'%')
+			</if>
+
+			<if test="officeIdList!=null and officeIdList.size!=0">
+				and su.office_id in
+				<foreach collection="officeIdList" item="officeId" separator="," open="(" close=")">
+					#{officeId}
+				</foreach>
+			</if>
+
+			<if test="beginDate !=null">
+				AND a.create_date >= #{beginDate}
+			</if>
+			<if test="endDate !=null">
+				AND a.create_date &lt;= #{endDate}
+			</if>
+			<if test="summarizingId !=null and summarizingId != ''">
+				AND a.summarizing_id = #{summarizingId}
+			</if>
 			<if test="sqlMap.dsf !=null and sqlMap.dsf!=''">
 				${sqlMap.dsf}
 			</if>
@@ -65,14 +141,26 @@
 	</select>
 
 
-	<select id="getByUserIdAndCheckinTime" resultType="com.jeeplus.modules.wexintheorder.entity.ClockInRecordInfo">
+	<select id="getByUserIdAndCheckinTypeAndSchCheckinTime" resultType="com.jeeplus.modules.wexintheorder.entity.ClockInRecordInfo">
 		select
 		<include refid="lockInRecordColumns"/>
 		,su.name as "userName"
 		from qw_clock_in_record_info a
 		left join sys_user su on su.id = a.sys_user_id
 		<where>
-			a.user_id = #{userId} and a.checkin_time = #{checkinTime} and a.del_flag = 0
+			a.user_id = #{userId} and a.checkin_type = #{checkinType} and a.sch_checkin_time = #{schCheckinTime} and a.del_flag = 0
+		</where>
+	</select>
+
+
+	<select id="getSummarizingByCheckinDateAndUserId" resultType="com.jeeplus.modules.wexintheorder.entity.ClockInRecordSummarizingInfo">
+		select
+		<include refid="lockInRecordSummarizingColumns"/>
+		,su.name as "userName"
+		from qw_clock_in_record_summarizing_info a
+		left join sys_user su on su.id = a.sys_user_id
+		<where>
+			a.user_id = #{userId} and a.checkin_date = #{checkinDate} and a.del_flag = 0
 		</where>
 	</select>
 
@@ -103,7 +191,8 @@
 			group_id,
 			schedule_id,
 			timeline_id,
-			sys_user_id
+			sys_user_id,
+			summarizing_id
 		) VALUES (
 			#{id},
 			#{createBy.id},
@@ -130,8 +219,8 @@
 			#{groupId},
 			#{scheduleId},
 			#{timelineId},
-			#{sysUserId}
-
+			#{sysUserId},
+			#{summarizingId}
 		)
 	</insert>
 
@@ -156,12 +245,84 @@
 			group_id = #{groupId},
 			schedule_id = #{scheduleId},
 			timeline_id = #{timelineId},
-			sys_user_id = #{sysUserId}
+			sys_user_id = #{sysUserId},
+			summarizing_id = #{summarizingId}
 		WHERE id = #{id}
 	</update>
 
 
 
+	<insert id="insertSummarizing">
+		INSERT INTO qw_clock_in_record_summarizing_info(
+			id,
+			create_by,
+			create_date,
+			update_by,
+			update_date,
+			remarks,
+			del_flag,
+			user_id,
+			checkin_date,
+			work_class,
+			earliest_time,
+			latest_time,
+			work_time,
+			sys_user_id,
+			sch_checkin_start_time,
+			sch_checkin_end_time
+		) VALUES (
+			#{id},
+			#{createBy.id},
+			#{createDate},
+			#{updateBy.id},
+			#{updateDate},
+			#{remarks},
+			#{delFlag},
+			#{userId},
+			#{checkinDate},
+			#{workClass},
+			#{earliestTime},
+			#{latestTime},
+			#{workTime},
+			#{sysUserId},
+			#{schCheckinStartTime},
+			#{schCheckinEndTime}
+
+		)
+	</insert>
+
+	<update id="updateSummarizing">
+		UPDATE qw_clock_in_record_summarizing_info SET
+			update_date = #{updateDate},
+			<if test="userId != null and userId != ''">
+				user_id = #{userId},
+			</if>
+			<if test="checkinDate != null and checkinDate != ''">
+				checkin_date = #{checkinDate},
+			</if>
+			<if test="workClass != null and workClass != ''">
+				work_class = #{workClass},
+			</if>
+			<if test="earliestTime != null and earliestTime != ''">
+				earliest_time = #{earliestTime},
+			</if>
+			<if test="latestTime != null and latestTime != ''">
+				latest_time = #{latestTime},
+			</if>
+			<if test="workTime != null and workTime != ''">
+				work_time = #{workTime},
+			</if>
+			<if test="schCheckinStartTime != null and schCheckinStartTime != ''">
+				sch_checkin_start_time = #{schCheckinStartTime},
+			</if>
+			<if test="schCheckinEndTime != null and schCheckinEndTime != ''">
+				sch_checkin_end_time = #{schCheckinEndTime},
+			</if>
+			sys_user_id = #{sysUserId}
+		WHERE id = #{id}
+	</update>
+
+
 	<select id="getUserByQwUSerId" resultType="User">
 		select * from sys_user a
 		<where>

+ 187 - 0
src/main/resources/mappings/modules/wexintheorder/ClockInRecordSummarizingDao.xml

@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jeeplus.modules.wexintheorder.dao.ClockInRecordSummarizingDao">
+
+	<sql id="lockInRecordSummarizingColumns">
+		a.id,
+		a.create_by AS "createBy.id",
+		a.create_date as "createDate",
+		a.update_by AS "updateBy.id",
+		a.update_date as "updateDate",
+		a.del_flag as "",
+		a.remarks,
+		a.user_id as "userId",
+		a.checkin_date as "checkinDate",
+		a.work_class as "workClass",
+		a.earliest_time as "earliestTime",
+		a.latest_time as "latestTime",
+		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"
+	</sql>
+
+	<select id="findList" 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}
+
+			<if test="(userName != null and userName != '') or (sysUserId != null and sysUserId != '')">
+				AND su.name like concat('%',#{userName},'%')
+			</if>
+
+			<if test="office!=null and office.id=='' and office.name!=null and office.name!='' ">
+				and  so.name like concat('%',#{office.name},'%')
+			</if>
+
+			<if test="officeIdList!=null and officeIdList.size!=0">
+				and su.office_id in
+				<foreach collection="officeIdList" item="officeId" separator="," open="(" close=")">
+					#{officeId}
+				</foreach>
+			</if>
+
+			<if test="beginDate !=null">
+				AND a.checkin_date >= #{beginDate}
+			</if>
+			<if test="endDate !=null">
+				AND a.checkin_date &lt;= #{endDate}
+			</if>
+
+			<if test="sqlMap.dsf !=null and sqlMap.dsf!=''">
+				${sqlMap.dsf}
+			</if>
+		</where>
+		<choose>
+			<when test="page !=null and page.orderBy != null and page.orderBy != ''">
+				ORDER BY ${page.orderBy}
+			</when>
+			<otherwise>
+				ORDER BY user_id, checkin_date desc
+			</otherwise>
+		</choose>
+	</select>
+
+	<select id="queryCount" resultType="int" >
+		SELECT
+		count(distinct a.id)
+		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}
+
+
+			<if test="(userName != null and userName != '') or (sysUserId != null and sysUserId != '')">
+				AND su.name like concat('%',#{userName},'%')
+			</if>
+
+			<if test="office!=null and office.id=='' and office.name!=null and office.name!='' ">
+				and  so.name like concat('%',#{office.name},'%')
+			</if>
+
+			<if test="officeIdList!=null and officeIdList.size!=0">
+				and su.office_id in
+				<foreach collection="officeIdList" item="officeId" separator="," open="(" close=")">
+					#{officeId}
+				</foreach>
+			</if>
+
+			<if test="beginDate !=null">
+				AND a.checkin_date >= #{beginDate}
+			</if>
+			<if test="endDate !=null">
+				AND a.checkin_date &lt;= #{endDate}
+			</if>
+			<if test="sqlMap.dsf !=null and sqlMap.dsf!=''">
+				${sqlMap.dsf}
+			</if>
+		</where>
+	</select>
+
+
+	<insert id="insert">
+		INSERT INTO qw_clock_in_record_summarizing_info(
+			id,
+			create_by,
+			create_date,
+			update_by,
+			update_date,
+			remarks,
+			del_flag,
+			user_id,
+			checkin_date,
+			work_class,
+			earliest_time,
+			latest_time,
+			work_time,
+			sys_user_id,
+			sch_checkin_start_time,
+			sch_checkin_end_time
+		) VALUES (
+			#{id},
+			#{createBy.id},
+			#{createDate},
+			#{updateBy.id},
+			#{updateDate},
+			#{remarks},
+			#{delFlag},
+			#{userId},
+			#{checkinDate},
+			#{workClass},
+			#{earliestTime},
+			#{latestTime},
+			#{workTime},
+			#{sysUserId},
+			#{schCheckinStartTime},
+			#{schCheckinEndTime}
+
+		)
+	</insert>
+
+	<update id="update">
+		UPDATE qw_clock_in_record_summarizing_info SET
+			update_date = #{updateDate},
+			<if test="userId != null and userId != ''">
+				user_id = #{userId},
+			</if>
+			<if test="checkinDate != null and checkinDate != ''">
+				checkin_date = #{checkinDate},
+			</if>
+			<if test="workClass != null and workClass != ''">
+				work_class = #{workClass},
+			</if>
+			<if test="earliestTime != null and earliestTime != ''">
+				earliest_time = #{earliestTime},
+			</if>
+			<if test="latestTime != null and latestTime != ''">
+				latest_time = #{latestTime},
+			</if>
+			<if test="workTime != null and workTime != ''">
+				work_time = #{workTime},
+			</if>
+			<if test="schCheckinStartTime != null and schCheckinStartTime != ''">
+				sch_checkin_start_time = #{schCheckinStartTime},
+			</if>
+			<if test="schCheckinEndTime != null and schCheckinEndTime != ''">
+				sch_checkin_end_time = #{schCheckinEndTime},
+			</if>
+			sys_user_id = #{sysUserId}
+		WHERE id = #{id}
+	</update>
+
+
+	<select id="getUserByQwUSerId" resultType="User">
+		select * from sys_user a
+		<where>
+			a.qw_user_id = #{qwUserId} and a.del_flag = 0
+		</where>
+	</select>
+
+</mapper>

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

@@ -142,22 +142,24 @@
 					<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">
-								<form:input path="userName" htmlEscape="false" maxlength="255"  class=" form-control layui-input"/>
+					<%--<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>
+							<label class="layui-form-label">部门:</label>
 							<div class="layui-input-block with-icon">
-								<sys:treeselect id="area" name="area.id" value="${clockInRecordInfo.area.id}" labelName="area.name" labelValue="${clockInRecordInfo.area.name}"
-												title="区域" url="/sys/area/treeData" cssClass="form-control layui-input" allowClear="true" notAllowSelectParent="false" allowInput="true"/>
+								<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>
 
-						<%--<div class="layui-item athird">
+						<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">
@@ -165,12 +167,12 @@
 									<button id="searchReset" class="layui-btn layui-btn-sm " onclick="resetSearch()">重置</button>
 								</div>
 							</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>--%>
+					<%--<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"/>"/>
@@ -180,16 +182,16 @@
 									   value="<fmt:formatDate value="${clockInRecordInfo.endDate}" pattern="yyyy-MM-dd"/>"/>
 								</input>
 							</div>
-						</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><!-- 导出按钮 -->
@@ -197,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>
@@ -218,11 +220,11 @@
             ,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:'schCheckinTime', align:'center',title: '理论打卡时间',width:150}
                 ,{field:'wifiName',align:'center', title: '打卡wifi名称', width:120}
             ]]
             ,data: [
@@ -239,6 +241,7 @@
 					,"checkinTime":"${clockInRecordInfo.checkinTime}"
 					,"schCheckinTime":"${clockInRecordInfo.schCheckinTime}"
                     ,"wifiName":"${clockInRecordInfo.wifiName}"
+                    ,"officeName":"${clockInRecordInfo.office.name}"
                 }
                 </c:forEach>
                 </c:if>

+ 267 - 0
src/main/webapp/webpage/modules/qw/clickInRecode/ClickInRecordSummarizingList.jsp

@@ -0,0 +1,267 @@
+<%@ 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="clockInRecordSummarizingInfo" action="${ctx}/clockInRecordSummarizingController/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="${clockInRecordSummarizingInfo.sysUserId}" labelName="userName" labelValue="${clockInRecordSummarizingInfo.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="${clockInRecordSummarizingInfo.office.id}" labelName="office.name" labelValue="${clockInRecordSummarizingInfo.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="${clockInRecordSummarizingInfo.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="${clockInRecordSummarizingInfo.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="clockInRecordSummarizing:clockInRecordSummarizing:export">
+							<table:exportExcel url="${ctx}/clockInRecordSummarizingController/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: '姓名',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:'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}
+            ]]
+            ,data: [
+                <c:if test="${ not empty page.list}">
+                <c:forEach items="${page.list}" var="clockInRecordSummarizingInfo" varStatus="index">
+                <c:if test="${index.index != 0}">,</c:if>
+                {
+                    "index":"${index.index+1}"
+                    ,"id":"${clockInRecordSummarizingInfo.id}"
+                    ,"userName":"${clockInRecordSummarizingInfo.userName}"
+                    ,"officeName":"${clockInRecordSummarizingInfo.office.name}"
+					,"checkinDate":"${clockInRecordSummarizingInfo.checkinDate}"
+					,"workClass":"${clockInRecordSummarizingInfo.workClass}"
+					,"earliestTime":"${clockInRecordSummarizingInfo.earliestTime}"
+					,"latestTime":"${clockInRecordSummarizingInfo.latestTime}"
+					,"workTime":"${clockInRecordSummarizingInfo.workTime}"
+                }
+                </c:forEach>
+                </c:if>
+            ]
+        });
+
+    })
+
+    resizeListTable();/*消除由于有竖向滚动条造成table出现横向滚动条*/
+    $("a").on("click",addLinkVisied);
+</script>
+
+<script type="text/javascript">
+    resizeListWindow1();
+    $(window).resize(function(){
+        resizeListWindow1();
+    });
+</script>
+</body>
+
+</html>
+