1811872455@163.com 3 недель назад
Родитель
Сommit
e95a09bd6b
38 измененных файлов с 1402 добавлено и 62 удалено
  1. 4 0
      .idea/encodings.xml
  2. 3 3
      storlead-centre-api/src/main/java/com/storlead/centre/ChenkqGeneratorCodeConfig.java
  3. 36 0
      storlead-centre-api/src/main/java/com/storlead/centre/dispatch/AttendanceSignDispatchTask.java
  4. 87 0
      storlead-centre-api/src/main/java/com/storlead/centre/dispatch/SyncAttendanceSignToOaTask.java
  5. 103 0
      storlead-centre-api/src/main/java/com/storlead/centre/vo/SignDataConvert.java
  6. 6 0
      storlead-centre-service/pom.xml
  7. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/controller/AttendanceSignRecordController.java
  8. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/controller/HrmschedulesignController.java
  9. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/controller/HrmschedulesignRemindController.java
  10. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/controller/SystemConfigItemController.java
  11. 128 0
      storlead-centre-service/src/main/java/com/storlead/centre/entity/AttendanceSignRecordEntity.java
  12. 88 0
      storlead-centre-service/src/main/java/com/storlead/centre/entity/HrmschedulesignEntity.java
  13. 51 0
      storlead-centre-service/src/main/java/com/storlead/centre/entity/HrmschedulesignRemindEntity.java
  14. 60 0
      storlead-centre-service/src/main/java/com/storlead/centre/entity/SystemConfigItemEntity.java
  15. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/AttendanceSignRecordMapper.java
  16. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/HrmschedulesignMapper.java
  17. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/HrmschedulesignRemindMapper.java
  18. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/SystemConfigItemMapper.java
  19. 32 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/HrmschedulesignMapper.xml
  20. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/HrmschedulesignRemindMapper.xml
  21. 37 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/SystemConfigItemMapper.xml
  22. 26 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/AttendanceSignRecordService.java
  23. 18 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/HrmschedulesignRemindService.java
  24. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/HrmschedulesignService.java
  25. 24 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/SystemConfigItemService.java
  26. 225 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/impl/AttendanceSignRecordServiceImpl.java
  27. 23 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/impl/HrmschedulesignRemindServiceImpl.java
  28. 24 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/impl/HrmschedulesignServiceImpl.java
  29. 53 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/impl/SystemConfigItemServiceImpl.java
  30. 52 0
      storlead-centre-service/src/main/resources/mapper/AttendanceSignRecordMapper.xml
  31. 37 0
      storlead-centre-service/src/main/resources/mapper/SystemConfigItemMapper.xml
  32. 32 0
      storlead-centre-service/src/main/resources/oa/mapper/HrmschedulesignMapper.xml
  33. 20 0
      storlead-centre-service/src/main/resources/oa/mapper/HrmschedulesignRemindMapper.xml
  34. 36 38
      storlead-wx/src/main/java/com/storlead/wx/pojo/vo/CheckinDataBo.java
  35. 1 1
      storlead-wx/src/main/java/com/storlead/wx/properties/CorpWeChatConstants.java
  36. 2 1
      storlead-wx/src/main/java/com/storlead/wx/service/CorpWeChatService.java
  37. 3 6
      storlead-wx/src/main/java/com/storlead/wx/service/impl/CorpWeChatServiceImpl.java
  38. 11 13
      storlead-wx/src/main/java/com/storlead/wx/util/CorpWechatUtil.java

+ 4 - 0
.idea/encodings.xml

@@ -1,9 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="Encoding">
+    <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/storlead-centre-api/src/main/java" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/storlead-centre-api/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/storlead-centre-service/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/storlead-framework/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/storlead-framework/src/main/resources" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/storlead-framework/storlead-auth/src/main/java" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/storlead-framework/storlead-common/src/main/java" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/storlead-framework/storlead-core/src/main/java" charset="UTF-8" />

+ 3 - 3
storlead-centre-api/src/main/java/com/storlead/centre/ChenkqGeneratorCodeConfig.java

