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

Merge remote-tracking branch 'origin/master'

lusa преди 3 седмици
родител
ревизия
22feba802d
променени са 60 файла, в които са добавени 2013 реда и са изтрити 204 реда
  1. 4 0
      .idea/encodings.xml
  2. 4 4
      storlead-centre-api/src/main/java/com/storlead/centre/ChenkqGeneratorCodeConfig.java
  3. 82 0
      storlead-centre-api/src/main/java/com/storlead/centre/dispatch/AttendanceSignDispatchTask.java
  4. 150 0
      storlead-centre-api/src/main/java/com/storlead/centre/dispatch/SyncAttendanceSignToOaTask.java
  5. 34 0
      storlead-centre-api/src/main/java/com/storlead/centre/dispatch/SyncOaBaseDataTask.java
  6. 38 0
      storlead-centre-api/src/main/java/com/storlead/centre/system/CorpWeChatController.java
  7. 3 1
      storlead-centre-api/src/main/java/com/storlead/centre/system/SystemWechatConfigApiController.java
  8. 107 0
      storlead-centre-api/src/main/java/com/storlead/centre/vo/SignDataConvert.java
  9. 8 6
      storlead-centre-api/src/main/resources/application-prod.yml
  10. 6 0
      storlead-centre-service/pom.xml
  11. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/controller/AttendanceSignCompensateRecordController.java
  12. 2 2
      storlead-centre-service/src/main/java/com/storlead/centre/controller/AttendanceSignRecordController.java
  13. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/controller/HrmschedulesignController.java
  14. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/controller/HrmschedulesignRemindController.java
  15. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/controller/SystemConfigItemController.java
  16. 61 0
      storlead-centre-service/src/main/java/com/storlead/centre/entity/AttendanceSignCompensateRecordEntity.java
  17. 60 31
      storlead-centre-service/src/main/java/com/storlead/centre/entity/AttendanceSignRecordEntity.java
  18. 88 0
      storlead-centre-service/src/main/java/com/storlead/centre/entity/HrmschedulesignEntity.java
  19. 51 0
      storlead-centre-service/src/main/java/com/storlead/centre/entity/HrmschedulesignRemindEntity.java
  20. 60 0
      storlead-centre-service/src/main/java/com/storlead/centre/entity/SystemConfigItemEntity.java
  21. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/AttendanceSignCompensateRecordMapper.java
  22. 1 1
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/AttendanceSignRecordMapper.java
  23. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/HrmschedulesignMapper.java
  24. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/HrmschedulesignRemindMapper.java
  25. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/SystemConfigItemMapper.java
  26. 17 12
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/AttendanceSignCompensateRecordMapper.xml
  27. 32 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/HrmschedulesignMapper.xml
  28. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/HrmschedulesignRemindMapper.xml
  29. 0 33
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/SysAppInfoMapper.xml
  30. 37 0
      storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/SystemConfigItemMapper.xml
  31. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/AttendanceSignCompensateRecordService.java
  32. 16 1
      storlead-centre-service/src/main/java/com/storlead/centre/service/AttendanceSignRecordService.java
  33. 18 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/HrmschedulesignRemindService.java
  34. 16 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/HrmschedulesignService.java
  35. 24 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/SystemConfigItemService.java
  36. 20 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/impl/AttendanceSignCompensateRecordServiceImpl.java
  37. 344 3
      storlead-centre-service/src/main/java/com/storlead/centre/service/impl/AttendanceSignRecordServiceImpl.java
  38. 23 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/impl/HrmschedulesignRemindServiceImpl.java
  39. 24 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/impl/HrmschedulesignServiceImpl.java
  40. 53 0
      storlead-centre-service/src/main/java/com/storlead/centre/service/impl/SystemConfigItemServiceImpl.java
  41. 105 0
      storlead-centre-service/src/main/java/com/storlead/centre/vo/SignDataConvert.java
  42. 6 15
      storlead-centre-service/src/main/resources/mapper/AttendanceSignCompensateRecordMapper.xml
  43. 22 16
      storlead-centre-service/src/main/resources/mapper/AttendanceSignRecordMapper.xml
  44. 37 0
      storlead-centre-service/src/main/resources/mapper/SystemConfigItemMapper.xml
  45. 32 0
      storlead-centre-service/src/main/resources/oa/mapper/HrmschedulesignMapper.xml
  46. 20 0
      storlead-centre-service/src/main/resources/oa/mapper/HrmschedulesignRemindMapper.xml
  47. 1 0
      storlead-framework/storlead-common/src/main/java/com/storlead/framework/common/properties/UrlChainDefinitionPorperties.java
  48. 3 0
      storlead-user/src/main/java/com/storlead/user/pojo/entity/UserEntity.java
  49. 49 37
      storlead-user/src/main/java/com/storlead/user/service/impl/UserServiceImpl.java
  50. 2 1
      storlead-user/src/main/resources/mapper/UserMapper.xml
  51. 138 0
      storlead-wx/src/main/java/com/storlead/wx/pojo/vo/CheckinDataBO.java
  52. 1 1
      storlead-wx/src/main/java/com/storlead/wx/properties/CorpWeChatConstants.java
  53. 4 2
      storlead-wx/src/main/java/com/storlead/wx/service/CorpWeChatService.java
  54. 12 19
      storlead-wx/src/main/java/com/storlead/wx/service/impl/CorpWeChatServiceImpl.java
  55. 12 13
      storlead-wx/src/main/java/com/storlead/wx/util/CorpWechatUtil.java
  56. 1 1
      ui/sp-user-center/.env.development
  57. 1 1
      ui/sp-user-center/.env.production
  58. 2 2
      ui/sp-user-center/.env.test
  59. 1 1
      ui/sp-user-center/index.html
  60. 1 1
      ui/sp-user-center/package.json

+ 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" />

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

