dev-manager-tauri/src-tauri/src/commands/docker_apps.rs
2026-09-21 12:52:37 +09:00

124 lines
4.0 KiB
Rust

use rusqlite::{params, Connection};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct DockerApp {
pub id: String,
pub product_id: String,
pub name: String,
pub access_url: Option<String>,
pub username: Option<String>,
pub password: Option<String>,
pub notes: Option<String>,
pub sort_order: i32,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct SaveDockerAppInput {
pub product_id: String,
pub name: String,
pub access_url: Option<String>,
pub username: Option<String>,
pub password: Option<String>,
pub notes: Option<String>,
pub sort_order: Option<i32>,
}
const COLS: &str =
"id, product_id, name, access_url, username, password, notes, sort_order, created_at, updated_at";
fn row_to_app(row: &rusqlite::Row<'_>) -> rusqlite::Result<DockerApp> {
Ok(DockerApp {
id: row.get(0)?,
product_id: row.get(1)?,
name: row.get(2)?,
access_url: row.get(3)?,
username: row.get(4)?,
password: row.get(5)?,
notes: row.get(6)?,
sort_order: row.get(7)?,
created_at: row.get(8)?,
updated_at: row.get(9)?,
})
}
fn get_by_id(conn: &Connection, id: &str) -> Option<DockerApp> {
let sql = format!("SELECT {COLS} FROM docker_apps WHERE id = ?1");
conn.query_row(&sql, params![id], row_to_app).ok()
}
// ── Tauri commands ───────────────────────────────────────────────────────────
#[tauri::command]
pub fn get_docker_apps(product_id: String) -> Result<Vec<DockerApp>, String> {
let conn = crate::db::pool().get().map_err(|e| e.to_string())?;
let sql =
format!("SELECT {COLS} FROM docker_apps WHERE product_id = ?1 ORDER BY sort_order, name");
let mut stmt = conn.prepare(&sql).map_err(|e| e.to_string())?;
let rows = stmt
.query_map(params![product_id], row_to_app)
.map_err(|e| e.to_string())?
.filter_map(|r| r.ok())
.collect();
Ok(rows)
}
#[tauri::command]
pub fn add_docker_app(input: SaveDockerAppInput) -> Result<DockerApp, String> {
let conn = crate::db::pool().get().map_err(|e| e.to_string())?;
let id = format!("dapp-{}", uuid::Uuid::new_v4());
conn.execute(
"INSERT INTO docker_apps
(id, product_id, name, access_url, username, password, notes, sort_order)
VALUES (?1,?2,?3,?4,?5,?6,?7,?8)",
params![
id,
input.product_id,
input.name,
input.access_url,
input.username,
input.password,
input.notes,
input.sort_order.unwrap_or(0)
],
)
.map_err(|e| e.to_string())?;
get_by_id(&conn, &id).ok_or_else(|| "创建后查询失败".into())
}
#[tauri::command]
pub fn edit_docker_app(id: String, input: SaveDockerAppInput) -> Result<DockerApp, String> {
let conn = crate::db::pool().get().map_err(|e| e.to_string())?;
let rows = conn
.execute(
"UPDATE docker_apps
SET name=?1, access_url=?2, username=?3, password=?4,
notes=?5, sort_order=?6, updated_at=datetime('now')
WHERE id=?7",
params![
input.name,
input.access_url,
input.username,
input.password,
input.notes,
input.sort_order.unwrap_or(0),
id
],
)
.map_err(|e| e.to_string())?;
if rows == 0 {
return Err(format!("应用 {} 不存在", id));
}
get_by_id(&conn, &id).ok_or_else(|| "更新后查询失败".into())
}
#[tauri::command]
pub fn delete_docker_app(id: String) -> Result<(), String> {
let conn = crate::db::pool().get().map_err(|e| e.to_string())?;
conn.execute("DELETE FROM docker_apps WHERE id=?1", params![id])
.map_err(|e| e.to_string())?;
Ok(())
}