mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-21 18:19:03 +08:00
feat: 间隔时间加分可以按照多少天、月、分钟后加分
fix: 修复若干问题 下雨了好害怕我靠
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use chrono::{DateTime, Months, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use tauri::{AppHandle, Emitter};
|
||||
@@ -15,6 +15,20 @@ pub struct AutoScoreAction {
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
enum IntervalUnit {
|
||||
Minute,
|
||||
Day,
|
||||
Month,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct IntervalTriggerValue {
|
||||
amount: i64,
|
||||
unit: IntervalUnit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AutoScoreRule {
|
||||
pub id: i32,
|
||||
@@ -171,23 +185,17 @@ impl AutoScoreService {
|
||||
|
||||
for trigger in &rule.triggers {
|
||||
if trigger.event == "interval_time_passed" {
|
||||
let minutes = trigger
|
||||
.value
|
||||
let interval = parse_interval_trigger_value(trigger.value.as_ref());
|
||||
let base_time = rule
|
||||
.last_executed
|
||||
.as_ref()
|
||||
.and_then(|v| v.parse::<i64>().ok())
|
||||
.unwrap_or(30);
|
||||
let interval_ms = minutes * 60 * 1000;
|
||||
.and_then(|value| DateTime::parse_from_rfc3339(value).ok())
|
||||
.map(|value| value.with_timezone(&Utc))
|
||||
.unwrap_or(now);
|
||||
|
||||
if let Some(last_executed_str) = &rule.last_executed {
|
||||
if let Ok(last_executed) = DateTime::parse_from_rfc3339(last_executed_str) {
|
||||
let last_executed_utc: DateTime<Utc> = last_executed.with_timezone(&Utc);
|
||||
let next_execute_time =
|
||||
last_executed_utc + chrono::Duration::milliseconds(interval_ms);
|
||||
let delay_ms = (next_execute_time - now).num_milliseconds();
|
||||
return Some(delay_ms.max(0));
|
||||
}
|
||||
}
|
||||
return Some(interval_ms);
|
||||
let next_execute_time = add_interval_to_time(base_time, &interval)?;
|
||||
let delay_ms = (next_execute_time - now).num_milliseconds();
|
||||
return Some(delay_ms.max(0));
|
||||
}
|
||||
}
|
||||
None
|
||||
@@ -197,3 +205,43 @@ impl AutoScoreService {
|
||||
let _ = app_handle.emit("auto-score:rulesChanged", &self.rules);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_interval_trigger_value(value: Option<&String>) -> IntervalTriggerValue {
|
||||
if let Some(raw_value) = value {
|
||||
if let Ok(minutes) = raw_value.parse::<i64>() {
|
||||
if minutes > 0 {
|
||||
return IntervalTriggerValue {
|
||||
amount: minutes,
|
||||
unit: IntervalUnit::Minute,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(parsed_value) = serde_json::from_str::<IntervalTriggerValue>(raw_value) {
|
||||
if parsed_value.amount > 0 {
|
||||
return parsed_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IntervalTriggerValue {
|
||||
amount: 30,
|
||||
unit: IntervalUnit::Minute,
|
||||
}
|
||||
}
|
||||
|
||||
fn add_interval_to_time(
|
||||
base_time: DateTime<Utc>,
|
||||
interval: &IntervalTriggerValue,
|
||||
) -> Option<DateTime<Utc>> {
|
||||
match interval.unit {
|
||||
IntervalUnit::Minute => {
|
||||
base_time.checked_add_signed(chrono::Duration::minutes(interval.amount))
|
||||
}
|
||||
IntervalUnit::Day => base_time.checked_add_signed(chrono::Duration::days(interval.amount)),
|
||||
IntervalUnit::Month => {
|
||||
let months = u32::try_from(interval.amount).ok()?;
|
||||
base_time.checked_add_months(Months::new(months))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user