@@ -128,15 +128,15 @@ public class ChenkqGeneratorCodeConfig {
         strategy.setColumnNaming(NamingStrategy.underline_to_camel);
 
         // 公共父类
-        strategy.setSuperEntityClass("com.storlead.frameworkmybatis.entity.SysBaseField");
+        strategy.setSuperEntityClass("com.storlead.framework.mybatis.entity.SysBaseField");
         // 写于父类中的公共字段
         strategy.setSuperEntityColumns("create_by","update_by","create_time","update_time","is_delete","enabled","owner_by","sort");
         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");

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

@@ -0,0 +1,82 @@
+package com.storlead.centre.dispatch;
+
+import com.storlead.centre.service.AttendanceSignRecordService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.text.ParseException;
+import java.time.LocalTime;
+import java.util.Date;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * @program: storlead-centre-platform
+ * @description:
+ * @author: chenkq
+ * @create: 2026-01-07 14:57
+ */
+
+@Slf4j
+@Component
+public class AttendanceSignDispatchTask {
+
+    @Resource
+    private AttendanceSignRecordService attendanceSignRecordService;
+
+    private final ReentrantLock syncLock = new ReentrantLock();
+
+    @Value("${environment}")
+    private  String environment;
+    /**
+     * 同步考勤数据
+     * @throws ParseException
+     */
+    @Scheduled(cron ="0 * * * * ? ")
+    public void syncSignData() throws ParseException {
+
+        if (!syncLock.tryLock()) {
+            log.warn("syncSignData 正在执行中,本次调度跳过");
+            return;
+        }
+        try {
+            if(!"prod".equals(environment)) {
+                return;
+            }
+            LocalTime now = LocalTime.now();
+
+            // ===== 总时间窗:06:00 – 22:30 =====
+            if (now.isBefore(LocalTime.of(6, 0))
+                    || now.isAfter(LocalTime.of(22, 30))) {
+                return;
+            }
+
+            boolean morningHighFrequency =
+                    (now.getHour() == 8 && now.getMinute() >= 30)
+                            || (now.getHour() == 9 && now.getMinute() <= 10);
+
+            boolean eveningHighFrequency =
+                    (now.getHour() == 18)
+                            || (now.getHour() == 19 && now.getMinute() <= 40);
+
+            boolean highFrequency = morningHighFrequency || eveningHighFrequency;
+            // 非高频时间:只允许 5 分钟一次
+            if (!highFrequency && now.getMinute() % 5 != 0) {
+                return;
+            }
+            attendanceSignRecordService.getSaveSignRecord();
+
+            attendanceSignRecordService.getDelayedSign();
+
+            attendanceSignRecordService.syncSignDataToOA();
+
+        } catch (Exception e) {
+            log.error("syncSignData error ----",e);
+        } finally {
+            // 👉 确保一定释放锁(防死锁)
+            syncLock.unlock();
+        }
+    }
+}

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

@@ -0,0 +1,150 @@
+package com.storlead.centre.dispatch;
+
+import cn.hutool.core.util.StrUtil;
+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.entity.SystemConfigItemEntity;
+import com.storlead.centre.service.AttendanceSignRecordService;
+import com.storlead.centre.service.HrmschedulesignRemindService;
+import com.storlead.centre.service.HrmschedulesignService;
+import com.storlead.centre.service.SystemConfigItemService;
+import com.storlead.centre.vo.SignDataConvert;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+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.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.concurrent.locks.ReentrantLock;
+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;
+    @Resource
+    private SystemConfigItemService systemConfigItemService;
+
+    @Value("${environment}")
+    private  String environment;
+
+//    private final ReentrantLock syncLock = new ReentrantLock();
+
+//    @Scheduled(cron ="0 * * * * ? ")
+//    public void syncSignDataToOA() throws ParseException {
+//        if(!"prod".equals(environment)) {
+//            return;
+//        }
+//
+//        if (!syncLock.tryLock()) {
+//            log.warn("syncSignData 正在执行中,本次调度跳过");
+//            return;
+//        }
+//
+//        try {
+//
+//            LocalTime now = LocalTime.now();
+//            // ===== 总时间窗:06:00 – 22:30 =====
+//            if (now.isBefore(LocalTime.of(6, 0))
+//                    || now.isAfter(LocalTime.of(22, 30))) {
+//                return;
+//            }
+//
+//            boolean morningHighFrequency =
+//                    (now.getHour() == 8 && now.getMinute() >= 30)
+//                            || (now.getHour() == 9 && now.getMinute() <= 10);
+//
+//            boolean eveningHighFrequency =
+//                    (now.getHour() == 18)
+//                            || (now.getHour() == 19 && now.getMinute() <= 40);
+//
+//            boolean highFrequency = morningHighFrequency || eveningHighFrequency;
+//            // 非高频时间:只允许 5 分钟一次
+//            if (!highFrequency && now.getMinute() % 5 != 0) {
+//                return;
+//            }
+//
+//            // 获取未同步的数据到
+//            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());
+//            List<Long> bmd = new ArrayList<>();
+//            SystemConfigItemEntity systemConfig = systemConfigItemService.getSystemConfigItem("ATTENDANCE_SGIN_PRIORITY_USER_ID");
+//            if (Objects.nonNull(systemConfig)) {
+//                String values = systemConfig.getItemFormatValue();
+//                if (StrUtil.isNotBlank(values)) {
+//                    bmd = Arrays.stream(values.split(","))
+//                            .map(String::trim)        // 去空格,防止 " 1"
+//                            .filter(s -> !s.isEmpty())// 防止空字符串
+//                            .map(Long::valueOf)
+//                            .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;
+//            List<HrmschedulesignEntity> hrmschedulesigns = SignDataConvert.attendanceListToOaSignVoList(attendances);
+//            if (!CollectionUtils.isEmpty(hrmschedulesigns)) {
+//                if (!CollectionUtils.isEmpty(bmd)) {
+//                    List<Long> finalBmd = bmd;
+//                    hrmschedulesignsDb = hrmschedulesigns.stream().filter(e -> finalBmd.contains(e.getUserid())).collect(Collectors.toList());
+//                } else {
+//                    hrmschedulesignsDb = hrmschedulesigns;
+//                }
+//                if (!CollectionUtils.isEmpty(hrmschedulesignsDb)) {
+//                    hrmschedulesignService.saveBatch(hrmschedulesignsDb);
+//                }
+//            }
+//
+//            List<HrmschedulesignRemindEntity> hrmschedulesignremindsDb;
+//            List<HrmschedulesignRemindEntity> hrmschedulesignreminds = SignDataConvert.attendanceListToOaSignRemindVoList(attendances);
+//            if (!CollectionUtils.isEmpty(hrmschedulesignreminds)) {
+//                if (!CollectionUtils.isEmpty(bmd)) {
+//                    List<Long> finalBmd = bmd;
+//                    hrmschedulesignremindsDb = hrmschedulesignreminds.stream().filter(e -> finalBmd.contains(e.getUserid())).collect(Collectors.toList());
+//                } else {
+//                    hrmschedulesignremindsDb = hrmschedulesignreminds;
+//                }
+//                if (!CollectionUtils.isEmpty(hrmschedulesignremindsDb)) {
+//                    hrmschedulesignRemindService.saveBatch(hrmschedulesignremindsDb);
+//                }
+//            }
+//        } catch (Exception e) {
+//            log.error("syncSignDataToOA error ----",e);
+//        } finally {
+//            // 👉 确保一定释放锁(防死锁)
+//            syncLock.unlock();
+//        }
+//    }
+
+}

+ 34 - 0
storlead-centre-api/src/main/java/com/storlead/centre/dispatch/SyncOaBaseDataTask.java

@@ -0,0 +1,34 @@
+package com.storlead.centre.dispatch;
+
+import com.storlead.user.service.IUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.text.ParseException;
+
+
+/**
+ * @program: storlead-centre-platform
+ * @description:
+ * @author: chenkq
+ * @create: 2026-01-14 11:04
+ */
+
+@Slf4j
+@Component
+public class SyncOaBaseDataTask {
+
+    @Resource
+    private IUserService userService;
+
+    @Scheduled(cron ="0 0 7-18 * * ? ")
+    public void syncOaData() throws ParseException {
+        /**
+         * 同步OA数据
+         */
+        userService.syncOa();
+
+    }
+}

