You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

考勤数据处理异常求助:日期重复、上下班时间分配错误

解决考勤记录合并与字段填充问题

看起来你的代码里有两个关键问题导致了当前的错误:条件判断用了赋值运算符而非比较运算符,以及没有按员工+日期合并考勤记录。咱们一步步来修复:

问题根源分析

  1. 条件判断的运算符错误:你在if判断里用了=(赋值)而不是==(比较),比如if($row->status='C/Out'),这会把$row->status强制设为C/Out,并且这个表达式永远返回真,导致你的时间填充逻辑完全混乱。
  2. 未合并同一日期的记录:你现在是逐条插入原始数据,所以同一个员工同一天的C/In和C/Out会被分成两条记录插入,自然出现日期重复,且两个字段无法正确对应。

修复后的代码实现

我们先把原始数据按「员工ID+日期」分组,收集同一天的上班和下班时间,再统一插入合并后的记录:

public function processTimesheet(){
    $this->load->model('dbquery');
    
    // 先查询所有原始考勤数据
    $query = $this->db->query("SELECT * FROM tbldumpbio");
    
    // 用数组按员工ID+日期分组存储考勤信息
    $attendanceData = [];
    foreach ($query->result() as $row){
        $dateTimeExplArr = explode(' ', $row->datetimex);
        $dateStr = $dateTimeExplArr[0];
        $timeStr = $dateTimeExplArr[1] ?? ''; // 用null合并运算符处理空时间
        
        // 生成唯一键:员工ID+日期,确保同一员工同一天的记录归为一组
        $key = $row->empid . '_' . $dateStr;
        
        // 初始化分组数据(如果不存在的话)
        if (!isset($attendanceData[$key])) {
            $attendanceData[$key] = [
                'name' => $row->name,
                'empCompID' => $row->empid,
                'date' => $dateStr,
                'timeIn' => '',
                'timeOut' => ''
            ];
        }
        
        // 正确判断状态并填充对应时间(注意用==比较)
        if ($row->status == 'C/In' && !empty($timeStr)) {
            $attendanceData[$key]['timeIn'] = $timeStr;
        } elseif ($row->status == 'C/Out' && !empty($timeStr)) {
            $attendanceData[$key]['timeOut'] = $timeStr;
        }
    }
    
    // 遍历分组后的数组,插入合并后的记录
    foreach ($attendanceData as $data) {
        // 补充其他默认字段
        $insertData = array_merge($data, [
            'ID' => '',
            'companyAccessID' => '',
            'status' => '',
            'inputType' => ''
        ]);
        $this->dbquery->modInsertval('tblempbioupload', $insertData);
    }
}

关键改进点说明

  • 修正运算符错误:把=改成==,确保是比较状态而非赋值。
  • 分组存储数据:用员工ID+日期作为唯一键,把同一天的C/In和C/Out时间合并到同一个数组元素里,避免重复记录。
  • 安全处理空时间:用?? ''(PHP7+支持)处理可能不存在的时间字段,避免isset判断的冗余。
  • 统一插入合并记录:最后只插入每组的一条记录,确保同一日期只有一条考勤记录,且timeIn和timeOut字段正确填充。

额外优化建议

如果你的tbldumpbio表数据量很大,建议直接在SQL查询时就按员工和日期分组,用聚合函数获取对应的In/Out时间,这样效率更高:

SELECT 
    empid,
    name,
    DATE(datetimex) as date_str,
    MAX(CASE WHEN status = 'C/In' THEN TIME(datetimex) END) as time_in,
    MAX(CASE WHEN status = 'C/Out' THEN TIME(datetimex) END) as time_out
FROM tbldumpbio
GROUP BY empid, name, DATE(datetimex)

然后直接用这个查询结果来插入,省去PHP里的分组逻辑,性能会更好。

内容的提问来源于stack exchange,提问作者zeus2026

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:46:25