175 lines
4.9 KiB
Rust
175 lines
4.9 KiB
Rust
use chrono::{Local, NaiveDate};
|
|
use rusqlite::{Connection, Result};
|
|
use serde::Serialize;
|
|
use std::fs;
|
|
use tauri::Manager;
|
|
|
|
fn init_database(app: &tauri::App) -> Result<(), Box<dyn std::error::Error>> {
|
|
// 获取应用数据目录
|
|
let app_dir = app.path().app_data_dir()?;
|
|
|
|
// 确保目录存在
|
|
fs::create_dir_all(&app_dir)?;
|
|
|
|
// 构建数据库文件路径
|
|
let db_path = app_dir.join("anniversaries.db");
|
|
|
|
// 打开数据库连接
|
|
let conn = Connection::open(db_path)?;
|
|
|
|
// 创建表
|
|
conn.execute(
|
|
"CREATE TABLE IF NOT EXISTS anniversaries (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
title TEXT NOT NULL,
|
|
start_date TEXT NOT NULL,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
)",
|
|
[],
|
|
)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
struct Anniversary {
|
|
id: i32,
|
|
title: String,
|
|
start_date: String,
|
|
days: i64,
|
|
}
|
|
#[tauri::command]
|
|
async fn get_anniversaries(app_handle: tauri::AppHandle) -> Result<Vec<Anniversary>, String> {
|
|
// 返回主页数据
|
|
let app_dir = app_handle
|
|
.path()
|
|
.app_data_dir()
|
|
.map_err(|e| e.to_string())?;
|
|
let db_path = app_dir.join("anniversaries.db");
|
|
let conn = Connection::open(db_path).map_err(|e| e.to_string())?;
|
|
|
|
let mut stmt = conn
|
|
.prepare("SELECT id, title, start_date FROM anniversaries ORDER BY created_at DESC")
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
let today = Local::now().date_naive();
|
|
|
|
let anniversaries = stmt
|
|
.query_map([], |row| {
|
|
let id: i32 = row.get(0)?;
|
|
let title: String = row.get(1)?;
|
|
let start_date: String = row.get(2)?;
|
|
|
|
// 计算天数
|
|
let start = NaiveDate::parse_from_str(&start_date, "%Y-%m-%d")
|
|
.map_err(|e| rusqlite::Error::InvalidParameterName(e.to_string()))?;
|
|
let days = (today - start).num_days();
|
|
|
|
Ok(Anniversary {
|
|
id,
|
|
title,
|
|
start_date,
|
|
days,
|
|
})
|
|
})
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
let result: Result<Vec<_>, _> = anniversaries.collect();
|
|
result.map_err(|e| e.to_string())
|
|
}
|
|
|
|
#[tauri::command]
|
|
async fn get_anniversary_by_id(
|
|
app_handle: tauri::AppHandle,
|
|
id: i32,
|
|
) -> Result<Anniversary, String> {
|
|
// 返回详情页数据
|
|
let app_dir = app_handle
|
|
.path()
|
|
.app_data_dir()
|
|
.map_err(|e| e.to_string())?;
|
|
let db_path = app_dir.join("anniversaries.db");
|
|
let conn = Connection::open(db_path).map_err(|e| e.to_string())?;
|
|
let mut stmt = conn
|
|
.prepare("SELECT title, start_date FROM anniversaries WHERE id = ?")
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
let today = Local::now().date_naive();
|
|
|
|
let result = stmt
|
|
.query_row([id], |row| {
|
|
let title: String = row.get(0)?;
|
|
let start_date: String = row.get(1)?;
|
|
|
|
// 计算天数
|
|
let start = NaiveDate::parse_from_str(&start_date, "%Y-%m-%d")
|
|
.map_err(|e| rusqlite::Error::InvalidParameterName(e.to_string()))?;
|
|
let days = (today - start).num_days();
|
|
|
|
Ok(Anniversary {
|
|
id,
|
|
title,
|
|
start_date,
|
|
days,
|
|
})
|
|
})
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
Ok(result)
|
|
}
|
|
|
|
#[tauri::command]
|
|
async fn delete_anniversary(app_handle: tauri::AppHandle, id: i64) -> Result<(), String> {
|
|
// 详情页删除
|
|
let app_dir = app_handle
|
|
.path()
|
|
.app_data_dir()
|
|
.map_err(|e| e.to_string())?;
|
|
let db_path = app_dir.join("anniversaries.db");
|
|
let conn = Connection::open(db_path).map_err(|e| e.to_string())?;
|
|
conn.execute("DELETE FROM anniversaries WHERE id = ?", [id])
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tauri::command]
|
|
async fn add_anniversary(
|
|
app_handle: tauri::AppHandle,
|
|
title: String,
|
|
start_date: String,
|
|
) -> Result<(), String> {
|
|
// 主页添加
|
|
let app_dir = app_handle
|
|
.path()
|
|
.app_data_dir()
|
|
.map_err(|e| e.to_string())?;
|
|
let db_path = app_dir.join("anniversaries.db");
|
|
let conn = Connection::open(db_path).map_err(|e| e.to_string())?;
|
|
conn.execute(
|
|
"INSERT INTO anniversaries (title, start_date) VALUES (?1, ?2)",
|
|
[&title, &start_date],
|
|
)
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
pub fn run() {
|
|
tauri::Builder::default()
|
|
.plugin(tauri_plugin_opener::init())
|
|
.setup(|app| {
|
|
init_database(app).expect("failed to initialize database");
|
|
Ok(())
|
|
})
|
|
.invoke_handler(tauri::generate_handler![
|
|
get_anniversaries,
|
|
get_anniversary_by_id,
|
|
add_anniversary,
|
|
delete_anniversary,
|
|
])
|
|
.run(tauri::generate_context!())
|
|
.expect("error while running tauri application");
|
|
}
|