diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index b8b93fb..7b76ba5 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -2,6 +2,16 @@ \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 751dbba..1c9aa40 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -10,8 +10,12 @@ - + + + + + - { + "keyToString": { + "ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true", + "Cargo.Run bookkeeper.executor": "Run", + "DefaultHtmlFileTemplate": "HTML File", + "RunOnceActivity.ShowReadmeOnStart": "true", + "RunOnceActivity.git.unshallow": "true", + "RunOnceActivity.rust.reset.selective.auto.import": "true", + "SHARE_PROJECT_CONFIGURATION_FILES": "true", + "git-widget-placeholder": "main", + "last_opened_file_path": "D:/code/finance-consumer/bookkeeper/templates", + "node.js.detected.package.eslint": "true", + "node.js.detected.package.tslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "node.js.selected.package.tslint": "(autodetect)", + "nodejs_package_manager_path": "npm", + "org.rust.cargo.project.model.PROJECT_DISCOVERY": "true", + "org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "", + "org.rust.first.attach.projects": "true", + "run.code.analysis.last.selected.profile": "pProject Default", + "settings.editor.selected.configurable": "preferences.pluginManager", + "vue.rearranger.settings.migration": "true" } -}]]> +} @@ -146,7 +150,8 @@ - + + - @@ -220,7 +233,8 @@ - diff --git a/bookkeeper/src/main.rs b/bookkeeper/src/main.rs index 86567b9..0ff62e1 100644 --- a/bookkeeper/src/main.rs +++ b/bookkeeper/src/main.rs @@ -19,6 +19,7 @@ use sea_orm::{ActiveModelTrait, ColumnTrait, ConnectOptions, DatabaseConnection, use sea_orm_rocket::{rocket::figment::Figment, Config, Connection, Database}; use std::str::FromStr; use std::time::Duration; +use rocket::http::Status; use serde::{Deserialize, Serialize}; #[derive(sea_orm_rocket::Database, Debug)] @@ -98,6 +99,49 @@ struct SplitPiece{ volume: i32, } +#[get("/tx/")] +async fn get_tx(conn: Connection<'_, Db>, id: i32) -> Result { + let row = TE::find_by_id(id) + .one(conn.into_inner()) + .await + .unwrap(); + match row { + None => { Err(Status::NotFound) }, + Some(row) => { + Ok(Template::render("tx", context! { + r: row, + target: "/tx/".to_owned() + id.to_string().as_str(), + })) + } + } +} + +#[post("/tx/", data = "")] +async fn post_tx(data: Form>, conn: Connection<'_, Db>, id: i32) -> Result { + dbg!(&data); + let mut record = translate(data); + record.id = Set(id); + dbg!(&record); + match record.update(conn.into_inner()).await { + Err(_) => { Err(Status::NotFound) }, + Ok(_) => { Ok(Redirect::to("/")) }, + } +} + +#[delete("/tx/")] +async fn delete_tx(conn: Connection<'_, Db>, id: i32) -> Result { + match TE::delete_by_id(id).exec(conn.into_inner()).await { + Err(_) => { Err(Status::InternalServerError) }, + Ok(res) => { + if res.rows_affected == 1 { + Ok(Redirect::to("/")) + } else { + Err(Status::NotFound) + } + } + } +} + #[get("/add")] async fn get_add() -> Template { Template::render("tx", context! { @@ -108,7 +152,6 @@ async fn get_add() -> Template { #[post("/add", data = "")] async fn add(trans: Form>, conn: Connection<'_, Db>) -> Flash { - dbg!(&trans); let record = translate(trans); record.insert(conn.into_inner()).await.unwrap(); @@ -174,5 +217,5 @@ async fn rocket() -> _ { .attach(Db::init()) .attach(AdHoc::try_on_ignite("Migrations", run_migrations)) .attach(Template::fairing()) - .mount("/", routes![index, add, get_add]) + .mount("/", routes![index, add, get_add, get_tx, post_tx, delete_tx]) } diff --git a/bookkeeper/templates/index.html.j2 b/bookkeeper/templates/index.html.j2 index 2f5690b..427be94 100644 --- a/bookkeeper/templates/index.html.j2 +++ b/bookkeeper/templates/index.html.j2 @@ -39,7 +39,7 @@ {{ (r.gain or 0)|float|round(4) }}% {{ (r.net_gain or 0)|float|round(4) }}% - 修改 +   {% else %} {{ p.date or "" }} @@ -63,7 +63,8 @@ - - - 修改 +   + {% endif %} {% endfor %} @@ -109,6 +110,33 @@ openModal($target); }); + (document.querySelectorAll('.modify-row') || []).forEach(($cl) => { + $cl.addEventListener('click', async () => { + const rowId = $cl.attributes.getNamedItem("row-id").value; + const $target = document.getElementById("modal"); + const response = await fetch(`/tx/${rowId}`); + if (!response.ok) { + return; + } + document.getElementById('modal-content').innerHTML = await response.text(); + openModal($target); + }); + }); + + (document.querySelectorAll('.delete-row') || []).forEach(($cl) => { + $cl.addEventListener('click', async () => { + const rowId = $cl.attributes.getNamedItem("row-id").value; + if (confirm(`删除${$cl.parentElement.parentElement.innerText}吗?`) !== true) { + return; + } + const response = await fetch(`/tx/${rowId}`, {method: 'DELETE'}); + alert(`${response.ok ? "OK" : "Fail"}: ${response.status}`); + if (response.ok) { + $cl.parentElement.parentElement.remove(); + } + }); + }); + // Add a click event on various child elements to close the parent modal (document.querySelectorAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button') || []).forEach(($close) => { const $target = $close.closest('.modal'); @@ -148,6 +176,8 @@ this_row.parentElement.removeChild(this_row); } } + + {% endblock container %} diff --git a/bookkeeper/templates/tx.html.j2 b/bookkeeper/templates/tx.html.j2 index 12dd47e..32fc726 100644 --- a/bookkeeper/templates/tx.html.j2 +++ b/bookkeeper/templates/tx.html.j2 @@ -34,30 +34,32 @@ - + - + 操作 + {% if r.split_pieces %} + {% for split in r.split_pieces %} - {% if r.split_pieces %} - {% for split in r.split_pieces %} - - - - + + + + 删除 - {% endfor %} - {% else %} - - - - - 删除 - {% endif %} + {% endfor %} + {% else %} + + + + + + 删除 + + {% endif %} 添加 @@ -67,9 +69,6 @@
-
- -