@@ -134,9 +134,9 @@ public class ChenkqGeneratorCodeConfig {
         strategy.setControllerMappingHyphenStyle(true);
         strategy.setEntityTableFieldAnnotationEnable(true);
 
-        strategy.setSuperMapperClass("com.storlead.frameworkmybatis.mapper.MyBaseMapper");
-        strategy.setSuperServiceClass("com.storlead.frameworkmybatis.service.MyBaseService");
-        strategy.setSuperServiceImplClass("com.storlead.frameworkmybatis.service.impl.MyBaseServiceImpl");
+        strategy.setSuperMapperClass("com.storlead.framework.mybatis.mapper.MyBaseMapper");
+        strategy.setSuperServiceClass("com.storlead.framework.mybatis.service.MyBaseService");
+        strategy.setSuperServiceImplClass("com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl");
         strategy.setEntityLombokModel(true);
         // 公共父类
 //        strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");

+ 36 - 0
storlead-centre-api/src/main/java/com/storlead/centre/dispatch/AttendanceSignDispatchTask.java

@@ -0,0 +1,36 @@
+package com.storlead.centre.dispatch;
+
+import com.storlead.centre.service.AttendanceSignRecordService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.text.ParseException;
+import java.util.Date;
+
+/**
+ * @program: storlead-centre-platform
+ * @description:
+ * @author: chenkq
+ * @create: 2026-01-07 14:57
+ */
+
+@Slf4j
+@Component
+public class AttendanceSignDispatchTask {
+
+    @Resource
+    private AttendanceSignRecordService attendanceSignRecordService;
+
+    /**
+     * 同步考勤数据
+     * @throws ParseException
+     */
+    @Scheduled(cron ="0 * * * * ? ")
+    public void syncSignData() throws ParseException {
+        log.error("开始时间--"+new Date());
+        log.info("oa company dept job user sync task starting ----");
+        attendanceSignRecordService.getSaveSignRecord();
+    }
+}

+ 87 - 0
storlead-centre-api/src/main/java/com/storlead/centre/dispatch/SyncAttendanceSignToOaTask.java

@@ -0,0 +1,87 @@
+package com.storlead.centre.dispatch;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.storlead.centre.entity.AttendanceSignRecordEntity;
+import com.storlead.centre.entity.HrmschedulesignEntity;
+import com.storlead.centre.entity.HrmschedulesignRemindEntity;
+import com.storlead.centre.service.AttendanceSignRecordService;
+import com.storlead.centre.service.HrmschedulesignRemindService;
+import com.storlead.centre.service.HrmschedulesignService;
+import com.storlead.centre.vo.SignDataConvert;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.text.ParseException;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @program: 同步考勤数据到OA
+ * @description:
+ * @author: chenkq
+ * @create: 2026-01-08 11:12
+ */
+@Slf4j
+@Component
+public class SyncAttendanceSignToOaTask {
+
+    @Resource
+    private AttendanceSignRecordService attendanceSignRecordService;
+    @Resource
+    private HrmschedulesignRemindService hrmschedulesignRemindService;
+    @Resource
+    private HrmschedulesignService hrmschedulesignService;
+
+    @Scheduled(cron ="0 * * * * ? ")
+    public void syncSignData() throws ParseException {
+        // 获取未同步的数据到
+        LambdaQueryWrapper<AttendanceSignRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(AttendanceSignRecordEntity::getSyncOa,Integer.valueOf(0));
+        List<AttendanceSignRecordEntity> attendances = attendanceSignRecordService.list(lambdaQueryWrapper);
+
+        if (CollectionUtils.isEmpty(attendances)) {
+            return;
+        }
+        List<Long> ids = attendances.stream().map(AttendanceSignRecordEntity::getId).collect(Collectors.toList());
+
+        LambdaUpdateWrapper<AttendanceSignRecordEntity> oawp = new LambdaUpdateWrapper<>();
+        oawp.set(AttendanceSignRecordEntity::getSyncOa,Integer.valueOf(1));
+        oawp.in(AttendanceSignRecordEntity::getId,ids);
+        attendanceSignRecordService.update(oawp);
+        //同步OA数据
+        List<HrmschedulesignEntity> hrmschedulesignsDb = new ArrayList<>();
+        List<HrmschedulesignEntity> hrmschedulesigns = SignDataConvert.attendanceListToOaSignVoList(attendances);
+        if (!CollectionUtils.isEmpty(hrmschedulesigns)) {
+            List<Long> bmd = Arrays.asList(408L);
+            if (!CollectionUtils.isEmpty(bmd)) {
+                hrmschedulesignsDb = hrmschedulesigns.stream().filter(e ->bmd.contains(e.getUserid())).collect(Collectors.toList());
+            } else {
+                hrmschedulesignsDb = hrmschedulesigns;
+            }
+            if (!CollectionUtils.isEmpty(hrmschedulesignsDb)) {
+                hrmschedulesignService.saveBatch(hrmschedulesignsDb);
+            }
+        }
+
+        List<HrmschedulesignRemindEntity> hrmschedulesignremindsDb = new ArrayList<>();
+        List<HrmschedulesignRemindEntity> hrmschedulesignreminds = SignDataConvert.attendanceListToOaSignRemindVoList(attendances);
+        if (!CollectionUtils.isEmpty(hrmschedulesignreminds)) {
+            List<Integer> bmd = Arrays.asList(408);
+            if (!CollectionUtils.isEmpty(bmd)) {
+                hrmschedulesignremindsDb = hrmschedulesignreminds.stream().filter(e ->bmd.contains(e.getUserid())).collect(Collectors.toList());
+            } else {
+                hrmschedulesignremindsDb = hrmschedulesignreminds;
+            }
+            if (!CollectionUtils.isEmpty(hrmschedulesignremindsDb)) {
+                hrmschedulesignRemindService.saveBatch(hrmschedulesignremindsDb);
+            }
+        }
+    }
+
+}

+ 103 - 0
storlead-centre-api/src/main/java/com/storlead/centre/vo/SignDataConvert.java

@@ -0,0 +1,103 @@
+package com.storlead.centre.vo;
+
+import com.alibaba.fastjson.JSON;
+import com.storlead.centre.entity.AttendanceSignRecordEntity;
+import com.storlead.centre.entity.HrmschedulesignEntity;
+import com.storlead.centre.entity.HrmschedulesignRemindEntity;
+import com.storlead.wx.pojo.vo.CheckinDataBO;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.util.CollectionUtils;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @program: storlead-centre-platform
+ * @description:
+ * @author: chenkq
+ * @create: 2026-01-09 10:51
+ */
+@Log4j2
+public class SignDataConvert {
+
+    private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+    public static List<HrmschedulesignEntity> attendanceListToOaSignVoList(List<AttendanceSignRecordEntity> vals) {
+        if (CollectionUtils.isEmpty(vals)) {
+            return null;
+        }
+        List<HrmschedulesignEntity> departmentTrees = vals.stream().map(SignDataConvert::attendanceToOaSignVo).filter(obj -> !Objects.isNull(obj)).collect(Collectors.toList());
+        return departmentTrees;
+    }
+
+    public static HrmschedulesignEntity  attendanceToOaSignVo(AttendanceSignRecordEntity attendance) {
+        if (null == attendance) {
+            return null;
+        }
+        try {
+            HrmschedulesignEntity entity = new HrmschedulesignEntity();
+            entity.setUserid(attendance.getUserId());
+            // 1 签到,2:签退
+            if ("上班打卡".equals(attendance.getCheckinType())) {
+                entity.setSigntype("1");
+            } else if ("下班打卡".equals(attendance.getCheckinType())){
+                entity.setSigntype("2");
+            }
+            String checkData = attendance.getCheckinDate().format(formatter);
+            entity.setUsertype("1");
+            entity.setSigndate(checkData);
+            entity.setSigntime(attendance.getCheckinTime());
+            entity.setClientAddress("");
+            entity.setIsincom("1");
+            entity.setSignfrom("Wechat");
+            entity.setLatitude(attendance.getLatitude());
+            entity.setLongitude(attendance.getLongitude());
+            entity.setAddr(attendance.getLocationTitle());
+            entity.setTimeZone("GMT+8");
+            entity.setBelongdate(checkData);
+            Map map = new HashMap();
+            map.put("deviceId",attendance.getDeviceId());
+            entity.setDeviceInfo(JSON.toJSONString(map));
+            return entity;
+        }catch (Exception e) {
+            return null;
+        }
+    }
+
+
+    public static List<HrmschedulesignRemindEntity> attendanceListToOaSignRemindVoList(List<AttendanceSignRecordEntity> vals) {
+        if (CollectionUtils.isEmpty(vals)) {
+            return null;
+        }
+        List<HrmschedulesignRemindEntity> departmentTrees = vals.stream().map(SignDataConvert::attendanceToOaSignRemindVo).filter(obj -> !Objects.isNull(obj)).collect(Collectors.toList());
+        return departmentTrees;
+    }
+
+    public static HrmschedulesignRemindEntity  attendanceToOaSignRemindVo(AttendanceSignRecordEntity attendance) {
+        if (null == attendance) {
+            return null;
+        }
+        try {
+            HrmschedulesignRemindEntity entity = new HrmschedulesignRemindEntity();
+            entity.setUserid(attendance.getUserId().intValue());
+            // 1 签到,2:签退
+            if ("上班打卡".equals(attendance.getCheckinType())) {
+                entity.setSigntype("1");
+            } else if ("下班打卡".equals(attendance.getCheckinType())){
+                entity.setSigntype("2");
+            }
+            String checkData = attendance.getCheckinDate().format(formatter);
+            entity.setSigndate(checkData);
+            entity.setSigntime(attendance.getCheckinTime());
+            entity.setBelongdate(checkData);
+            return entity;
+        }catch (Exception e) {
+            return null;
+        }
+    }
+}

+ 6 - 0
storlead-centre-service/pom.xml

@@ -38,6 +38,12 @@
             <version>1.0</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.storlead.boot</groupId>
+            <artifactId>storlead-user</artifactId>
+            <version>1.0</version>
+        </dependency>
+
         <dependency>
             <groupId>com.storlead.boot</groupId>
             <artifactId>storlead-mybatis</artifactId>

+ 20 - 0
storlead-centre-service/src/main/java/com/storlead/centre/controller/AttendanceSignRecordController.java

@@ -0,0 +1,20 @@
+package com.storlead.centre.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * OA系统签到/签退记录表 前端控制器
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-04
+ */
+@RestController
+@RequestMapping("/attendance/sign")
+public class AttendanceSignRecordController {
+
+}

+ 20 - 0
storlead-centre-service/src/main/java/com/storlead/centre/controller/HrmschedulesignController.java

@@ -0,0 +1,20 @@
+package com.storlead.centre.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-05
+ */
+@RestController
+@RequestMapping("/hrmschedulesign-entity")
+public class HrmschedulesignController {
+
+}

+ 20 - 0
storlead-centre-service/src/main/java/com/storlead/centre/controller/HrmschedulesignRemindController.java

@@ -0,0 +1,20 @@
+package com.storlead.centre.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-05
+ */
+@RestController
+@RequestMapping("/hrmschedulesign-remind-entity")
+public class HrmschedulesignRemindController {
+
+}

+ 20 - 0
storlead-centre-service/src/main/java/com/storlead/centre/controller/SystemConfigItemController.java

@@ -0,0 +1,20 @@
+package com.storlead.centre.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 系统配置项 前端控制器
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-08
+ */
+@RestController
+@RequestMapping("/system-config-item-entity")
+public class SystemConfigItemController {
+
+}

+ 128 - 0
storlead-centre-service/src/main/java/com/storlead/centre/entity/AttendanceSignRecordEntity.java

@@ -0,0 +1,128 @@
+package com.storlead.centre.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import java.time.LocalDate;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.storlead.framework.mybatis.entity.SysBaseField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * <p>
+ * OA系统签到/签退记录表
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+@TableName("attendance_sign_record")
+@ApiModel(value="AttendanceSignRecordEntity对象", description="OA系统签到/签退记录表")
+public class AttendanceSignRecordEntity extends SysBaseField {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "微信Id")
+    @TableField("wx_user_id")
+    private String wxUserId;
+
+    @ApiModelProperty(value = "员工ID")
+    @TableField("user_id")
+    private Long userId;
+
+    @ApiModelProperty(value = "员工姓名(冗余)")
+    @TableField("user_name")
+    private String userName;
+
+    @ApiModelProperty(value = "部门ID")
+    @TableField("dept_id")
+    private Long deptId;
+
+    @ApiModelProperty(value = "部门名称(冗余)")
+    @TableField("dept_name")
+    private String deptName;
+
+    @ApiModelProperty(value = "考勤组ID")
+    @TableField("group_id")
+    private Long groupId;
+
+    @ApiModelProperty(value = "考勤组名称")
+    @TableField("group_name")
+    private String groupName;
+
+    @ApiModelProperty(value = "打卡类型:ON_DUTY上班 OFF_DUTY下班")
+    @TableField("checkin_type")
+    private String checkinType;
+
+    @ApiModelProperty(value = "是否同步OA:0 未同步,1:已同步")
+    @TableField("sync_oa")
+    private Integer syncOa;
+
+    @ApiModelProperty(value = "异常类型:NORMAL LATE EARLY ABSENT")
+    @TableField("exception_type")
+    private String exceptionType;
+
+    @TableField("checkin_wx_time")
+    private Long checkinWxTime;
+
+    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern="yyyy-MM-dd")
+    @TableField("checkin_date")
+    private LocalDate checkinDate;
+
+    @ApiModelProperty(value = "打卡时间(Unix时间戳,秒)")
+    @TableField("checkin_time")
+    private String checkinTime;
+
+
+    @ApiModelProperty(value = "打卡地点名称")
+    @TableField("location_title")
+    private String locationTitle;
+
+    @ApiModelProperty(value = "打卡地点详细地址")
+    @TableField("location_detail")
+    private String locationDetail;
+
+    @ApiModelProperty(value = "WiFi 名称")
+    @TableField("wifi_name")
+    private String wifiName;
+
+    @ApiModelProperty(value = "WiFi MAC 地址")
+    @TableField("wifi_mac")
+    private String wifiMac;
+
+    @ApiModelProperty(value = "经度(放大后的整型)")
+    @TableField("longitude")
+    private String longitude;
+
+    @ApiModelProperty(value = "纬度(放大后的整型)")
+    @TableField("latitude")
+    private String latitude;
+
+    @ApiModelProperty(value = "设备唯一标识")
+    @TableField("device_id")
+    private String deviceId;
+
+    @ApiModelProperty(value = "打卡媒体ID列表(JSON数组)")
+    @TableField("media_ids")
+    private String mediaIds;
+
+    @ApiModelProperty(value = "打卡备注")
+    @TableField("remark")
+    private String remark;
+
+
+}

