From 8e3309ef57424194ce9683175b59d3c9e8cb0b27 Mon Sep 17 00:00:00 2001
From: tjx <t2856754968@163.com>
Date: 星期二, 23 十二月 2025 14:22:33 +0800
Subject: [PATCH] 111

---
 src/test/java/com/gs/dingtalk/DeviceReceivingApplicationTests.java          |    9 +
 src/main/java/com/gs/dingtalk/service/QwCheckinDayDataService.java          |   46 +++++
 src/main/java/com/gs/dingtalk/service/impl/QwCheckinDayDataServiceImpl.java |  178 ++++++++++++++++++++++
 src/main/resources/mapper/QwCheckinDayDataMapper.xml                        |    6 
 src/main/java/com/gs/dingtalk/mapper/QwCheckinDayDataMapper.java            |   12 +
 src/main/java/com/gs/dingtalk/entity/QwCheckinDayData.java                  |  170 +++++++++++++++++++++
 6 files changed, 421 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/gs/dingtalk/entity/QwCheckinDayData.java b/src/main/java/com/gs/dingtalk/entity/QwCheckinDayData.java
new file mode 100644
index 0000000..a49c74b
--- /dev/null
+++ b/src/main/java/com/gs/dingtalk/entity/QwCheckinDayData.java
@@ -0,0 +1,170 @@
+package com.gs.dingtalk.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 浼佷笟寰俊鎵撳崱鏃ユ姤鏁版嵁
+ * @TableName QW_CHECKIN_DAY_DATA
+ */
+@TableName(value = "QW_CHECKIN_DAY_DATA")
+@Data
+@KeySequence(value = "SEQ_QW_CHECKIN_DAY_DATA", dbType = DbType.ORACLE)
+public class QwCheckinDayData implements Serializable {
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭ID
+     */
+    @TableId
+    private Long id;
+
+    /**
+     * 鏃ユ姤鏃ユ湡锛圲nix鏃堕棿鎴筹級
+     */
+    private Long reportDate;
+
+    /**
+     * 鏃ユ姤鏃ユ湡锛堣浆鎹㈠悗鐨勬棩鏈燂級
+     */
+    private Date reportDatetime;
+
+    /**
+     * 鐢ㄦ埛璐﹀彿(userid)
+     */
+    private String acctid;
+
+    /**
+     * 鍛樺伐濮撳悕
+     */
+    private String name;
+
+    /**
+     * 鍛樺伐鍒悕
+     */
+    private String nameEx;
+
+    /**
+     * 鎵�灞為儴闂紙澶氫釜閮ㄩ棬浠ュ垎鍙峰垎闅旓級
+     */
+    private String departsName;
+
+    /**
+     * 璁板綍绫诲瀷锛�1-鍥哄畾涓婁笅鐝紱3-鎸夌彮娆′笂涓嬬彮锛�4-鑷敱绛惧埌锛�5-鍔犵彮锛�7-鏃犺鍒�
+     */
+    private Integer recordType;
+
+    /**
+     * 鏃ユ姤绫诲瀷锛�0-宸ヤ綔鏃ユ棩鎶ワ紱1-浼戞伅鏃ユ棩鎶�
+     */
+    private Integer dayType;
+
+    /**
+     * 瑙勫垯ID
+     */
+    private Integer groupid;
+
+    /**
+     * 瑙勫垯鍚嶇О
+     */
+    private String groupname;
+
+    /**
+     * 鐝ID
+     */
+    private Integer scheduleid;
+
+    /**
+     * 鐝鍚嶇О
+     */
+    private String schedulename;
+
+    /**
+     * 褰撴棩鎵撳崱娆℃暟
+     */
+    private Integer checkinCount;
+
+    /**
+     * 褰撴棩瀹為檯宸ヤ綔鏃堕暱锛堢锛�
+     */
+    private Integer regularWorkSec;
+
+    /**
+     * 褰撴棩鏍囧噯宸ヤ綔鏃堕暱锛堢锛�
+     */
+    private Integer standardWorkSec;
+
+    /**
+     * 褰撴棩鏈�鏃╂墦鍗℃椂闂达紙璺�0鐐圭鏁帮級
+     */
+    private Integer earliestTime;
+
+    /**
+     * 褰撴棩鏈�鏅氭墦鍗℃椂闂达紙璺�0鐐圭鏁帮級
+     */
+    private Integer lastestTime;
+
+    /**
+     * 杩熷埌娆℃暟
+     */
+    private Integer lateCount;
+
+    /**
+     * 杩熷埌鏃堕暱锛堢锛�
+     */
+    private Integer lateDuration;
+
+    /**
+     * 鏃╅��娆℃暟
+     */
+    private Integer earlyLeaveCount;
+
+    /**
+     * 鏃╅��鏃堕暱锛堢锛�
+     */
+    private Integer earlyLeaveDuration;
+
+    /**
+     * 缂哄崱娆℃暟
+     */
+    private Integer absentCount;
+
+    /**
+     * 鏃峰伐娆℃暟
+     */
+    private Integer absenteeismCount;
+
+    /**
+     * 鏃峰伐鏃堕暱锛堢锛�
+     */
+    private Integer absenteeismDuration;
+
+    /**
+     * 鍦扮偣寮傚父娆℃暟
+     */
+    private Integer locationExCount;
+
+    /**
+     * 璁惧寮傚父娆℃暟
+     */
+    private Integer deviceExCount;
+
+    /**
+     * 鍔犵彮鐘舵�侊細0-鏃犲姞鐝紱1-姝e父锛�2-缂烘椂闀�
+     */
+    private Integer otStatus;
+
+    /**
+     * 鍔犵彮鏃堕暱锛堢锛�
+     */
+    private Integer otDuration;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
+}
diff --git a/src/main/java/com/gs/dingtalk/mapper/QwCheckinDayDataMapper.java b/src/main/java/com/gs/dingtalk/mapper/QwCheckinDayDataMapper.java
new file mode 100644
index 0000000..004acb4
--- /dev/null
+++ b/src/main/java/com/gs/dingtalk/mapper/QwCheckinDayDataMapper.java
@@ -0,0 +1,12 @@
+package com.gs.dingtalk.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gs.dingtalk.entity.QwCheckinDayData;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 浼佷笟寰俊鎵撳崱鏃ユ姤鏁版嵁Mapper
+ */
+@Mapper
+public interface QwCheckinDayDataMapper extends BaseMapper<QwCheckinDayData> {
+}
diff --git a/src/main/java/com/gs/dingtalk/service/QwCheckinDayDataService.java b/src/main/java/com/gs/dingtalk/service/QwCheckinDayDataService.java
new file mode 100644
index 0000000..c0e20c7
--- /dev/null
+++ b/src/main/java/com/gs/dingtalk/service/QwCheckinDayDataService.java
@@ -0,0 +1,46 @@
+package com.gs.dingtalk.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.gs.dingtalk.entity.QwCheckinDayData;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 浼佷笟寰俊鎵撳崱鏃ユ姤鏁版嵁Service
+ */
+public interface QwCheckinDayDataService extends IService<QwCheckinDayData> {
+
+    /**
+     * 灏咰heckinDayData杞崲涓篞wCheckinDayData瀹炰綋
+     *
+     * @param dayData 浼佷笟寰俊鎵撳崱鏃ユ姤鏁版嵁
+     * @return QwCheckinDayData瀹炰綋
+     */
+    QwCheckinDayData convertToEntity(WorkWXService.CheckinDayData dayData);
+
+    /**
+     * 鎵归噺淇濆瓨鎵撳崱鏃ユ姤鏁版嵁锛堣嚜鍔ㄥ幓閲嶏紝鎸塧cctid+report_date锛�
+     *
+     * @param dayDataList 鎵撳崱鏃ユ姤鏁版嵁鍒楄〃
+     * @return 鏂板璁板綍鏁�
+     */
+    int saveDayDataBatch(List<WorkWXService.CheckinDayData> dayDataList);
+
+    /**
+     * 鍚屾鎸囧畾鏃ユ湡鐨勬墦鍗℃棩鎶ユ暟鎹埌鏁版嵁搴�
+     *
+     * @param date 鏃ユ湡锛圲nix鏃堕棿鎴筹紝闇�涓哄綋澶�0鐐癸級
+     * @return 鏂板璁板綍鏁�
+     * @throws IOException 鑾峰彇鎵撳崱鏃ユ姤鏁版嵁寮傚父
+     */
+    int syncDayData(long date) throws IOException;
+
+    /**
+     * 鍚屾鏄ㄥぉ鐨勬墦鍗℃棩鎶ユ暟鎹埌鏁版嵁搴�
+     *
+     * @return 鏂板璁板綍鏁�
+     * @throws IOException 鑾峰彇鎵撳崱鏃ユ姤鏁版嵁寮傚父
+     */
+    int syncYesterdayDayData() throws IOException;
+}
diff --git a/src/main/java/com/gs/dingtalk/service/impl/QwCheckinDayDataServiceImpl.java b/src/main/java/com/gs/dingtalk/service/impl/QwCheckinDayDataServiceImpl.java
new file mode 100644
index 0000000..bfde440
--- /dev/null
+++ b/src/main/java/com/gs/dingtalk/service/impl/QwCheckinDayDataServiceImpl.java
@@ -0,0 +1,178 @@
+package com.gs.dingtalk.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.gs.dingtalk.entity.QwCheckinDayData;
+import com.gs.dingtalk.mapper.QwCheckinDayDataMapper;
+import com.gs.dingtalk.service.QwCheckinDayDataService;
+import com.gs.dingtalk.service.WorkWXService;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 浼佷笟寰俊鎵撳崱鏃ユ姤鏁版嵁Service瀹炵幇
+ */
+@Service
+@RequiredArgsConstructor
+public class QwCheckinDayDataServiceImpl extends ServiceImpl<QwCheckinDayDataMapper, QwCheckinDayData>
+        implements QwCheckinDayDataService {
+
+    private static final Logger log = LoggerFactory.getLogger(QwCheckinDayDataServiceImpl.class);
+
+    private final WorkWXService workWXService;
+
+    @Override
+    public QwCheckinDayData convertToEntity(WorkWXService.CheckinDayData dayData) {
+        if (dayData == null) {
+            return null;
+        }
+
+        QwCheckinDayData entity = new QwCheckinDayData();
+
+        // 鍩虹淇℃伅
+        WorkWXService.BaseInfo baseInfo = dayData.getBaseInfo();
+        if (baseInfo != null) {
+            entity.setReportDate(baseInfo.getDate());
+            if (baseInfo.getDate() != null) {
+                entity.setReportDatetime(new Date(baseInfo.getDate() * 1000));
+            }
+            entity.setAcctid(baseInfo.getAcctid());
+            entity.setName(baseInfo.getName());
+            entity.setNameEx(baseInfo.getNameEx());
+            entity.setDepartsName(baseInfo.getDepartsName());
+            entity.setRecordType(baseInfo.getRecordType());
+            entity.setDayType(baseInfo.getDayType());
+
+            // 瑙勫垯淇℃伅
+            WorkWXService.RuleInfo ruleInfo = baseInfo.getRuleInfo();
+            if (ruleInfo != null) {
+                entity.setGroupid(ruleInfo.getGroupid());
+                entity.setGroupname(ruleInfo.getGroupname());
+                entity.setScheduleid(ruleInfo.getScheduleid());
+                entity.setSchedulename(ruleInfo.getSchedulename());
+            }
+        }
+
+        // 姹囨�讳俊鎭�
+        WorkWXService.SummaryInfo summaryInfo = dayData.getSummaryInfo();
+        if (summaryInfo != null) {
+            entity.setCheckinCount(summaryInfo.getCheckinCount());
+            entity.setRegularWorkSec(summaryInfo.getRegularWorkSec());
+            entity.setStandardWorkSec(summaryInfo.getStandardWorkSec());
+            entity.setEarliestTime(summaryInfo.getEarliestTime());
+            entity.setLastestTime(summaryInfo.getLastestTime());
+        }
+
+        // 寮傚父淇℃伅 - 鍒濆鍖栭粯璁ゅ��
+        entity.setLateCount(0);
+        entity.setLateDuration(0);
+        entity.setEarlyLeaveCount(0);
+        entity.setEarlyLeaveDuration(0);
+        entity.setAbsentCount(0);
+        entity.setAbsenteeismCount(0);
+        entity.setAbsenteeismDuration(0);
+        entity.setLocationExCount(0);
+        entity.setDeviceExCount(0);
+
+        // 瑙f瀽寮傚父淇℃伅
+        List<WorkWXService.ExceptionInfo> exceptionInfos = dayData.getExceptionInfos();
+        if (exceptionInfos != null && !exceptionInfos.isEmpty()) {
+            for (WorkWXService.ExceptionInfo ex : exceptionInfos) {
+                if (ex.getException() == null) continue;
+                switch (ex.getException()) {
+                    case 1: // 杩熷埌
+                        entity.setLateCount(ex.getCount() != null ? ex.getCount() : 0);
+                        entity.setLateDuration(ex.getDuration() != null ? ex.getDuration() : 0);
+                        break;
+                    case 2: // 鏃╅��
+                        entity.setEarlyLeaveCount(ex.getCount() != null ? ex.getCount() : 0);
+                        entity.setEarlyLeaveDuration(ex.getDuration() != null ? ex.getDuration() : 0);
+                        break;
+                    case 3: // 缂哄崱
+                        entity.setAbsentCount(ex.getCount() != null ? ex.getCount() : 0);
+                        break;
+                    case 4: // 鏃峰伐
+                        entity.setAbsenteeismCount(ex.getCount() != null ? ex.getCount() : 0);
+                        entity.setAbsenteeismDuration(ex.getDuration() != null ? ex.getDuration() : 0);
+                        break;
+                    case 5: // 鍦扮偣寮傚父
+                        entity.setLocationExCount(ex.getCount() != null ? ex.getCount() : 0);
+                        break;
+                    case 6: // 璁惧寮傚父
+                        entity.setDeviceExCount(ex.getCount() != null ? ex.getCount() : 0);
+                        break;
+                }
+            }
+        }
+
+        // 鍔犵彮淇℃伅
+        entity.setOtStatus(0);
+        entity.setOtDuration(0);
+        WorkWXService.OtInfo otInfo = dayData.getOtInfo();
+        if (otInfo != null) {
+            entity.setOtStatus(otInfo.getOtStatus() != null ? otInfo.getOtStatus() : 0);
+            entity.setOtDuration(otInfo.getOtDuration() != null ? otInfo.getOtDuration() : 0);
+        }
+
+        entity.setCreateTime(new Date());
+        return entity;
+    }
+
+    @Override
+    public int saveDayDataBatch(List<WorkWXService.CheckinDayData> dayDataList) {
+        if (dayDataList == null || dayDataList.isEmpty()) {
+            return 0;
+        }
+
+        int insertCount = 0;
+        for (WorkWXService.CheckinDayData dayData : dayDataList) {
+            QwCheckinDayData entity = convertToEntity(dayData);
+            if (entity == null || entity.getAcctid() == null || entity.getReportDate() == null) {
+                continue;
+            }
+
+            // 妫�鏌ユ槸鍚﹀凡瀛樺湪锛堟寜acctid + report_date鍘婚噸锛�
+            LambdaQueryWrapper<QwCheckinDayData> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(QwCheckinDayData::getAcctid, entity.getAcctid())
+                    .eq(QwCheckinDayData::getReportDate, entity.getReportDate());
+
+            QwCheckinDayData existing = this.getOne(wrapper);
+            if (existing != null) {
+                // 宸插瓨鍦ㄥ垯鏇存柊
+                entity.setId(existing.getId());
+                this.updateById(entity);
+                log.debug("鏇存柊鎵撳崱鏃ユ姤鏁版嵁: acctid={}, date={}", entity.getAcctid(), entity.getReportDatetime());
+            } else {
+                // 涓嶅瓨鍦ㄥ垯鎻掑叆
+                this.save(entity);
+                insertCount++;
+                log.debug("鏂板鎵撳崱鏃ユ姤鏁版嵁: acctid={}, date={}", entity.getAcctid(), entity.getReportDatetime());
+            }
+        }
+
+        log.info("鎵撳崱鏃ユ姤鏁版嵁淇濆瓨瀹屾垚锛屾柊澧�: {}, 鎬诲鐞�: {}", insertCount, dayDataList.size());
+        return insertCount;
+    }
+
+    @Override
+    public int syncDayData(long date) throws IOException {
+        List<WorkWXService.CheckinDayData> dayDataList = workWXService.getCheckinDayDataByQwStaff(date, date);
+        return saveDayDataBatch(dayDataList);
+    }
+
+    @Override
+    public int syncYesterdayDayData() throws IOException {
+        long currentTime = System.currentTimeMillis() / 1000;
+        long oneDaySeconds = 86400;
+        long yesterdayStart = ((currentTime / oneDaySeconds) - 1) * oneDaySeconds;
+
+        log.info("寮�濮嬪悓姝ユ槰澶�({})鐨勬墦鍗℃棩鎶ユ暟鎹�", new Date(yesterdayStart * 1000));
+        return syncDayData(yesterdayStart);
+    }
+}
diff --git a/src/main/resources/mapper/QwCheckinDayDataMapper.xml b/src/main/resources/mapper/QwCheckinDayDataMapper.xml
new file mode 100644
index 0000000..cb289d4
--- /dev/null
+++ b/src/main/resources/mapper/QwCheckinDayDataMapper.xml
@@ -0,0 +1,6 @@
+<?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.gs.dingtalk.mapper.QwCheckinDayDataMapper">
+
+
+</mapper>
diff --git a/src/test/java/com/gs/dingtalk/DeviceReceivingApplicationTests.java b/src/test/java/com/gs/dingtalk/DeviceReceivingApplicationTests.java
index e61b889..8e3997b 100644
--- a/src/test/java/com/gs/dingtalk/DeviceReceivingApplicationTests.java
+++ b/src/test/java/com/gs/dingtalk/DeviceReceivingApplicationTests.java
@@ -9,6 +9,7 @@
 import com.gs.dingtalk.service.SimpleExample;
 import com.gs.dingtalk.service.VwCjScSjTsBbService;
 import com.gs.dingtalk.service.WorkWXService;
+import com.gs.dingtalk.service.QwCheckinDayDataService;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -33,6 +34,9 @@
 
     @Autowired
     private QwCheckinDataService qwCheckinDataService;
+
+    @Autowired
+    private QwCheckinDayDataService qwCheckinDayDataService;
 
     /**
      * 娴嬭瘯瀵煎嚭鐢熶骇鏁版嵁骞跺彂閫侀拤閽夋秷鎭�
@@ -285,6 +289,11 @@
                         });
                     }
                 });
+
+                // 淇濆瓨鍒版暟鎹簱
+                System.out.println("  - 寮�濮嬩繚瀛樻墦鍗℃棩鎶ユ暟鎹埌鏁版嵁搴�...");
+                int insertCount = qwCheckinDayDataService.saveDayDataBatch(dayDataList);
+                System.out.println("鉁� 淇濆瓨瀹屾垚锛屾柊澧炶褰曟暟: " + insertCount + ", 鏇存柊(宸插瓨鍦�): " + (dayDataList.size() - insertCount));
             } else {
                 System.out.println("鉁� 鑾峰彇鐨勬墦鍗℃棩鎶ユ暟鎹负绌�");
             }

--
Gitblit v1.9.3