-- ============================================================================= -- 说明:将「已终审通过」的请假单(默认仅年假)按自然日写入/更新 lq_attendance_record。 -- 重要:部分库里 FLOW_TASK.F_Id 与请假单 F_Id 不一致,但 F_PROCESSID 会等于请假单 F_Id, -- 旧脚本只用 F_Id 关联会导致「预览有数据、INSERT 0 行」。本版已改为 F_Id 或 F_PROCESSID 匹配。 -- 兼容:MySQL 5.7 / 8.x -- ============================================================================= -- --------------------------------------------------------------------------- -- 零、诊断(先看这个:到底流程表和请假单能不能对上) -- --------------------------------------------------------------------------- -- 0a) 年假单在不在 -- SELECT F_Id, F_BILLNO, F_LEAVETYPE, HEX(F_LEAVETYPE) AS type_hex, -- F_LEAVESTARTTIME, F_LEAVEENDTIME, F_APPLYUSER -- FROM wform_leaveapply -- WHERE TRIM(IFNULL(F_LEAVETYPE,'')) LIKE '%年假%' -- ORDER BY F_LEAVESTARTTIME DESC -- LIMIT 20; -- 0b) 同一条请假单:用 F_Id 关联流程(旧逻辑) -- SELECT la.F_Id, la.F_BILLNO, ft.F_Id AS task_id, ft.F_PROCESSID, ft.F_STATUS, ft.F_CREATORUSERID -- FROM wform_leaveapply la -- LEFT JOIN flow_task ft ON ft.F_Id = la.F_Id -- WHERE la.F_Id = '把你的请假单F_Id贴这里'; -- 0c) 同一条:用 F_PROCESSID 关联(新逻辑常命中这条) -- SELECT la.F_Id, la.F_BILLNO, ft.F_Id AS task_id, ft.F_PROCESSID, ft.F_STATUS, ft.F_CREATORUSERID -- FROM wform_leaveapply la -- LEFT JOIN flow_task ft ON ft.F_PROCESSID = la.F_Id -- WHERE la.F_Id = '把你的请假单F_Id贴这里'; -- 说明:F_STATUS=2 表示审核通过。若 0b 无行、0c 有行,必须用本文件下面的「关联子查询」版本。 -- --------------------------------------------------------------------------- -- 序列表子查询(0~999),下面多处复用 -- --------------------------------------------------------------------------- -- (内联写在各语句中,避免 MySQL 5.7 无 CTE 时无法复用临时表名) -- --------------------------------------------------------------------------- -- 一、预览(已改为:流程通过 + (F_Id 或 F_PROCESSID) 匹配请假单) -- --------------------------------------------------------------------------- SELECT la.F_Id AS leave_id, DATE_ADD(DATE(la.F_LEAVESTARTTIME), INTERVAL seq.n DAY) AS attendance_date, TRIM(la.F_LEAVETYPE) AS leave_type, la.F_BILLNO AS bill_no, COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid) AS target_user_id, u.F_REALNAME AS employee_name, CASE WHEN TRIM(la.F_LEAVETYPE) = '病假' THEN 5 ELSE 4 END AS attendance_status, LEFT( CONCAT('请假审批通过:', TRIM(IFNULL(la.F_LEAVETYPE, '')), '(单号 ', IFNULL(la.F_BILLNO, ''), ')'), 500 ) AS remark_text FROM wform_leaveapply la INNER JOIN ( SELECT la2.F_Id AS LID, ( SELECT ft.F_CREATORUSERID FROM flow_task ft WHERE ft.F_STATUS = 2 AND (ft.F_Id = la2.F_Id OR (ft.F_PROCESSID IS NOT NULL AND TRIM(ft.F_PROCESSID) <> '' AND ft.F_PROCESSID = la2.F_Id)) ORDER BY IFNULL(ft.F_LastModifyTime, ft.F_CREATORTIME) DESC LIMIT 1 ) AS creator_uid FROM wform_leaveapply la2 ) lc ON lc.LID = la.F_Id AND lc.creator_uid IS NOT NULL INNER JOIN ( SELECT d1.n + d2.n * 10 + d3.n * 100 AS n FROM ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d1 CROSS JOIN ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d2 CROSS JOIN ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d3 ) seq ON seq.n <= DATEDIFF(DATE(la.F_LEAVEENDTIME), DATE(la.F_LEAVESTARTTIME)) LEFT JOIN base_user u ON u.F_Id = COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid) AND (u.F_DeleteMark IS NULL OR u.F_DeleteMark = 0) WHERE la.F_LEAVESTARTTIME IS NOT NULL AND la.F_LEAVEENDTIME IS NOT NULL AND DATE(la.F_LEAVEENDTIME) >= DATE(la.F_LEAVESTARTTIME) AND TRIM(IFNULL(la.F_LEAVETYPE, '')) = '年假' ORDER BY la.F_Id, attendance_date; -- --------------------------------------------------------------------------- -- 1b、与「二、写入」相同条件的行数(应为 ≥1) -- --------------------------------------------------------------------------- SELECT COUNT(*) AS rows_would_insert FROM wform_leaveapply la INNER JOIN ( SELECT la2.F_Id AS LID, ( SELECT ft.F_CREATORUSERID FROM flow_task ft WHERE ft.F_STATUS = 2 AND (ft.F_Id = la2.F_Id OR (ft.F_PROCESSID IS NOT NULL AND TRIM(ft.F_PROCESSID) <> '' AND ft.F_PROCESSID = la2.F_Id)) ORDER BY IFNULL(ft.F_LastModifyTime, ft.F_CREATORTIME) DESC LIMIT 1 ) AS creator_uid FROM wform_leaveapply la2 ) lc ON lc.LID = la.F_Id AND lc.creator_uid IS NOT NULL INNER JOIN ( SELECT d1.n + d2.n * 10 + d3.n * 100 AS n FROM ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d1 CROSS JOIN ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d2 CROSS JOIN ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d3 ) seq ON seq.n <= DATEDIFF(DATE(la.F_LEAVEENDTIME), DATE(la.F_LEAVESTARTTIME)) LEFT JOIN base_user u ON u.F_Id = COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid) AND (u.F_DeleteMark IS NULL OR u.F_DeleteMark = 0) LEFT JOIN lq_mdxx m ON m.F_Id = u.F_MDID LEFT JOIN lq_attendance_group g ON g.F_Id = u.F_AttendanceGroupId AND IFNULL(g.F_DeleteMark, 0) = 0 WHERE la.F_LEAVESTARTTIME IS NOT NULL AND la.F_LEAVEENDTIME IS NOT NULL AND DATE(la.F_LEAVEENDTIME) >= DATE(la.F_LEAVESTARTTIME) AND TRIM(IFNULL(la.F_LEAVETYPE, '')) = '年假'; -- --------------------------------------------------------------------------- -- 二、写入(已取消块注释,执行前务必确认 1b > 0;建议先备份表) -- --------------------------------------------------------------------------- INSERT INTO lq_attendance_record ( F_Id, F_UserId, F_EmployeeName, F_StoreId, F_StoreName, F_AttendanceGroupId, F_AttendanceGroupName, F_AttendanceDate, F_PunchInTime, F_PunchOutTime, F_Status, F_LateMinutes, F_EarlyLeaveMinutes, F_IsManual, F_Remark, F_RuleSnapshotJson, F_AllRuleSnapshotJson, F_CreateUserId, F_CreateTime, F_UpdateUserId, F_UpdateTime, F_IsEffective ) SELECT CONCAT('L', REPLACE(UUID(), '-', '')) AS F_Id, COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid) AS F_UserId, IFNULL(u.F_REALNAME, '') AS F_EmployeeName, u.F_MDID AS F_StoreId, m.dm AS F_StoreName, u.F_AttendanceGroupId AS F_AttendanceGroupId, g.F_GroupName AS F_AttendanceGroupName, DATE_ADD(DATE(la.F_LEAVESTARTTIME), INTERVAL seq.n DAY) AS F_AttendanceDate, NULL AS F_PunchInTime, NULL AS F_PunchOutTime, CASE WHEN TRIM(la.F_LEAVETYPE) = '病假' THEN 5 ELSE 4 END AS F_Status, 0 AS F_LateMinutes, 0 AS F_EarlyLeaveMinutes, 1 AS F_IsManual, LEFT( CONCAT('请假审批通过:', TRIM(IFNULL(la.F_LEAVETYPE, '')), '(单号 ', IFNULL(la.F_BILLNO, ''), ')'), 500 ) AS F_Remark, '{}' AS F_RuleSnapshotJson, '{}' AS F_AllRuleSnapshotJson, 'system' AS F_CreateUserId, NOW() AS F_CreateTime, 'system' AS F_UpdateUserId, NOW() AS F_UpdateTime, 1 AS F_IsEffective FROM wform_leaveapply la INNER JOIN ( SELECT la2.F_Id AS LID, ( SELECT ft.F_CREATORUSERID FROM flow_task ft WHERE ft.F_STATUS = 2 AND (ft.F_Id = la2.F_Id OR (ft.F_PROCESSID IS NOT NULL AND TRIM(ft.F_PROCESSID) <> '' AND ft.F_PROCESSID = la2.F_Id)) ORDER BY IFNULL(ft.F_LastModifyTime, ft.F_CREATORTIME) DESC LIMIT 1 ) AS creator_uid FROM wform_leaveapply la2 ) lc ON lc.LID = la.F_Id AND lc.creator_uid IS NOT NULL INNER JOIN ( SELECT d1.n + d2.n * 10 + d3.n * 100 AS n FROM ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d1 CROSS JOIN ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d2 CROSS JOIN ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d3 ) seq ON seq.n <= DATEDIFF(DATE(la.F_LEAVEENDTIME), DATE(la.F_LEAVESTARTTIME)) LEFT JOIN base_user u ON u.F_Id = COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid) AND (u.F_DeleteMark IS NULL OR u.F_DeleteMark = 0) LEFT JOIN lq_mdxx m ON m.F_Id = u.F_MDID LEFT JOIN lq_attendance_group g ON g.F_Id = u.F_AttendanceGroupId AND IFNULL(g.F_DeleteMark, 0) = 0 WHERE la.F_LEAVESTARTTIME IS NOT NULL AND la.F_LEAVEENDTIME IS NOT NULL AND DATE(la.F_LEAVEENDTIME) >= DATE(la.F_LEAVESTARTTIME) AND TRIM(IFNULL(la.F_LEAVETYPE, '')) = '年假' -- 若 F_UserId 为空会违反 NOT NULL,直接筛掉并避免「静默 0 行」误解 AND COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid) IS NOT NULL AND COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid) <> '' ON DUPLICATE KEY UPDATE F_Status = VALUES(F_Status), F_LateMinutes = 0, F_EarlyLeaveMinutes = 0, F_IsManual = 1, F_Remark = VALUES(F_Remark), F_RuleSnapshotJson = '{}', F_AllRuleSnapshotJson = '{}', F_EmployeeName = VALUES(F_EmployeeName), F_StoreId = VALUES(F_StoreId), F_StoreName = VALUES(F_StoreName), F_AttendanceGroupId = VALUES(F_AttendanceGroupId), F_AttendanceGroupName = VALUES(F_AttendanceGroupName), F_UpdateUserId = 'system', F_UpdateTime = NOW(), F_IsEffective = 1; -- --------------------------------------------------------------------------- -- 三、只补一条请假单(把 YOUR_LEAVE_ID 换成 F_Id;不限制年假时可去掉假种条件) -- --------------------------------------------------------------------------- /* INSERT INTO lq_attendance_record ( F_Id, F_UserId, F_EmployeeName, F_StoreId, F_StoreName, F_AttendanceGroupId, F_AttendanceGroupName, F_AttendanceDate, F_PunchInTime, F_PunchOutTime, F_Status, F_LateMinutes, F_EarlyLeaveMinutes, F_IsManual, F_Remark, F_RuleSnapshotJson, F_AllRuleSnapshotJson, F_CreateUserId, F_CreateTime, F_UpdateUserId, F_UpdateTime, F_IsEffective ) SELECT CONCAT('L', REPLACE(UUID(), '-', '')), COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid), IFNULL(u.F_REALNAME, ''), u.F_MDID, m.dm, u.F_AttendanceGroupId, g.F_GroupName, DATE_ADD(DATE(la.F_LEAVESTARTTIME), INTERVAL seq.n DAY), NULL, NULL, CASE WHEN TRIM(la.F_LEAVETYPE) = '病假' THEN 5 ELSE 4 END, 0, 0, 1, LEFT( CONCAT('请假审批通过:', TRIM(IFNULL(la.F_LEAVETYPE, '')), '(单号 ', IFNULL(la.F_BILLNO, ''), ')'), 500 ), '{}', '{}', 'system', NOW(), 'system', NOW(), 1 FROM wform_leaveapply la INNER JOIN ( SELECT la2.F_Id AS LID, ( SELECT ft.F_CREATORUSERID FROM flow_task ft WHERE ft.F_STATUS = 2 AND (ft.F_Id = la2.F_Id OR (ft.F_PROCESSID IS NOT NULL AND TRIM(ft.F_PROCESSID) <> '' AND ft.F_PROCESSID = la2.F_Id)) ORDER BY IFNULL(ft.F_LastModifyTime, ft.F_CREATORTIME) DESC LIMIT 1 ) AS creator_uid FROM wform_leaveapply la2 WHERE la2.F_Id = 'YOUR_LEAVE_ID' ) lc ON lc.LID = la.F_Id AND lc.creator_uid IS NOT NULL INNER JOIN ( SELECT d1.n + d2.n * 10 + d3.n * 100 AS n FROM ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d1 CROSS JOIN ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d2 CROSS JOIN ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d3 ) seq ON seq.n <= DATEDIFF(DATE(la.F_LEAVEENDTIME), DATE(la.F_LEAVESTARTTIME)) LEFT JOIN base_user u ON u.F_Id = COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid) AND (u.F_DeleteMark IS NULL OR u.F_DeleteMark = 0) LEFT JOIN lq_mdxx m ON m.F_Id = u.F_MDID LEFT JOIN lq_attendance_group g ON g.F_Id = u.F_AttendanceGroupId AND IFNULL(g.F_DeleteMark, 0) = 0 WHERE la.F_Id = 'YOUR_LEAVE_ID' AND la.F_LEAVESTARTTIME IS NOT NULL AND la.F_LEAVEENDTIME IS NOT NULL AND DATE(la.F_LEAVEENDTIME) >= DATE(la.F_LEAVESTARTTIME) AND COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid) IS NOT NULL AND COALESCE(NULLIF(TRIM(la.F_APPLYUSER), ''), lc.creator_uid) <> '' ON DUPLICATE KEY UPDATE F_Status = VALUES(F_Status), F_LateMinutes = 0, F_EarlyLeaveMinutes = 0, F_IsManual = 1, F_Remark = VALUES(F_Remark), F_RuleSnapshotJson = '{}', F_AllRuleSnapshotJson = '{}', F_EmployeeName = VALUES(F_EmployeeName), F_StoreId = VALUES(F_StoreId), F_StoreName = VALUES(F_StoreName), F_AttendanceGroupId = VALUES(F_AttendanceGroupId), F_AttendanceGroupName = VALUES(F_AttendanceGroupName), F_UpdateUserId = 'system', F_UpdateTime = NOW(), F_IsEffective = 1; */ -- --------------------------------------------------------------------------- -- 四、仍 0 行时:不依赖流程表,手工指定「员工用户Id」(BASE_USER.F_Id)强插(确认已终审再过) -- --------------------------------------------------------------------------- /* INSERT INTO lq_attendance_record ( F_Id, F_UserId, F_EmployeeName, F_StoreId, F_StoreName, F_AttendanceGroupId, F_AttendanceGroupName, F_AttendanceDate, F_PunchInTime, F_PunchOutTime, F_Status, F_LateMinutes, F_EarlyLeaveMinutes, F_IsManual, F_Remark, F_RuleSnapshotJson, F_AllRuleSnapshotJson, F_CreateUserId, F_CreateTime, F_UpdateUserId, F_UpdateTime, F_IsEffective ) SELECT CONCAT('L', REPLACE(UUID(), '-', '')), '手工填写BASE_USER的F_Id' AS F_UserId, IFNULL(u.F_REALNAME, ''), u.F_MDID, m.dm, u.F_AttendanceGroupId, g.F_GroupName, DATE_ADD(DATE(la.F_LEAVESTARTTIME), INTERVAL seq.n DAY), NULL, NULL, CASE WHEN TRIM(la.F_LEAVETYPE) = '病假' THEN 5 ELSE 4 END, 0, 0, 1, LEFT( CONCAT('请假审批通过:', TRIM(IFNULL(la.F_LEAVETYPE, '')), '(单号 ', IFNULL(la.F_BILLNO, ''), ')'), 500 ), '{}', '{}', 'system', NOW(), 'system', NOW(), 1 FROM wform_leaveapply la INNER JOIN ( SELECT d1.n + d2.n * 10 + d3.n * 100 AS n FROM ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d1 CROSS JOIN ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d2 CROSS JOIN ( SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) d3 ) seq ON seq.n <= DATEDIFF(DATE(la.F_LEAVEENDTIME), DATE(la.F_LEAVESTARTTIME)) INNER JOIN base_user u ON u.F_Id = '手工填写BASE_USER的F_Id' AND (u.F_DeleteMark IS NULL OR u.F_DeleteMark = 0) LEFT JOIN lq_mdxx m ON m.F_Id = u.F_MDID LEFT JOIN lq_attendance_group g ON g.F_Id = u.F_AttendanceGroupId AND IFNULL(g.F_DeleteMark, 0) = 0 WHERE la.F_Id = 'YOUR_LEAVE_ID' AND la.F_LEAVESTARTTIME IS NOT NULL AND la.F_LEAVEENDTIME IS NOT NULL AND DATE(la.F_LEAVEENDTIME) >= DATE(la.F_LEAVESTARTTIME) ON DUPLICATE KEY UPDATE F_Status = VALUES(F_Status), F_LateMinutes = 0, F_EarlyLeaveMinutes = 0, F_IsManual = 1, F_Remark = VALUES(F_Remark), F_RuleSnapshotJson = '{}', F_AllRuleSnapshotJson = '{}', F_EmployeeName = VALUES(F_EmployeeName), F_StoreId = VALUES(F_StoreId), F_StoreName = VALUES(F_StoreName), F_AttendanceGroupId = VALUES(F_AttendanceGroupId), F_AttendanceGroupName = VALUES(F_AttendanceGroupName), F_UpdateUserId = 'system', F_UpdateTime = NOW(), F_IsEffective = 1; */