+ 88 - 0
storlead-centre-service/src/main/java/com/storlead/centre/entity/HrmschedulesignEntity.java

@@ -0,0 +1,88 @@
+package com.storlead.centre.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.storlead.framework.mybatis.entity.SysBaseField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-05
+ */
+@Data
+@Accessors(chain = true)
+@TableName("hrmschedulesign")
+@ApiModel(value="HrmschedulesignEntity对象", description="")
+public class HrmschedulesignEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "自增主键")
+    @TableId(value = "ID", type = IdType.AUTO)
+    private Integer id;
+
+    @TableField("USERID")
+    private Long userid;
+
+    @TableField("USERTYPE")
+    private String usertype;
+
+    @TableField("SIGNTYPE")
+    private String signtype;
+
+    @TableField("SIGNDATE")
+    private String signdate;
+
+    @TableField("SIGNTIME")
+    private String signtime;
+
+    @TableField("clientAddress")
+    private String clientAddress;
+
+    @TableField("ISINCOM")
+    private String isincom;
+
+    @TableField("SIGNFROM")
+    private String signfrom;
+
+    @TableField("LONGITUDE")
+    private String longitude;
+
+    @TableField("LATITUDE")
+    private String latitude;
+
+    @TableField("ADDR")
+    private String addr;
+
+    @TableField("ISIMPORT")
+    private Integer isimport;
+
+    @TableField("SUUID")
+    private String suuid;
+
+    @TableField("timeZone")
+    private String timeZone;
+
+    @TableField("belongdate")
+    private String belongdate;
+
+    @TableField("memo")
+    private String memo;
+
+    @TableField("deviceInfo")
+    private String deviceInfo;
+
+
+}

+ 51 - 0
storlead-centre-service/src/main/java/com/storlead/centre/entity/HrmschedulesignRemindEntity.java

@@ -0,0 +1,51 @@
+package com.storlead.centre.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.storlead.framework.mybatis.entity.SysBaseField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-05
+ */
+@Data
+@Accessors(chain = true)
+@TableName("hrmschedulesign_remind")
+@ApiModel(value="HrmschedulesignRemindEntity对象", description="")
+public class HrmschedulesignRemindEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @TableField("userid")
+    private Integer userid;
+
+    @TableField("signtype")
+    private String signtype;
+
+    @TableField("signdate")
+    private String signdate;
+
+    @TableField("signtime")
+    private String signtime;
+
+    @TableField("belongdate")
+    private String belongdate;
+
+
+}

+ 60 - 0
storlead-centre-service/src/main/java/com/storlead/centre/entity/SystemConfigItemEntity.java