+ 38 - 0
storlead-centre-api/src/main/java/com/storlead/centre/system/CorpWeChatController.java

@@ -0,0 +1,38 @@
+package com.storlead.centre.system;
+
+import cn.hutool.json.JSONObject;
+import com.storlead.framework.web.assemble.Result;
+import com.storlead.wx.service.CorpWeChatService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * @program: storlead-centre-platform
+ * @description:
+ * @author: chenkq
+ * @create: 2025-12-31 17:46
+ */
+@Api(tags = "系统: 企业微信管理")
+@RestController
+@RequestMapping("/xwork")
+@Log4j2
+public class CorpWeChatController {
+    @Resource
+    private CorpWeChatService corpWeChatService;
+
+    @ApiOperation("返回用于企业微信登陆所需要的参数")
+    @GetMapping("/get_x_work_login_param")
+    public Result<JSONObject> getCorpWechatLoginParam() {
+        Result<JSONObject> result = new Result<>();
+
+        result.setResult(corpWeChatService.getCorpWechatLoginParam());
+        return result;
+    }
+
+}

+ 3 - 1
storlead-centre-api/src/main/java/com/storlead/centre/system/SystemWechatConfigApiController.java

@@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.annotation.Resource;
+
 /**
  * <p>
  * 企业微信secret配置 前端控制器
@@ -21,7 +23,7 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/sys/wechat/config")
 public class SystemWechatConfigApiController {
 
-    @Autowired
+    @Resource
     private SystemWechatConfigService systemWechatConfigService;
 
     @PostMapping(value = "/save")

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

@@ -0,0 +1,107 @@
+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(attendance.getLocationTitle());
+            entity.setIsincom("1");
+            if ("外出打卡".equals(attendance.getCheckinType())) {
+                entity.setSignfrom("Wechat_out");
+            } else {
+                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;
+        }
+    }
+}

+ 8 - 6
storlead-centre-api/src/main/resources/application-prod.yml

@@ -5,7 +5,9 @@ server:
   tomcat:
     max-swallow-size: -1
     max-upload-size: 200MB
-    basedir: /mnt/vdb/storlead/sales/temp
+    basedir: /mnt/vdb/storlead/centra/temp
+  servlet:
+    context-path: /api
   compression:
     enabled: true
     min-response-size: 1024
@@ -92,9 +94,9 @@ spring:
       datasource:
         master:
           driver-class-name: com.mysql.jdbc.Driver
-          url: jdbc:mysql://storlead.internal.cn-south-1.mysql.rds.myhuaweicloud.com:65369/sp_unified_service_prod?useSSL=false&useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&rewriteBatchedStatements=true
-          username: sp_sales_prod
-          password: MsKLJue01MLIYnd2*0ReMQ
+          url: jdbc:mysql://storlead.internal.cn-south-1.mysql.rds.myhuaweicloud.com:65369/sp_centre_ecology_prod?useSSL=false&useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&rewriteBatchedStatements=true
+          username: sp_centre_ecology
+          password: MsKLJMjdue01MLId6Ynd2*0R6eMQ
         oa:
           driver-class-name: com.mysql.jdbc.Driver
           url: jdbc:mysql://storlead.internal.cn-south-1.mysql.rds.myhuaweicloud.com:65369/storlead_ecology_prod?useSSL=false&useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true
@@ -126,7 +128,7 @@ mybatis-plus:
 logging:
   file:
     # 日志存放目录
-    path: /mnt/vdb/storlead/sales/log/
+    path: /mnt/vdb/storlead/centra/log/
   level:
     root: info
     io:
@@ -149,7 +151,7 @@ logging:
     com:
       storlead: error
 
-
+environment: prod
 # 企业微信
 corp-wechat:
   corpId: ww5323bd8ab4394132

+ 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/AttendanceSignCompensateRecordController.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-15
+ */
+@RestController
+@RequestMapping("/attendance-sign-compensate-record-entity")
+public class AttendanceSignCompensateRecordController {
+
+}

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

@@ -11,10 +11,10 @@ import org.springframework.web.bind.annotation.RestController;
  * </p>
  *
  * @author chenkq
- * @since 2025-12-25
+ * @since 2026-01-04
  */
 @RestController
-@RequestMapping("/attendance-sign-record-entity")
+@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 {
+
+}

+ 61 - 0
storlead-centre-service/src/main/java/com/storlead/centre/entity/AttendanceSignCompensateRecordEntity.java

@@ -0,0 +1,61 @@
+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 java.time.LocalDate;
+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-15
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+@TableName("attendance_sign_compensate_record")
+@ApiModel(value="AttendanceSignCompensateRecordEntity对象", description="考勤补偿记录")
+public class AttendanceSignCompensateRecordEntity extends SysBaseField {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "员工ID")
+    @TableField("user_id")
+    private Long userId;
+
+    @ApiModelProperty(value = "员工姓名(冗余)")
+    @TableField("user_name")
+    private String userName;
+
+    @ApiModelProperty(value = "0:上班卡,没下班卡,指定类型:")
+    @TableField("checkin_type")
+    private Integer checkinType;
+
+    @ApiModelProperty(value = "打卡日期(yyyy-MM-dd,用于查询与汇总)")
+    @TableField("checkin_date")
+    private LocalDate checkinDate;
+
+    @ApiModelProperty(value = "0:未处理,1:已处理")
+    @TableField("is_checkin")
+    private Integer isCheckin;
+
+    @ApiModelProperty(value = "备注")
+    @TableField("remark")
+    private String remark;
+
+
+}

+ 60 - 31
storlead-centre-service/src/main/java/com/storlead/centre/entity/AttendanceSignRecordEntity.java

@@ -1,18 +1,18 @@
 package com.storlead.centre.entity;
 
-import java.math.BigDecimal;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.IdType;
 import java.time.LocalDate;
 import com.baomidou.mybatisplus.annotation.TableId;
