use serde::{Deserialize, Serialize};
use crate::event::{context::EventHeader, dispatcher::EventHandler};
#[derive(Debug, Serialize, Deserialize)]
pub struct P2AttendanceUserTaskUpdatedV1 {
pub schema: String,
pub header: EventHeader,
pub event: P2AttendanceUserTaskUpdatedV1Data,
}
pub(crate) struct P2AttendanceUserTaskUpdatedV1ProcessorImpl<F>
where
F: Fn(P2AttendanceUserTaskUpdatedV1) + 'static,
{
f: F,
}
impl<F> EventHandler for P2AttendanceUserTaskUpdatedV1ProcessorImpl<F>
where
F: Fn(P2AttendanceUserTaskUpdatedV1) + 'static + Sync + Send,
{
fn handle(&self, payload: &[u8]) -> anyhow::Result<()> {
let event: P2AttendanceUserTaskUpdatedV1 = serde_json::from_slice(payload)?;
(self.f)(event);
Ok(())
}
}
impl<F> P2AttendanceUserTaskUpdatedV1ProcessorImpl<F>
where
F: Fn(P2AttendanceUserTaskUpdatedV1) + 'static,
{
pub(crate) fn new(f: F) -> Self {
P2AttendanceUserTaskUpdatedV1ProcessorImpl { f }
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct P2AttendanceUserTaskUpdatedV1Data {
pub user_id: AttendanceUserId,
pub task: AttendanceTask,
pub tenant_key: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct AttendanceUserId {
pub union_id: String,
pub user_id: String,
pub open_id: String,
pub employee_id: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct AttendanceTask {
pub task_id: String,
pub user_id: String,
pub employee_id: Option<String>,
pub group_id: String,
pub shift_id: String,
pub record_date: String,
pub shift_name: String,
pub check_time: String,
pub result: i32,
pub type_: i32,
pub location: Option<AttendanceLocation>,
pub is_field: bool,
pub is_remedy: bool,
pub comment: Option<String>,
pub create_time: String,
pub update_time: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct AttendanceLocation {
pub latitude: f64,
pub longitude: f64,
pub address: Option<String>,
}
#[cfg(test)]
#[allow(unused_variables, unused_unsafe)]
mod test {
use serde_json::json;
use crate::event::context::EventContext;
#[test]
fn test_decode_attendance_event() {
let event_data = json!({
"schema": "2.0",
"header": {
"event_id": "7db4fd0bb90cfa6127e3aaa446d39b38",
"token": "",
"create_time": "1719211482721",
"event_type": "attendance.user_task.updated_v1",
"tenant_key": "tenant_key",
"app_id": "app_id"
},
"event": {
"user_id": {
"open_id": "ou_b434284f852b1531071855b16d19f40b",
"union_id": "on_526dbf7b9ef1fda341aecb79a2481662",
"user_id": "aa5cf9d7",
"employee_id": "emp_001"
},
"task": {
"task_id": "task_123456",
"user_id": "aa5cf9d7",
"employee_id": "emp_001",
"group_id": "group_001",
"shift_id": "shift_001",
"record_date": "2024-06-20",
"shift_name": "标准班次",
"check_time": "2024-06-20 09:00:00",
"result": 1,
"type_": 1,
"location": {
"latitude": 39.908822,
"longitude": 116.397128,
"address": "北京市朝阳区"
},
"is_field": false,
"is_remedy": false,
"comment": "正常打卡",
"create_time": "1719211482485",
"update_time": "1719211482485"
},
"tenant_key": "133195a24e8f575d"
}
});
let event_context: EventContext = serde_json::from_value(event_data).unwrap();
assert_eq!(event_context.schema, Some("2.0".to_string()));
}
}