@@ -0,0 +1,60 @@
+package com.storlead.centre.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.storlead.framework.mybatis.entity.SysBaseField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 系统配置项
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-08
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+@TableName("system_config_item")
+@ApiModel(value="SystemConfigItemEntity对象", description="系统配置项")
+public class SystemConfigItemEntity extends SysBaseField {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键id")
+    @TableId(value = "item_id", type = IdType.AUTO)
+    private Long itemId;
+
+    @ApiModelProperty(value = "配置项名称")
+    @TableField("item_name")
+    private String itemName;
+
+    @ApiModelProperty(value = "配置键值编码")
+    @TableField("item_code")
+    private String itemCode;
+
+    @ApiModelProperty(value = "配置项数据类型:0:字符串,1:整数,2:小数,3:金额, 4:时间, 5:日期")
+    @TableField("item_data_type")
+    private Integer itemDataType;
+
+    @ApiModelProperty(value = "数据格式要求")
+    @TableField("item_data_format_desc")
+    private String itemDataFormatDesc;
+
+    @ApiModelProperty(value = "数据格式正则脚本")
+    @TableField("item_format_value")
+    private String itemFormatValue;
+
+    @ApiModelProperty(value = "描述")
+    @TableField("item_desc")
+    private String itemDesc;
+
+
+}

+ 16 - 0
storlead-centre-service/src/main/java/com/storlead/centre/mapper/AttendanceSignRecordMapper.java

@@ -0,0 +1,16 @@
+package com.storlead.centre.mapper;
+
+import com.storlead.centre.entity.AttendanceSignRecordEntity;
+import com.storlead.framework.mybatis.mapper.MyBaseMapper;
+
+/**
+ * <p>
+ * OA系统签到/签退记录表 Mapper 接口
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-04
+ */
+public interface AttendanceSignRecordMapper extends MyBaseMapper<AttendanceSignRecordEntity> {
+
+}

+ 16 - 0
storlead-centre-service/src/main/java/com/storlead/centre/mapper/HrmschedulesignMapper.java

@@ -0,0 +1,16 @@
+package com.storlead.centre.mapper;
+
+import com.storlead.centre.entity.HrmschedulesignEntity;
+import com.storlead.framework.mybatis.mapper.MyBaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-05
+ */
+public interface HrmschedulesignMapper extends MyBaseMapper<HrmschedulesignEntity> {
+
+}

+ 16 - 0
storlead-centre-service/src/main/java/com/storlead/centre/mapper/HrmschedulesignRemindMapper.java

@@ -0,0 +1,16 @@
+package com.storlead.centre.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.storlead.centre.entity.HrmschedulesignRemindEntity;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-05
+ */
+public interface HrmschedulesignRemindMapper extends BaseMapper<HrmschedulesignRemindEntity> {
+
+}

+ 16 - 0
storlead-centre-service/src/main/java/com/storlead/centre/mapper/SystemConfigItemMapper.java

@@ -0,0 +1,16 @@
+package com.storlead.centre.mapper;
+
+import com.storlead.centre.entity.SystemConfigItemEntity;
+import com.storlead.framework.mybatis.mapper.MyBaseMapper;
+
+/**
+ * <p>
+ * 系统配置项 Mapper 接口
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-08
+ */
+public interface SystemConfigItemMapper extends MyBaseMapper<SystemConfigItemEntity> {
+
+}

+ 32 - 0
storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/HrmschedulesignMapper.xml

@@ -0,0 +1,32 @@
+<?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.storlead.centre.mapper.HrmschedulesignMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.HrmschedulesignEntity">
+        <id column="ID" property="id" />
+        <result column="USERID" property="userid" />
+        <result column="USERTYPE" property="usertype" />
+        <result column="SIGNTYPE" property="signtype" />
+        <result column="SIGNDATE" property="signdate" />
+        <result column="SIGNTIME" property="signtime" />
+        <result column="clientAddress" property="clientAddress" />
+        <result column="ISINCOM" property="isincom" />
+        <result column="SIGNFROM" property="signfrom" />
+        <result column="LONGITUDE" property="longitude" />
+        <result column="LATITUDE" property="latitude" />
+        <result column="ADDR" property="addr" />
+        <result column="ISIMPORT" property="isimport" />
+        <result column="SUUID" property="suuid" />
+        <result column="timeZone" property="timeZone" />
+        <result column="belongdate" property="belongdate" />
+        <result column="memo" property="memo" />
+        <result column="deviceInfo" property="deviceInfo" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        ID, USERID, USERTYPE, SIGNTYPE, SIGNDATE, SIGNTIME, clientAddress, ISINCOM, SIGNFROM, LONGITUDE, LATITUDE, ADDR, ISIMPORT, SUUID, timeZone, belongdate, memo, deviceInfo
+    </sql>
+
+</mapper>

+ 20 - 0
storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/HrmschedulesignRemindMapper.xml

@@ -0,0 +1,20 @@
+<?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.storlead.centre.mapper.HrmschedulesignRemindMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.HrmschedulesignRemindEntity">
+        <id column="id" property="id" />
+        <result column="userid" property="userid" />
+        <result column="signtype" property="signtype" />
+        <result column="signdate" property="signdate" />
+        <result column="signtime" property="signtime" />
+        <result column="belongdate" property="belongdate" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, userid, signtype, signdate, signtime, belongdate
+    </sql>
+
+</mapper>

+ 37 - 0
storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/SystemConfigItemMapper.xml

@@ -0,0 +1,37 @@
+<?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.storlead.centre.mapper.SystemConfigItemMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.SystemConfigItemEntity">
+        <id column="item_id" property="itemId" />
+    <result column="create_time" property="createTime" />
+    <result column="update_time" property="updateTime" />
+    <result column="is_delete" property="isDelete" />
+    <result column="enabled" property="enabled" />
+    <result column="create_by" property="createBy" />
+    <result column="owner_by" property="ownerBy" />
+    <result column="update_by" property="updateBy" />
+    <result column="sort" property="sort" />
+        <result column="item_name" property="itemName" />
+        <result column="item_code" property="itemCode" />
+        <result column="item_data_type" property="itemDataType" />
+        <result column="item_data_format_desc" property="itemDataFormatDesc" />
+        <result column="item_format_value" property="itemFormatValue" />
+        <result column="item_desc" property="itemDesc" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        create_time,
+        update_time,
+        is_delete,
+        enabled,
+        create_by,
+        owner_by,
+        update_by,
+        sort,
+        item_id, item_name, item_code, item_data_type, item_data_format_desc, item_format_value, item_desc
+    </sql>
+
+</mapper>

+ 26 - 0
storlead-centre-service/src/main/java/com/storlead/centre/service/AttendanceSignRecordService.java

@@ -0,0 +1,26 @@
+package com.storlead.centre.service;
+
+import com.storlead.centre.entity.AttendanceSignRecordEntity;
+import com.storlead.wx.pojo.vo.CheckinDataBO;
+import com.storlead.framework.mybatis.service.MyBaseService;
+
+import java.util.List;
+
+/**
+ * <p>
+ * OA系统签到/签退记录表 服务类
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-04
+ */
+public interface AttendanceSignRecordService extends MyBaseService<AttendanceSignRecordEntity> {
+
+    void getSaveSignRecord();
+    /**
+     * 获取打卡信息
+     */
+    List<CheckinDataBO> getSaveSignRecord(List<String> wxUserIds,Integer opencheckindatatype,Long starttime,Long endtime);
+
+    List<AttendanceSignRecordEntity> getSignSyncRecord();
+}

+ 18 - 0
storlead-centre-service/src/main/java/com/storlead/centre/service/HrmschedulesignRemindService.java

@@ -0,0 +1,18 @@
+package com.storlead.centre.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.storlead.centre.entity.HrmschedulesignRemindEntity;
+import com.storlead.framework.mybatis.service.MyBaseService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-05
+ */
+public interface HrmschedulesignRemindService extends IService<HrmschedulesignRemindEntity> {
+
+}