-import java.time.LocalDateTime;
-import com.baomidou.mybatisplus.annotation.TableField;
+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>
@@ -20,7 +20,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author chenkq
- * @since 2025-12-25
+ * @since 2026-01-04
  */
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -35,6 +35,10 @@ public class AttendanceSignRecordEntity extends SysBaseField {
     @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;
@@ -51,47 +55,72 @@ public class AttendanceSignRecordEntity extends SysBaseField {
     @TableField("dept_name")
     private String deptName;
 
-    @ApiModelProperty(value = "签到日期")
-    @TableField("sign_date")
-    private LocalDate signDate;
+    @ApiModelProperty(value = "考勤组ID")
+    @TableField("group_id")
+    private Long groupId;
 
-    @ApiModelProperty(value = "签到/签退时间")
-    @TableField("sign_time")
-    private LocalDateTime signTime;
+    @ApiModelProperty(value = "考勤组名称")
+    @TableField("group_name")
+    private String groupName;
 
-    @ApiModelProperty(value = "类型:1签到 2签退")
-    @TableField("sign_type")
-    private Integer signType;
+    @ApiModelProperty(value = "打卡类型:ON_DUTY上班 OFF_DUTY下班")
+    @TableField("checkin_type")
+    private String checkinType;
 
-    @ApiModelProperty(value = "是否同步OA")
+    @ApiModelProperty(value = "是否同步OA:0 未同步,1:已同步")
     @TableField("sync_oa")
     private Integer syncOa;
 
-    @ApiModelProperty(value = "来源:1OA 2APP 3H5")
-    @TableField("sign_source")
-    private Integer signSource;
+    @ApiModelProperty(value = "异常类型:NORMAL LATE EARLY ABSENT")
+    @TableField("exception_type")
+    private String exceptionType;
 
-    @ApiModelProperty(value = "设备类型:PC / Android / iOS")
-    @TableField("device_type")
-    private String deviceType;
+    @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("device_id")
-    private String deviceId;
 
-    @ApiModelProperty(value = "签到地址")
-    @TableField("sign_address")
-    private String signAddress;
+    @ApiModelProperty(value = "打卡地点名称")
+    @TableField("location_title")
+    private String locationTitle;
 
-    @ApiModelProperty(value = "经度")
+    @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 BigDecimal longitude;
+    private String longitude;
 
-    @ApiModelProperty(value = "纬度")
+    @ApiModelProperty(value = "纬度(放大后的整型)")
     @TableField("latitude")
-    private BigDecimal latitude;
+    private String latitude;
+
+    @ApiModelProperty(value = "设备唯一标识")
+    @TableField("device_id")
+    private String deviceId;
+
+    @ApiModelProperty(value = "打卡媒体ID列表(JSON数组)")
+    @TableField("media_ids")
+    private String mediaIds;
 
-    @ApiModelProperty(value = "备注")
+    @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/AttendanceSignCompensateRecordMapper.java

@@ -0,0 +1,16 @@
+package com.storlead.centre.mapper;
+
+import com.storlead.centre.entity.AttendanceSignCompensateRecordEntity;
+import com.storlead.framework.mybatis.mapper.MyBaseMapper;
+
+/**
+ * <p>
+ * 考勤补偿记录 Mapper 接口
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-15
+ */
+public interface AttendanceSignCompensateRecordMapper extends MyBaseMapper<AttendanceSignCompensateRecordEntity> {
+
+}

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

@@ -9,7 +9,7 @@ import com.storlead.framework.mybatis.mapper.MyBaseMapper;
  * </p>
  *
  * @author chenkq
- * @since 2025-12-25
+ * @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> {
+
+}

+ 17 - 12
storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/SysAppPageInfoMapper.xml → storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/AttendanceSignCompensateRecordMapper.xml

@@ -1,32 +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.SysAppPageInfoMapper">
+<mapper namespace="com.storlead.centre.mapper.AttendanceSignCompensateRecordMapper">
 
     <!-- 通用查询映射结果 -->
-    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.SysAppPageInfoEntity">
+    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.AttendanceSignCompensateRecordEntity">
         <id column="id" property="id" />
     <result column="sort" property="sort" />
-    <result column="enabled" property="enabled" />
-    <result column="create_by" property="createBy" />
     <result column="create_time" property="createTime" />
     <result column="update_by" property="updateBy" />
     <result column="update_time" property="updateTime" />
-        <result column="app_id" property="appId" />
-        <result column="page_name" property="pageName" />
-        <result column="page_code" property="pageCode" />
-        <result column="redirect_uri" property="redirectUri" />
-        <result column="description" property="description" />
+    <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="user_id" property="userId" />
+        <result column="user_name" property="userName" />
+        <result column="checkin_type" property="checkinType" />
+        <result column="checkin_date" property="checkinDate" />
+        <result column="is_checkin" property="isCheckin" />
+        <result column="remark" property="remark" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
         sort,
-        enabled,
-        create_by,
         create_time,
         update_by,
         update_time,
-        id, app_id, page_name, page_code, redirect_uri, description
+        is_delete,
+        enabled,
+        create_by,
+        owner_by,
+        id, user_id, user_name, checkin_type, checkin_date, is_checkin, remark
     </sql>
 
 </mapper>

+ 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>

+ 0 - 33
storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/SysAppInfoMapper.xml

@@ -1,33 +0,0 @@
-<?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.SysAppInfoMapper">
-
-    <!-- 通用查询映射结果 -->
-    <resultMap id="BaseResultMap" type="com.storlead.centre.pojo.entity.SysAppInfoEntity">
-        <id column="id" property="id" />
-    <result column="sort" property="sort" />
-    <result column="enabled" property="enabled" />
-    <result column="create_by" property="createBy" />
-    <result column="create_time" property="createTime" />
-    <result column="update_by" property="updateBy" />
-    <result column="update_time" property="updateTime" />
-        <result column="app_name" property="appName" />
-        <result column="app_code" property="appCode" />
-        <result column="app_secret" property="appSecret" />
-        <result column="redirect_uri" property="redirectUri" />
-        <result column="homepage_url" property="homepageUrl" />
-        <result column="description" property="description" />
-    </resultMap>
-
-    <!-- 通用查询结果列 -->
-    <sql id="Base_Column_List">
-        sort,
-        enabled,
-        create_by,
-        create_time,
-        update_by,
-        update_time,
-        id, app_name, app_code, app_secret, redirect_uri, homepage_url, description
-    </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>

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

@@ -0,0 +1,16 @@
+package com.storlead.centre.service;
+
+import com.storlead.centre.entity.AttendanceSignCompensateRecordEntity;
+import com.storlead.framework.mybatis.service.MyBaseService;
+
+/**
+ * <p>
+ * 考勤补偿记录 服务类
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-15
+ */
+public interface AttendanceSignCompensateRecordService extends MyBaseService<AttendanceSignCompensateRecordEntity> {
+
+}

+ 16 - 1
storlead-centre-service/src/main/java/com/storlead/centre/service/AttendanceSignRecordService.java

@@ -1,16 +1,31 @@
 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 2025-12-25
+ * @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();
+
+    void getDelayedSign();
+
+
+    void syncSignDataToOA();
 }

+ 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);
+}

+ 20 - 0
storlead-centre-service/src/main/java/com/storlead/centre/service/impl/AttendanceSignCompensateRecordServiceImpl.java

@@ -0,0 +1,20 @@
+package com.storlead.centre.service.impl;
+
+import com.storlead.centre.entity.AttendanceSignCompensateRecordEntity;
+import com.storlead.centre.mapper.AttendanceSignCompensateRecordMapper;
+import com.storlead.centre.service.AttendanceSignCompensateRecordService;
+import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 考勤补偿记录 服务实现类
+ * </p>
+ *
+ * @author chenkq
+ * @since 2026-01-15
+ */
+@Service
+public class AttendanceSignCompensateRecordServiceImpl extends MyBaseServiceImpl<AttendanceSignCompensateRecordMapper, AttendanceSignCompensateRecordEntity> implements AttendanceSignCompensateRecordService {
+
+}