+ 16 - 0
storlead-centre-service/src/main/java/com/storlead/centre/service/HrmschedulesignService.java

@@ -0,0 +1,16 @@
+package com.storlead.centre.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.storlead.centre.entity.HrmschedulesignEntity;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-05
+ */
+public interface HrmschedulesignService extends IService<HrmschedulesignEntity> {
+
+}

+ 24 - 0
storlead-centre-service/src/main/java/com/storlead/centre/service/SystemConfigItemService.java

@@ -0,0 +1,24 @@
+package com.storlead.centre.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.storlead.centre.entity.SystemConfigItemEntity;
+import com.storlead.framework.mybatis.service.MyBaseService;
+
+import java.util.Objects;
+
+/**
+ * <p>
+ * 系统配置项 服务类
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-08
+ */
+public interface SystemConfigItemService extends MyBaseService<SystemConfigItemEntity> {
+
+    SystemConfigItemEntity getSystemConfigItem(String code);
+
+    Long getCheckinDataTime();
+
+    void setCheckinDataTime(Long checkinTime);
+}

+ 225 - 0
storlead-centre-service/src/main/java/com/storlead/centre/service/impl/AttendanceSignRecordServiceImpl.java

@@ -0,0 +1,225 @@
+package com.storlead.centre.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.storlead.centre.entity.AttendanceSignRecordEntity;
+import com.storlead.centre.mapper.AttendanceSignRecordMapper;
+import com.storlead.centre.service.SystemConfigItemService;
+import com.storlead.framework.common.constant.CommonConstant;
+import com.storlead.framework.common.util.DateUtils;
+import com.storlead.user.pojo.entity.JobEntity;
+import com.storlead.user.pojo.entity.UserEntity;
+import com.storlead.user.service.IUserService;
+import com.storlead.user.service.impl.UserServiceImpl;
+import com.storlead.wx.pojo.vo.CheckinDataBO;
+import com.storlead.centre.service.AttendanceSignRecordService;
+import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
+import com.storlead.wx.service.CorpWeChatService;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * OA系统签到/签退记录表 服务实现类
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-04
+ */
+@Log4j2
+@Service
+public class AttendanceSignRecordServiceImpl extends MyBaseServiceImpl<AttendanceSignRecordMapper, AttendanceSignRecordEntity> implements AttendanceSignRecordService {
+
+    @Resource
+    private CorpWeChatService corpWeChatService;
+    @Resource
+    private SystemConfigItemService systemConfigItemService;
+
+    @Resource
+    private IUserService userService;
+
+    @Override
+    public void getSaveSignRecord() {
+
+        LambdaQueryWrapper<UserEntity> lm = new LambdaQueryWrapper<>();
+        lm.isNotNull(UserEntity::getXworkUserId);
+        lm.ne(UserEntity::getXworkUserId,"");
+        lm.eq(UserEntity::getIsDelete,CommonConstant.DEL_FLAG_0);
+        lm.eq(UserEntity::getEnabled,1);
+        List<UserEntity> userEntities = userService.list(lm);
+        if (CollectionUtils.isEmpty(userEntities)) {
+            return;
+        }
+        Map<String, UserEntity> userMap = userEntities.stream()
+                .filter(u -> u.getXworkUserId() != null)
+                .collect(Collectors.toMap(
+                        UserEntity::getXworkUserId,
+                        userEntity -> userEntity,
+                        (oldVal, newVal) -> oldVal
+                ));
+        List<String> wxUserIds = userEntities.stream().map(UserEntity::getXworkUserId).collect(Collectors.toList());
+        List<CheckinDataBO> checkins = new ArrayList<>();
+
+        Long currentTime = System.currentTimeMillis() / 1000;
+        Long starttime =  systemConfigItemService.getCheckinDataTime();
+        Long endtime = currentTime;
+
+        int batchSize = 90;
+        for (int i = 0; i < wxUserIds.size(); i += batchSize) {
+            int end = Math.min(i + batchSize, wxUserIds.size());
+            List<String> subList = wxUserIds.subList(i, end);
+            List<CheckinDataBO> batchResult = getSaveSignRecord(subList,3,starttime,endtime);
+            if (batchResult != null && !batchResult.isEmpty()) {
+                checkins.addAll(batchResult);
+            }
+        }
+
+        LocalDateTime dateTime = timestampToLocalDateTime(endtime);
+        String time = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+        log.error(endtime+"---------跑到了这里-----"+time);
+        systemConfigItemService.setCheckinDataTime(endtime);
+        if (CollectionUtils.isEmpty(checkins)) {
+            return;
+        }
+        List<AttendanceSignRecordEntity> signls = appPageInfoListToAppPageTreeVoList(checkins);
+        if (CollectionUtils.isEmpty(signls)) {
+            return ;
+        }
+        for (AttendanceSignRecordEntity signRecord : signls) {
+            UserEntity user = userMap.get(signRecord.getWxUserId());
+            if (Objects.nonNull(user)) {
+                signRecord.setUserId(user.getId());
+                signRecord.setUserName(user.getRealName());
+                signRecord.setDeptId(user.getDeptId());
+            }
+        }
+        // 保存打卡记录
+        this.saveBatch(signls);
+    }
+    /**
+     * 获取打卡信息
+     */
+    @Override
+    public List<CheckinDataBO> getSaveSignRecord(List<String> wxUserIds,Integer opencheckindatatype,Long starttime,Long endtime) {
+
+        List<CheckinDataBO> checkinds =  corpWeChatService.getCheckinDayData(wxUserIds,starttime,endtime,opencheckindatatype);
+        // 存储打卡信息
+        if (CollectionUtils.isEmpty(checkinds)) {
+            return null;
+        }
+
+        return checkinds;
+    }
+
+    /**
+     * 获取需要同步的数据进行同步
+     * @return
+     */
+    public List<AttendanceSignRecordEntity> getSignSyncRecord() {
+
+        LambdaQueryWrapper<AttendanceSignRecordEntity> wq = new LambdaQueryWrapper<>();
+        wq.eq(AttendanceSignRecordEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+        wq.eq(AttendanceSignRecordEntity::getSyncOa,Integer.valueOf(0));
+        List<AttendanceSignRecordEntity> recordls = this.list(wq);
+        return recordls;
+    }
+
+   public  List<AttendanceSignRecordEntity> appPageInfoListToAppPageTreeVoList(List<CheckinDataBO> vals) {
+        if (CollectionUtils.isEmpty(vals)) {
+            return null;
+        }
+        List<AttendanceSignRecordEntity> departmentTrees = vals.stream().map(this::appPageInfoListToAppPageTreeVo).filter(obj -> !Objects.isNull(obj)).collect(Collectors.toList());
+        return departmentTrees;
+    }
+
+    public  AttendanceSignRecordEntity  appPageInfoListToAppPageTreeVo(CheckinDataBO bo) {
+        if (null == bo) {
+            return null;
+        }
+        try {
+            AttendanceSignRecordEntity entity = new AttendanceSignRecordEntity();
+
+            entity.setWxUserId(bo.getUserId());
+            entity.setGroupId(bo.getGroupId());
+            entity.setGroupName(bo.getGroupName());
+            entity.setCheckinType(bo.getCheckinType());
+            entity.setExceptionType(bo.getExceptionType());
+            entity.setCheckinWxTime(bo.getCheckinTime());
+            LocalDateTime dateTime = timestampToLocalDateTime(bo.getCheckinTime());
+
+            log.error(bo.getCheckinTime()+"-------打卡时间---------"+dateTime);
+            DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
+            String timeStr = dateTime.format(timeFormatter);
+            entity.setCheckinDate(dateTime.toLocalDate());
+            entity.setCheckinTime(timeStr);
+            entity.setLocationTitle(bo.getLocationTitle());
+            entity.setLocationDetail(bo.getLocationDetail());
+            entity.setWifiName(bo.getWifiName());
+            entity.setWifiMac(bo.getWifiMac());
+            if (StrUtil.isNotBlank(bo.getLat())) {
+                Long lat = Long.valueOf(bo.getLat());
+                Double latd = lat / 1000000.0d;
+                entity.setLatitude(latd.toString());
+            }
+            if (StrUtil.isNotBlank(bo.getLng())) {
+                Long lng = Long.valueOf(bo.getLng());
+                Double lngd = lng / 1000000.0d;
+                entity.setLongitude(lngd.toString());
+            }
+
+            entity.setDeviceId(bo.getDeviceId());
+            // 媒体ID列表(如果是 JSON 存库,这里可序列化)
+            if (!CollectionUtils.isEmpty(bo.getMediaIds())) {
+                entity.setMediaIds(JSON.toJSONString(bo.getMediaIds()));
+            }
+            return entity;
+        }catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static LocalDateTime timestampToLocalDateTime(Long timestamp) {
+
+        LocalDateTime dateTime = Instant.ofEpochSecond(timestamp)
+                .atZone(ZoneId.of("Asia/Shanghai"))
+                .toLocalDateTime();
+
+        return dateTime;
+    }
+
+    public static String timestampToLocalTime(Long timestamp) {
+        String time = Instant.ofEpochMilli(timestamp)
+                .atZone(ZoneId.of("Asia/Shanghai"))
+                .format(DateTimeFormatter.ofPattern("HH:mm:ss"));
+
+        log.error("时间--------"+time);
+        return time;
+    }
+
+
+//    public ld dd() {
+//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+//        String time = sdf.format(new Date(timestamp));
+//    }
+
+    public static void main(String[] args) {
+        LocalDateTime dateTime = timestampToLocalDateTime(1767840360L);
+        log.error("---------"+dateTime);
+    }
+}

+ 23 - 0
storlead-centre-service/src/main/java/com/storlead/centre/service/impl/HrmschedulesignRemindServiceImpl.java

@@ -0,0 +1,23 @@
+package com.storlead.centre.service.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.storlead.centre.entity.HrmschedulesignRemindEntity;
+import com.storlead.centre.mapper.HrmschedulesignRemindMapper;
+import com.storlead.centre.service.HrmschedulesignRemindService;
+import com.storlead.framework.common.constant.DSConstants;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-05
+ */
+@Service
+@DS(DSConstants.DATASOURCE_OA)
+public class HrmschedulesignRemindServiceImpl extends ServiceImpl<HrmschedulesignRemindMapper, HrmschedulesignRemindEntity> implements HrmschedulesignRemindService {
+
+}

+ 24 - 0
storlead-centre-service/src/main/java/com/storlead/centre/service/impl/HrmschedulesignServiceImpl.java

@@ -0,0 +1,24 @@
+package com.storlead.centre.service.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.storlead.centre.entity.HrmschedulesignEntity;
+import com.storlead.centre.mapper.HrmschedulesignMapper;
+import com.storlead.centre.service.HrmschedulesignService;
+import com.storlead.framework.common.constant.DSConstants;
+import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-05
+ */
+@Service
+@DS(DSConstants.DATASOURCE_OA)
+public class HrmschedulesignServiceImpl extends ServiceImpl<HrmschedulesignMapper, HrmschedulesignEntity> implements HrmschedulesignService {
+
+}

+ 53 - 0
storlead-centre-service/src/main/java/com/storlead/centre/service/impl/SystemConfigItemServiceImpl.java

@@ -0,0 +1,53 @@
+package com.storlead.centre.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.storlead.centre.entity.SystemConfigItemEntity;
+import com.storlead.centre.mapper.SystemConfigItemMapper;
+import com.storlead.centre.service.SystemConfigItemService;
+import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.Objects;
+
+/**
+ * <p>
+ * 系统配置项 服务实现类
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-08
+ */
+@Service
+public class SystemConfigItemServiceImpl extends MyBaseServiceImpl<SystemConfigItemMapper, SystemConfigItemEntity> implements SystemConfigItemService {
+
+    @Override
+    public SystemConfigItemEntity getSystemConfigItem(String code) {
+        LambdaQueryWrapper<SystemConfigItemEntity> queryWrapper = new LambdaQueryWrapper();
+        queryWrapper.eq(SystemConfigItemEntity::getItemCode,code);
+        queryWrapper.last("limit 1");
+        SystemConfigItemEntity item = this.getOne(queryWrapper);
+        if (Objects.isNull(item)) {
+            return null;
+        }
+        return item;
+    }
+
+    @Override
+    public Long getCheckinDataTime() {
+        SystemConfigItemEntity item = getSystemConfigItem("GET_CHECKIN_DATA_TIME");
+        if (Objects.isNull(item) || StrUtil.isBlank(item.getItemFormatValue())) {
+            return null;
+        }
+        return Long.valueOf(item.getItemFormatValue());
+    }
+
+    @Override
+    public void setCheckinDataTime(Long checkinTime) {
+        LambdaUpdateWrapper<SystemConfigItemEntity> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.set(SystemConfigItemEntity::getItemFormatValue,checkinTime.toString());
+        updateWrapper.eq(SystemConfigItemEntity::getItemCode,"GET_CHECKIN_DATA_TIME");
+        update(updateWrapper);
+    }
+}

+ 52 - 0
storlead-centre-service/src/main/resources/mapper/AttendanceSignRecordMapper.xml

@@ -0,0 +1,52 @@
+<?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.storlead.centre.mapper.AttendanceSignRecordMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.AttendanceSignRecordEntity">
+        <id column="id" property="id" />
+        <result column="sort" property="sort" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="is_delete" property="isDelete" />
+        <result column="enabled" property="enabled" />
+        <result column="create_by" property="createBy" />
+        <result column="wx_user_id" property="wxUserId" />
+        <result column="user_id" property="userId" />
+        <result column="user_name" property="userName" />
+        <result column="dept_id" property="deptId" />
+        <result column="dept_name" property="deptName" />
+        <result column="group_id" property="groupId" />
+        <result column="group_name" property="groupName" />
+        <result column="checkin_type" property="checkinType" />
+        <result column="sync_oa" property="syncOa" />
+        <result column="exception_type" property="exceptionType" />
+        <result column="checkin_wx_time" property="checkinWxTime" />
+        <result column="checkin_time" property="checkinTime" />
+        <result column="checkin_date" property="checkinDate" />
+        <result column="location_title" property="locationTitle" />
+        <result column="location_detail" property="locationDetail" />
+        <result column="wifi_name" property="wifiName" />
+        <result column="wifi_mac" property="wifiMac" />
+        <result column="longitude" property="longitude" />
+        <result column="latitude" property="latitude" />
+        <result column="device_id" property="deviceId" />
+        <result column="media_ids" property="mediaIds" />
+        <result column="remark" property="remark" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        sort,
+        create_time,
+        update_by,
+        update_time,
+        is_delete,
+        enabled,
+        create_by,
+        owner_by,
+        id, wx_user_id, user_id, user_name, dept_id, dept_name, group_id, group_name, checkin_type,sync_oa, exception_type, checkin_time,checkin_wx_time, checkin_date, location_title, location_detail, wifi_name, wifi_mac, longitude, latitude, device_id, media_ids, remark
+    </sql>
+
+</mapper>

+ 37 - 0
storlead-centre-service/src/main/resources/mapper/SystemConfigItemMapper.xml

@@ -0,0 +1,37 @@
+<?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.storlead.centre.mapper.SystemConfigItemMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.SystemConfigItemEntity">
+        <id column="item_id" property="itemId" />
+    <result column="create_time" property="createTime" />
+    <result column="update_time" property="updateTime" />
+    <result column="is_delete" property="isDelete" />
+    <result column="enabled" property="enabled" />
+    <result column="create_by" property="createBy" />
+    <result column="owner_by" property="ownerBy" />
+    <result column="update_by" property="updateBy" />
+    <result column="sort" property="sort" />
+        <result column="item_name" property="itemName" />
+        <result column="item_code" property="itemCode" />
+        <result column="item_data_type" property="itemDataType" />
+        <result column="item_data_format_desc" property="itemDataFormatDesc" />
+        <result column="item_format_value" property="itemFormatValue" />
+        <result column="item_desc" property="itemDesc" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        create_time,
+        update_time,
+        is_delete,
+        enabled,
+        create_by,
+        owner_by,
+        update_by,
+        sort,
+        item_id, item_name, item_code, item_data_type, item_data_format_desc, item_format_value, item_desc
+    </sql>
+
+</mapper>

+ 32 - 0
storlead-centre-service/src/main/resources/oa/mapper/HrmschedulesignMapper.xml

@@ -0,0 +1,32 @@
+<?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.storlead.centre.mapper.HrmschedulesignMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.HrmschedulesignEntity">
+        <id column="ID" property="id" />
+        <result column="USERID" property="userid" />
+        <result column="USERTYPE" property="usertype" />
+        <result column="SIGNTYPE" property="signtype" />
+        <result column="SIGNDATE" property="signdate" />
+        <result column="SIGNTIME" property="signtime" />
+        <result column="clientAddress" property="clientAddress" />
+        <result column="ISINCOM" property="isincom" />
+        <result column="SIGNFROM" property="signfrom" />
+        <result column="LONGITUDE" property="longitude" />
+        <result column="LATITUDE" property="latitude" />
+        <result column="ADDR" property="addr" />
+        <result column="ISIMPORT" property="isimport" />
+        <result column="SUUID" property="suuid" />
+        <result column="timeZone" property="timeZone" />
+        <result column="belongdate" property="belongdate" />
+        <result column="memo" property="memo" />
+        <result column="deviceInfo" property="deviceInfo" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        ID, USERID, USERTYPE, SIGNTYPE, SIGNDATE, SIGNTIME, clientAddress, ISINCOM, SIGNFROM, LONGITUDE, LATITUDE, ADDR, ISIMPORT, SUUID, timeZone, belongdate, memo, deviceInfo
+    </sql>
+
+</mapper>

+ 20 - 0
storlead-centre-service/src/main/resources/oa/mapper/HrmschedulesignRemindMapper.xml

@@ -0,0 +1,20 @@
+<?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.storlead.centre.mapper.HrmschedulesignRemindMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.HrmschedulesignRemindEntity">
+        <id column="id" property="id" />
+        <result column="userid" property="userid" />
+        <result column="signtype" property="signtype" />
+        <result column="signdate" property="signdate" />
+        <result column="signtime" property="signtime" />
+        <result column="belongdate" property="belongdate" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, userid, signtype, signdate, signtime, belongdate
+    </sql>
+
+</mapper>

+ 36 - 38
storlead-centre-service/src/main/java/com/storlead/centre/pojo/CheckinDataBo.java → storlead-wx/src/main/java/com/storlead/wx/pojo/vo/CheckinDataBo.java

@@ -1,7 +1,7 @@
-package com.storlead.centre.pojo;
+package com.storlead.wx.pojo.vo;
 
 import com.alibaba.fastjson.JSON;
-import com.storlead.centre.entity.AttendanceSignRecordEntity;
+//import com.storlead.centre.entity.AttendanceSignRecordEntity;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import org.springframework.util.CollectionUtils;
@@ -18,7 +18,7 @@ import java.util.stream.Collectors;
  * @create: 2026-01-04 15:23
  */
 @Data
-public class CheckinDataBo implements Serializable {
+public class CheckinDataBO implements Serializable {
     private static final long serialVersionUID = 1L;
 
     @ApiModelProperty(value = "用户唯一标识(企微 / 系统用户ID)",example = "ChenKaiQiang")
@@ -101,39 +101,37 @@ public class CheckinDataBo implements Serializable {
             example = "1")
     private Long groupId;
 
-
-
-    public static List<AttendanceSignRecordEntity> appPageInfoListToAppPageTreeVoList(List<CheckinDataBo> vals) {
-        if (CollectionUtils.isEmpty(vals)) {
-            return null;
-        }
-        List<AttendanceSignRecordEntity> departmentTrees = vals.stream().map(CheckinDataBo::appPageInfoListToAppPageTreeVo).filter(obj -> !Objects.isNull(obj)).collect(Collectors.toList());
-        return departmentTrees;
-    }
-
-    public static AttendanceSignRecordEntity  appPageInfoListToAppPageTreeVo(CheckinDataBo bo) {
-        if (null == bo) {
-            return null;
-        }
-        AttendanceSignRecordEntity entity = new AttendanceSignRecordEntity();
-
-        entity.setWxUserId(bo.getUserId());
-        entity.setGroupId(bo.getGroupId());
-        entity.setGroupName(bo.getGroupName());
-        entity.setCheckinType(bo.getCheckinType());
-        entity.setExceptionType(bo.getExceptionType());
-        entity.setCheckinTime(bo.getCheckinTime());
-        entity.setLocationTitle(bo.getLocationTitle());
-        entity.setLocationDetail(bo.getLocationDetail());
-        entity.setWifiName(bo.getWifiName());
-        entity.setWifiMac(bo.getWifiMac());
-        entity.setLatitude(bo.getLat());
-        entity.setLongitude(bo.getLat());
-        entity.setDeviceId(bo.getDeviceId());
-        // 媒体ID列表(如果是 JSON 存库,这里可序列化)
-        if (!CollectionUtils.isEmpty(bo.getMediaIds())) {
-            entity.setMediaIds(JSON.toJSONString(bo.getMediaIds()));
-        }
-        return entity;
-    }
+//    public static List<AttendanceSignRecordEntity> appPageInfoListToAppPageTreeVoList(List<CheckinDataBo> vals) {
+//        if (CollectionUtils.isEmpty(vals)) {
+//            return null;
+//        }
+//        List<AttendanceSignRecordEntity> departmentTrees = vals.stream().map(CheckinDataBo::appPageInfoListToAppPageTreeVo).filter(obj -> !Objects.isNull(obj)).collect(Collectors.toList());
+//        return departmentTrees;
+//    }
+//
+//    public static AttendanceSignRecordEntity  appPageInfoListToAppPageTreeVo(CheckinDataBo bo) {
+//        if (null == bo) {
+//            return null;
+//        }
+//        AttendanceSignRecordEntity entity = new AttendanceSignRecordEntity();
+//
+//        entity.setWxUserId(bo.getUserId());
+//        entity.setGroupId(bo.getGroupId());
+//        entity.setGroupName(bo.getGroupName());
+//        entity.setCheckinType(bo.getCheckinType());
+//        entity.setExceptionType(bo.getExceptionType());
+//        entity.setCheckinTime(bo.getCheckinTime());
+//        entity.setLocationTitle(bo.getLocationTitle());
+//        entity.setLocationDetail(bo.getLocationDetail());
+//        entity.setWifiName(bo.getWifiName());
+//        entity.setWifiMac(bo.getWifiMac());
+//        entity.setLatitude(bo.getLat());
+//        entity.setLongitude(bo.getLat());
+//        entity.setDeviceId(bo.getDeviceId());
+//        // 媒体ID列表(如果是 JSON 存库,这里可序列化)
+//        if (!CollectionUtils.isEmpty(bo.getMediaIds())) {
+//            entity.setMediaIds(JSON.toJSONString(bo.getMediaIds()));
+//        }
+//        return entity;
+//    }
 }

+ 1 - 1
storlead-wx/src/main/java/com/storlead/wx/properties/CorpWeChatConstants.java

@@ -209,7 +209,7 @@ public class CorpWeChatConstants {
      * 单个userid不少于1字节,不多于64字节
      * 可填充个数:1 ~ 100
      * */
-    public final static String GETCHECKIN_DAYDATA_URL = "    https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckin_daydata?access_token=ACCESS_TOKEN";
+    public final static String GETCHECKIN_DAYDATA_URL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata?access_token=ACCESS_TOKEN";
 
 
 

+ 2 - 1
storlead-wx/src/main/java/com/storlead/wx/service/CorpWeChatService.java

@@ -3,6 +3,7 @@ package com.storlead.wx.service;
 
 import cn.hutool.json.JSONObject;
 import com.storlead.framework.common.vo.UserVo;
+import com.storlead.wx.pojo.vo.CheckinDataBO;
 import com.storlead.wx.pojo.vo.SummaryInfoVO;
 import com.storlead.wx.pojo.vo.WechatAppBO;
 import com.storlead.wx.pojo.vo.WechatToken;
@@ -120,5 +121,5 @@ public interface CorpWeChatService {
     boolean sendTextCardMsgByUserIdByAppCode(@NotNull String title, @NotNull String description, @NotNull String redirectionUrl, Set<String> users, Set<Long> deptSet,String appCode);
 
 
-    List<SummaryInfoVO> getCheckinDayData(List<String> userIdList);
+    List<CheckinDataBO> getCheckinDayData(List<String> userIdList,Long starttime,Long endtime,Integer opencheckindatatype);
 }

+ 3 - 6
storlead-wx/src/main/java/com/storlead/wx/service/impl/CorpWeChatServiceImpl.java

@@ -7,10 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.google.common.collect.ImmutableMap;
 import com.storlead.framework.common.vo.UserVo;
-import com.storlead.wx.pojo.vo.CorpWeChatUserVO;
-import com.storlead.wx.pojo.vo.SummaryInfoVO;
-import com.storlead.wx.pojo.vo.WechatAppBO;
-import com.storlead.wx.pojo.vo.WechatToken;
+import com.storlead.wx.pojo.vo.*;
 import com.storlead.wx.properties.CorpWeChatConstants;
 import com.storlead.wx.properties.CorpWeChatProperties;
 import com.storlead.wx.service.CorpWeChatService;
@@ -331,10 +328,10 @@ public class CorpWeChatServiceImpl implements CorpWeChatService {
     }
 
     @Override
-    public List<SummaryInfoVO> getCheckinDayData(List<String> userIdList) {
+    public List<CheckinDataBO> getCheckinDayData(List<String> userIdList,Long starttime,Long endtime,Integer opencheckindatatype) {
 
         String token = this.getAccessToken().getToken();
-        List<SummaryInfoVO> checkinData = CorpWechatUtil.getUserCheckinDayData(CorpWeChatConstants.GETCHECKIN_DAYDATA_URL,token,userIdList);
+        List<CheckinDataBO> checkinData = CorpWechatUtil.getUserCheckinDayData(CorpWeChatConstants.GETCHECKIN_DAYDATA_URL,token,userIdList,starttime,endtime,opencheckindatatype);
         return checkinData;
     }
 

+ 11 - 13
storlead-wx/src/main/java/com/storlead/wx/util/CorpWechatUtil.java

@@ -4,10 +4,7 @@ import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONObject;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.extension.exceptions.ApiException;
-import com.storlead.wx.pojo.vo.CorpWeChatDeptVO;
-import com.storlead.wx.pojo.vo.CorpWeChatUserVO;
-import com.storlead.wx.pojo.vo.SummaryInfoVO;
-import com.storlead.wx.pojo.vo.WechatToken;
+import com.storlead.wx.pojo.vo.*;
 import com.storlead.wx.properties.CorpWeChatConstants;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
@@ -171,25 +168,26 @@ public class CorpWechatUtil {
      * @param useridlist
      * @return
      */
-    public static List<SummaryInfoVO> getUserCheckinDayData(@NotNull String url, @NotNull String accessToken, List<String> useridlist) {
-
+    public static List<CheckinDataBO> getUserCheckinDayData(@NotNull String url, @NotNull String accessToken, List<String> useridlist,Long starttime,Long endtime,Integer opencheckindatatype) {
 
         Map<String,Object> paramMap = new HashMap<>();
-        paramMap.put("starttime","1599062400");
-        paramMap.put("endtime","1599062400");
+        paramMap.put("opencheckindatatype",3);
+        paramMap.put("starttime",starttime.toString());
+        paramMap.put("endtime",endtime.toString());
         paramMap.put("useridlist",useridlist);
 
-        String resultStr = HttpUtil.post(url.replace("ACCESS_TOKEN", accessToken),paramMap);
+        //paramMap
+
+        String resultStr = HttpUtil.post(url.replace("ACCESS_TOKEN", accessToken),JSON.toJSONString(paramMap));
         if (StringUtils.isNotEmpty(resultStr)) {
             log.debug("查询所有用户---> {}", resultStr);
             JSONObject jsonResult = new JSONObject(resultStr);
             int errCode = jsonResult.getInt("errcode");
             String errMsg = jsonResult.getStr("errmsg");
             if (CorpWeChatConstants.RETURN_SUCCESS_CODE == errCode) {
-                log.info("获取打开信息: {} ", jsonResult.getJSONArray("userlist").toString());
-                String json = jsonResult.getJSONArray("userlist").toString();
-                List<SummaryInfoVO> infos = JSON.parseArray(json,SummaryInfoVO.class);
-                // com.alibaba.fastjson.JSONObject.(json,List<CorpWeChatUserVO>)
+                log.info("获取打卡信息: {} ", jsonResult.getJSONArray("checkindata").toString());
+                String json = jsonResult.getJSONArray("checkindata").toString();
+                List<CheckinDataBO> infos = JSON.parseArray(json,CheckinDataBO.class);
                 return infos;
             }
         }