+ 344 - 3
storlead-centre-service/src/main/java/com/storlead/centre/service/impl/AttendanceSignRecordServiceImpl.java

@@ -1,10 +1,34 @@
 package com.storlead.centre.service.impl;
 
-import com.storlead.centre.entity.AttendanceSignRecordEntity;
+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.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.storlead.centre.entity.*;
 import com.storlead.centre.mapper.AttendanceSignRecordMapper;
-import com.storlead.centre.service.AttendanceSignRecordService;
+import com.storlead.centre.service.*;
+import com.storlead.centre.vo.SignDataConvert;
+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.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.lang.reflect.Array;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -12,9 +36,326 @@ import org.springframework.stereotype.Service;
  * </p>
  *
  * @author chenkq
- * @since 2025-12-25
+ * @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 AttendanceSignRecordService attendanceSignRecordService;
+    @Resource
+    private HrmschedulesignRemindService hrmschedulesignRemindService;
+    @Resource
+    private HrmschedulesignService hrmschedulesignService;
+
+    @Resource
+    private AttendanceSignCompensateRecordService signCompensateRecordService;
+
+    @Resource
+    private IUserService userService;
+
+    @Override
+    public void getSaveSignRecord() {
+        try {
+            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);
+        }catch (Exception e) {
+            log.error("getSaveSignRecord----error---",e);
+        }
+    }
+    /**
+     * 获取打卡信息
+     */
+    @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;
+    }
+
+    /**
+     * 获取指定考勤记录
+     */
+    @Override
+    public void getDelayedSign() {
+        try {
+            LambdaQueryWrapper<AttendanceSignCompensateRecordEntity> compensate = new LambdaQueryWrapper<>();
+            compensate.eq(AttendanceSignCompensateRecordEntity::getIsCheckin, Integer.valueOf(0));
+            compensate.eq(AttendanceSignCompensateRecordEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+            List<AttendanceSignCompensateRecordEntity> attendanceSignls = signCompensateRecordService.list(compensate);
+            if (CollectionUtils.isEmpty(attendanceSignls)) {
+                return;
+            }
+
+            for (AttendanceSignCompensateRecordEntity attendanceSign : attendanceSignls) {
+                UserEntity user = userService.getById(attendanceSign.getUserId());
+                if (Objects.isNull(user) || StrUtil.isBlank(user.getXworkUserId())) {
+                    continue;
+                }
+                List<String> subList = Arrays.asList(user.getXworkUserId());
+                LocalDate date = attendanceSign.getCheckinDate();
+                ZoneId zoneId = ZoneId.of("Asia/Shanghai");
+                long starttime = date
+                        .atTime(0, 0, 0)
+                        .atZone(zoneId)
+                        .toEpochSecond();
+
+                long endtime = date
+                        .atTime(23, 59, 59)
+                        .atZone(zoneId)
+                        .toEpochSecond();
+
+                List<CheckinDataBO> batchResult = getSaveSignRecord(subList, 3, starttime, endtime);
+                if (CollectionUtils.isEmpty(batchResult)) {
+                    continue;
+                }
+
+                List<AttendanceSignRecordEntity> signls = appPageInfoListToAppPageTreeVoList(batchResult);
+                if (CollectionUtils.isEmpty(signls)) {
+                    return;
+                }
+
+                for (AttendanceSignRecordEntity signRecord : signls) {
+                    if (Objects.nonNull(user)) {
+                        signRecord.setUserId(user.getId());
+                        signRecord.setUserName(user.getRealName());
+                        signRecord.setDeptId(user.getDeptId());
+                    }
+                }
+                // 保存打卡记录
+                this.saveBatch(signls);
+
+                LambdaUpdateWrapper<AttendanceSignCompensateRecordEntity> updateWrapper = new LambdaUpdateWrapper<>();
+                updateWrapper.eq(AttendanceSignCompensateRecordEntity::getId, attendanceSign.getId());
+                updateWrapper.set(AttendanceSignCompensateRecordEntity::getIsCheckin, Integer.valueOf(1));
+                signCompensateRecordService.update(updateWrapper);
+            }
+        }catch (Exception e) {
+            log.error("----getDelayedSign------error-"+e);
+        }
+
+    }
+
+    @Override
+    public void syncSignDataToOA() {
+        try {
+
+            // 获取未同步的数据到
+            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());
+            List<Long> bmd = new ArrayList<>();
+            SystemConfigItemEntity systemConfig = systemConfigItemService.getSystemConfigItem("ATTENDANCE_SGIN_PRIORITY_USER_ID");
+            if (Objects.nonNull(systemConfig)) {
+                String values = systemConfig.getItemFormatValue();
+                if (StrUtil.isNotBlank(values)) {
+                    bmd = Arrays.stream(values.split(","))
+                            .map(String::trim)        // 去空格,防止 " 1"
+                            .filter(s -> !s.isEmpty())// 防止空字符串
+                            .map(Long::valueOf)
+                            .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;
+            List<HrmschedulesignEntity> hrmschedulesigns = SignDataConvert.attendanceListToOaSignVoList(attendances);
+            if (!CollectionUtils.isEmpty(hrmschedulesigns)) {
+                if (!CollectionUtils.isEmpty(bmd)) {
+                    List<Long> finalBmd = bmd;
+                    hrmschedulesignsDb = hrmschedulesigns.stream().filter(e -> finalBmd.contains(e.getUserid())).collect(Collectors.toList());
+                } else {
+                    hrmschedulesignsDb = hrmschedulesigns;
+                }
+                if (!CollectionUtils.isEmpty(hrmschedulesignsDb)) {
+                    hrmschedulesignService.saveBatch(hrmschedulesignsDb);
+                }
+            }
+
+            List<HrmschedulesignRemindEntity> hrmschedulesignremindsDb;
+            List<HrmschedulesignRemindEntity> hrmschedulesignreminds = SignDataConvert.attendanceListToOaSignRemindVoList(attendances);
+            if (!CollectionUtils.isEmpty(hrmschedulesignreminds)) {
+                if (!CollectionUtils.isEmpty(bmd)) {
+                    List<Long> finalBmd = bmd;
+                    hrmschedulesignremindsDb = hrmschedulesignreminds.stream().filter(e -> finalBmd.contains(e.getUserid())).collect(Collectors.toList());
+                } else {
+                    hrmschedulesignremindsDb = hrmschedulesignreminds;
+                }
+                if (!CollectionUtils.isEmpty(hrmschedulesignremindsDb)) {
+                    hrmschedulesignRemindService.saveBatch(hrmschedulesignremindsDb);
+                }
+            }
+        } catch (Exception e) {
+            log.error("syncSignDataToOA error ----",e);
+        }
+    }
+
+    /**
+     * 获取需要同步的数据进行同步
+     * @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);
+    }
+}

+ 105 - 0
storlead-centre-service/src/main/java/com/storlead/centre/vo/SignDataConvert.java

@@ -0,0 +1,105 @@
+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 lombok.extern.log4j.Log4j2;
+import org.springframework.util.CollectionUtils;
+
+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(attendance.getLocationTitle());
+            entity.setIsincom("1");
+            if ("外出打卡".equals(attendance.getCheckinType())) {
+                entity.setSignfrom("Wechat_out");
+            } else {
+                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 - 15
storlead-centre-service/src/main/java/com/storlead/centre/mapper/xml/AttendanceSignRecordMapper.xml → storlead-centre-service/src/main/resources/mapper/AttendanceSignCompensateRecordMapper.xml

@@ -1,9 +1,9 @@
 <?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">
+<mapper namespace="com.storlead.centre.mapper.AttendanceSignCompensateRecordMapper">
 
     <!-- 通用查询映射结果 -->
-    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.AttendanceSignRecordEntity">
+    <resultMap id="BaseResultMap" type="com.storlead.centre.entity.AttendanceSignCompensateRecordEntity">
         <id column="id" property="id" />
     <result column="sort" property="sort" />
     <result column="create_time" property="createTime" />
@@ -15,18 +15,9 @@
     <result column="owner_by" property="ownerBy" />
         <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="sign_date" property="signDate" />
-        <result column="sign_time" property="signTime" />
-        <result column="sign_type" property="signType" />
-        <result column="sync_oa" property="syncOa" />
-        <result column="sign_source" property="signSource" />
-        <result column="device_type" property="deviceType" />
-        <result column="device_id" property="deviceId" />
-        <result column="sign_address" property="signAddress" />
-        <result column="longitude" property="longitude" />
-        <result column="latitude" property="latitude" />
+        <result column="checkin_type" property="checkinType" />
+        <result column="checkin_date" property="checkinDate" />
+        <result column="is_checkin" property="isCheckin" />
         <result column="remark" property="remark" />
     </resultMap>
 
@@ -40,7 +31,7 @@
         enabled,
         create_by,
         owner_by,
-        id, user_id, user_name, dept_id, dept_name, sign_date, sign_time, sign_type, sync_oa, sign_source, device_type, device_id, sign_address, longitude, latitude, remark
+        id, user_id, user_name, checkin_type, checkin_date, is_checkin, remark
     </sql>
 
 </mapper>

+ 22 - 16
storlead-centre-service/src/main/resources/mapper/AttendanceSignRecordMapper.xml

@@ -5,28 +5,34 @@
     <!-- 通用查询映射结果 -->
     <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="owner_by" property="ownerBy" />
+        <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="sign_date" property="signDate" />
-        <result column="sign_time" property="signTime" />
-        <result column="sign_type" property="signType" />
+        <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="sign_source" property="signSource" />
-        <result column="device_type" property="deviceType" />
-        <result column="device_id" property="deviceId" />
-        <result column="sign_address" property="signAddress" />
+        <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>
 
@@ -40,7 +46,7 @@
         enabled,
         create_by,
         owner_by,
-        id, user_id, user_name, dept_id, dept_name, sign_date, sign_time, sign_type, sync_oa, sign_source, device_type, device_id, sign_address, longitude, latitude, remark
+        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>

+ 1 - 0
storlead-framework/storlead-common/src/main/java/com/storlead/framework/common/properties/UrlChainDefinitionPorperties.java

@@ -28,6 +28,7 @@ public class UrlChainDefinitionPorperties {
 			"/**/*.jpg",
 			"/**/*.png",
 			"/**/*.ico",
+			"/actuator",
 			"/actuator/health",
 			"/actuator/**",
 			"/app/**",

+ 3 - 0
storlead-user/src/main/java/com/storlead/user/pojo/entity/UserEntity.java

@@ -128,6 +128,9 @@ public class UserEntity extends SysBaseField {
     @ApiModelProperty(value = "最近的活动时间")
     private Date lastActivityTime;
 
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
     public UserEntity(Long id, String userName, String password) {
         this.id = id;
         this.userName = userName;

+ 49 - 37
storlead-user/src/main/java/com/storlead/user/service/impl/UserServiceImpl.java

@@ -1,6 +1,8 @@
 package com.storlead.user.service.impl;
 
 import cn.hutool.core.date.DateTime;
+import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -140,6 +142,8 @@ public class UserServiceImpl extends MyBaseServiceImpl<UserMapper, UserEntity> i
 					boolean sj = syncJob();
 					if (c && sc && sj) {
 						syncUser();
+						// 同步企业微信id,根据手机号
+						syncWxId();
 					}
 					log.error("syncCompany--------------end = "+(System.currentTimeMillis() - d));
 				}
@@ -155,29 +159,37 @@ public class UserServiceImpl extends MyBaseServiceImpl<UserMapper, UserEntity> i
 	@Override
 	public Boolean syncWxId() {
 		LambdaQueryWrapper<UserEntity> wp = new LambdaQueryWrapper<>();
-		wp.isNull(UserEntity::getXworkUserId);
 		wp.eq(UserEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
 		wp.isNotNull(UserEntity::getMobile).ne(UserEntity::getMobile,"");
 		wp.ne(UserEntity::getStatus,Integer.valueOf(5));
-		wp.isNotNull(UserEntity::getPermanentDate);
+		wp.isNull(UserEntity::getXworkUserId);
+
 		List<UserEntity> list = list(wp);
+		if (CollectionUtils.isEmpty(list)) {
+			return true;
+		}
+		String token = corpWeChatService.getAddressAccessTokenFromTencent().getToken();
 
-		List<com.storlead.framework.common.vo.UserVo> us = new ArrayList<>();
-		List<com.storlead.framework.common.vo.UserVo> finalUs = us;
-		list.forEach(a -> {
-			com.storlead.framework.common.vo.UserVo v = new com.storlead.framework.common.vo.UserVo();
-			BeanUtils.copyProperties(a,v);
-			finalUs.add(v);
-		});
-		corpWeChatService.syncWxUserIdByMobile(finalUs);
-		for (com.storlead.framework.common.vo.UserVo user : us) {
-			if (Objects.nonNull(user.getXworkUserId())) {
+		for (UserEntity user : list) {
+			String mobile = user.getMobile();
+			boolean isValid = Validator.isMobile(mobile);
+			if (!isValid) {
 				LambdaUpdateWrapper<UserEntity> updateWrapper = new LambdaUpdateWrapper<>();
-				updateWrapper.eq(UserEntity::getMobile,user.getMobile());
-				updateWrapper.set(UserEntity::getXworkUserId,user.getXworkUserId());
+				updateWrapper.eq(UserEntity::getId,user.getId());
+				updateWrapper.set(UserEntity::getXworkUserId,"");
 				update(updateWrapper);
+				continue;
 			}
+			String xworkUserId =  corpWeChatService.syncWxUserIdByMobile(token,mobile);
+			LambdaUpdateWrapper<UserEntity> updateWrapper = new LambdaUpdateWrapper<>();
+			if (StrUtil.isBlank(xworkUserId)) {
+				updateWrapper.eq(UserEntity::getRemark,"账号异常,未获取到微信Id");
+			}
+			updateWrapper.eq(UserEntity::getId,user.getId());
+			updateWrapper.set(UserEntity::getXworkUserId,xworkUserId);
+			update(updateWrapper);
 		}
+
 		return Boolean.TRUE;
 	}
 	/**
@@ -383,20 +395,17 @@ public class UserServiceImpl extends MyBaseServiceImpl<UserMapper, UserEntity> i
 			currentUser = new LoginUser().setId(0L);
 		}
 		List<UserEntity> userList = hrmresourceService.getUserList();
-		log.error("syncUser--------------end3 = "+(System.currentTimeMillis()-d));
 		List<UserEntity> dbUserList = list();
 		List<UserEntity> addList = new ArrayList<>();
 		List<UserEntity> updateList = new ArrayList<>();
 
 		List<DeptEntity> depts = departService.list();
-		log.error("syncUser--------------end4 = "+(System.currentTimeMillis()-d));
 		Map deptMap = new HashMap();
 		depts.forEach(c -> {
 			deptMap.put(c.getId(),c.getRouteCode());
 		});
 		// 默认密码
 		String defaultPassWord = "storlead123456";
-		log.error("syncUser--------------end5 = "+(System.currentTimeMillis()-d));
 		for (UserEntity user : userList) {
 			UserEntity userDb = dbUserList.stream().filter(u -> u.getId().equals(user.getId())).findFirst().orElse(null);
 			String routeCode =  Objects.isNull(deptMap.get(user.getDeptId())) ? "" : deptMap.get(user.getDeptId()).toString();
@@ -406,8 +415,10 @@ public class UserServiceImpl extends MyBaseServiceImpl<UserMapper, UserEntity> i
 						.setUserName(user.getMobile()).setOrgRouteCode(routeCode)
 						.setPassword(passwordEncoder.encode(defaultPassWord))
 						.setDataSource(0)
-						.setCreateBy(currentUser.getId())
-						.setEnabled(false);
+						.setCreateBy(currentUser.getId());
+				if (user.getStatus()!=null && Integer.parseInt(user.getStatus()) == 5) {
+					user.setEnabled(false);
+				}
 				addList.add(user);
 			} else {
 				//禁用离职状态的用户
@@ -417,31 +428,29 @@ public class UserServiceImpl extends MyBaseServiceImpl<UserMapper, UserEntity> i
 
 				user
 						.setOrgRouteCode(routeCode)
+						.setXworkUserId(user.getXworkUserId())
 						.setUserName(user.getMobile());
+
 				updateList.add(user);
 			}
 		}
-		log.error("syncUser--------------end6 = "+(System.currentTimeMillis()-d));
 		if (!CollectionUtils.isEmpty(addList)) {
 			this.saveBatch(addList);
 		}
-		if (CollectionUtils.isEmpty(updateList)) {
-			syncUserOpenIdFormTencent();
-		}
-		log.error("syncUser--------------end7 = "+(System.currentTimeMillis()-d));
-		if (!CollectionUtils.isEmpty(updateList)) {
-			ThreadPoolUtil.execute(new Runnable() {
-				@Override
-				public void run() {
-					saveOrUpdateBatch(updateList);
-					syncUserOpenIdFormTencent();
-
-				}
-			});
-		}
-		log.error("syncUser--------------end8 = "+(System.currentTimeMillis()-d));
-
-
+//		if (CollectionUtils.isEmpty(updateList)) {
+//			syncUserOpenIdFormTencent();
+//		}
+//		log.error("syncUser--------------end7 = "+(System.currentTimeMillis()-d));
+//		if (!CollectionUtils.isEmpty(updateList)) {
+//			ThreadPoolUtil.execute(new Runnable() {
+//				@Override
+//				public void run() {
+//					saveOrUpdateBatch(updateList);
+//					syncUserOpenIdFormTencent();
+//
+//				}
+//			});
+//		}
 		return true;
 	}
 
@@ -452,6 +461,9 @@ public class UserServiceImpl extends MyBaseServiceImpl<UserMapper, UserEntity> i
 	 * @date 2021-6-15 上午 11:58
 	 */
 	public boolean syncUserOpenIdFormTencent() {
+
+//		LambdaQueryWrapper<UserEntity> us = new LambdaQueryWrapper();
+//		us.eq(UserEntity::getIsDelete,CommonConstant.DEL_FLAG_0);
 		List<UserEntity> list = this.list();
 
 		List<com.storlead.framework.common.vo.UserVo> us = new ArrayList<>();

+ 2 - 1
storlead-user/src/main/resources/mapper/UserMapper.xml

@@ -35,6 +35,7 @@
 		<result column="education" property="education" />
 		<result column="job_des" property="jobDes" />
 		<result column="is_freeze" property="isFreeze" />
+		<result column="remark" property="remark" />
 		<result column="last_activity_time" property="lastActivityTime" />
 		<result column="external_user_type" property="externalUserType" />
 	</resultMap>
@@ -43,7 +44,7 @@
 	<sql id="Base_Column_List">
 		id, user_name, `password`, data_source,xwork_user_id, avatar, sex, nick_name, real_name, mobile, email, job_id, dept_id, sub_company_id, company_id, id_num
 , address, birthday, entry_date,external_user_type, permanent_date, resign_date, bank_name, bank_card_num, status, probation_pay, formal_pay, is_shenzhen_census, census, ethnic, marriage
-, education,job_des,is_freeze,last_activity_time, <include refid="com.storlead.framework.mybatis.mapper.SysBaseFieldMapper.Base_Column_List"></include>
+, education,job_des,is_freeze,last_activity_time,remark, <include refid="com.storlead.framework.mybatis.mapper.SysBaseFieldMapper.Base_Column_List"></include>
 	</sql>
 
 	<update id="addUserAvatar">

+ 138 - 0
storlead-wx/src/main/java/com/storlead/wx/pojo/vo/CheckinDataBO.java

@@ -0,0 +1,138 @@
+package com.storlead.wx.pojo.vo;
+
+import com.alibaba.fastjson.JSON;
+//import com.storlead.centre.entity.AttendanceSignRecordEntity;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.util.CollectionUtils;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @program: storlead-centre-platform
+ * @description:
+ * @author: chenkq
+ * @create: 2026-01-04 15:23
+ */
+@Data
+public class CheckinDataBO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "用户唯一标识(企微 / 系统用户ID)",example = "ChenKaiQiang")
+    private String userId;
+
+    @ApiModelProperty(value = "考勤组名称",example = "领存技术Attendance")
+    private String groupName;
+
+    @ApiModelProperty(
+            value = "打卡类型(字典)",
+            notes = "CHECKIN_TYPE:\n" +
+                    "ON_DUTY - 上班打卡\n" +
+                    "OFF_DUTY - 下班打卡",
+            example = "上班打卡"
+    )
+    private String checkinType;
+
+    @ApiModelProperty(
+            value = "异常类型(字典)",
+            notes = "EXCEPTION_TYPE:\n" +
+                    "LATE - 迟到\n" +
+                    "EARLY - 早退\n" +
+                    "ABSENT - 缺卡\n" +
+                    "NORMAL - 正常(为空或NORMAL)",
+            example = ""
+    )
+    private String exceptionType;
+
+    @ApiModelProperty(
+            value = "打卡时间(Unix时间戳,秒)",
+            example = "1767490002"
+    )
+    private Long checkinTime;
+
+    @ApiModelProperty(
+            value = "打卡地点名称",
+            example = "领存技术"
+    )
+    private String locationTitle;
+
+    @ApiModelProperty(
+            value = "打卡地点详细地址",
+            example = "广东省深圳市宝安区新安街道兴业路金利通金融中心"
+    )
+    private String locationDetail;
+
+    @ApiModelProperty(
+            value = "WiFi 名称",
+            notes = "未连接公司WiFi时通常为固定文案",
+            example = "未连接到公司指定WiFi"
+    )
+    private String wifiName;
+
+    @ApiModelProperty(
+            value = "WiFi MAC 地址",
+            example = "00:dd:b6:e5:98:5a"
+    )
+    private String wifiMac;
+
+    @ApiModelProperty(value = "打卡备注说明",example = "")
+    private String notes;
+
+    @ApiModelProperty(value = "打卡照片/视频媒体ID列表",example = "[]")
+    private List<String> mediaIds;
+
+    @ApiModelProperty(
+            value = "位置打卡地点纬度,是实际纬度的1000000倍,与腾讯地图一致采用GCJ-02坐标系统标准",
+            example = "22551739"
+    )
+    private String lat;
+
+    @ApiModelProperty(value = "位置打卡地点纬度,是实际纬度的1000000倍,与腾讯地图一致采用GCJ-02坐标系统标准",
+            example = "113879515")
+    private String lng;
+
+    @ApiModelProperty(value = "设备唯一标识",example = "1f758b0ea9f2b33a"    )
+    private String deviceId;
+
+    @ApiModelProperty(value = "考勤组ID",
+            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;
+//    }
+}

+ 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";
 
 
 

+ 4 - 2
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;
@@ -38,6 +39,7 @@ public interface CorpWeChatService {
      */
     WechatToken getJSApiTicket();
 
+    WechatToken getAddressAccessTokenFromTencent();
     /**
      * 返回用于企业微信登陆所需要的参数
      *
@@ -97,7 +99,7 @@ public interface CorpWeChatService {
     // boolean sendTextCardMsg(@NotNull String title, @NotNull String description, @NotNull String redirectionUrl, Set<String> userSet, Set<Long> deptSet);
 
 
-    void syncWxUserIdByMobile(List<UserVo> userList);
+    String syncWxUserIdByMobile(String token,String mobile);
     /**
      * 发送卡片消息
      *
@@ -120,5 +122,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);
 }

+ 12 - 19
storlead-wx/src/main/java/com/storlead/wx/service/impl/CorpWeChatServiceImpl.java

@@ -4,13 +4,9 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONObject;
 import com.alibaba.fastjson.JSON;
 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;
@@ -19,8 +15,6 @@ import com.storlead.wx.util.CorpWechatUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -83,7 +77,8 @@ public class CorpWeChatServiceImpl implements CorpWeChatService {
      * @author blank
      * @date 2021-3-8 下午 2:59
      */
-    private WechatToken getAddressAccessTokenFromTencent() {
+    @Override
+    public WechatToken getAddressAccessTokenFromTencent() {
         return CorpWechatUtil.getAccessToken(CorpWeChatConstants.GET_ACCESS_TOKEN_URL, CorpWeChatProperties.getCorpId(), CorpWeChatProperties.getCorpAgentSecret());
     }
 
@@ -174,15 +169,13 @@ public class CorpWeChatServiceImpl implements CorpWeChatService {
 
 
     @Override
-    public void syncWxUserIdByMobile(List<UserVo> userList) {
-        String token = getAddressAccessTokenFromTencent().getToken();
-        for(UserVo user : userList) {
-            try{
-                String workUserId = CorpWechatUtil.getWxUserIdByMobile(CorpWeChatConstants.GET_USER_ID_BY_MOBILE_URL, token, user.getMobile());
-                user.setXworkUserId(workUserId);
-            }catch (Exception e) {
-                log.error("syncUserOpenIdFormTencent ------------error = ",e);
-            }
+    public String syncWxUserIdByMobile(String token,String mobile) {
+        try{
+            String workUserId = CorpWechatUtil.getWxUserIdByMobile(CorpWeChatConstants.GET_USER_ID_BY_MOBILE_URL, token, mobile);
+            return workUserId;
+        }catch (Exception e) {
+            log.error("syncUserOpenIdFormTencent ------------error = ",e);
+            return "";
         }
     }
 
@@ -331,10 +324,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;
     }
 

+ 12 - 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;
@@ -161,7 +158,7 @@ public class CorpWechatUtil {
                 return userid;
             }
         }
-        return null;
+        return "";
     }
 
     /**
@@ -171,24 +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;
             }
         }

+ 1 - 1
ui/sp-user-center/.env.development

@@ -1,5 +1,5 @@
 # 页面标题
-VITE_APP_TITLE = 领存应用平台
+VITE_APP_TITLE = 领存统一门户
 
 # 开发环境配置
 VITE_APP_ENV = 'development'

+ 1 - 1
ui/sp-user-center/.env.production

@@ -1,5 +1,5 @@
 # 页面标题
-VITE_APP_TITLE = 领存应用平台
+VITE_APP_TITLE = 领存统一门户
 
 # 生产环境配置
 VITE_APP_ENV = 'production'

+ 2 - 2
ui/sp-user-center/.env.test

@@ -1,5 +1,5 @@
 # 页面标题
-VITE_APP_TITLE = 领存应用平台
+VITE_APP_TITLE = 领存统一门户
 
 # 生产环境配置
 VITE_APP_ENV = 'test'
@@ -32,7 +32,7 @@ VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
 # websocket 开关
 VITE_APP_WEBSOCKET = true
 
-VITE_APP_BASE_URL = 'https://sales.test.storlead.com/'
+VITE_APP_BASE_URL = 'https://app.test.storlead.com/'
 
 VITE_APP_PAGESIZE = 10
 

+ 1 - 1
ui/sp-user-center/index.html

@@ -7,7 +7,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
     <link rel="shortcut icon" type="image/x-icon" href="/src/assets/icons/icon_logo.png" />
       <script type="text/javascript" src="https://rescdn.qqmail.com/node/ww/wwopenmng/js/sso/wwLogin-1.0.0.js"></script>
-    <title>领存应用平台</title>
+    <title>领存统一门户</title>
     <!--[if lt IE 11
       ]><script>
         window.location.href='/html/ie.html';

+ 1 - 1
ui/sp-user-center/package.json

@@ -1,7 +1,7 @@
 {
   "name": "sp-sales-management",
   "version": "5.1.2",
-  "description": "领存应用平台",
+  "description": "领存统一门户",
   "author": "lusa",
   "license": "MIT",
   "type": "module",