From b44669e3ac12ea9ab44ca4355b327ed3921c4e76 Mon Sep 17 00:00:00 2001 From: ultrageese Date: Fri, 22 May 2026 10:44:20 +1000 Subject: [PATCH] =?UTF-8?q?=D0=9C=D0=BE=D0=B6=D0=BD=D0=BE=20=D1=81=D0=BC?= =?UTF-8?q?=D0=BE=D1=82=D1=80=D0=B5=D1=82=D1=8C=20=D0=B1=D0=B5=D1=81=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D0=B5=D1=87=D0=BD=D0=BE=20=D0=BD=D0=B0=20=D1=82?= =?UTF-8?q?=D1=80=D0=B8=20=D0=B2=D0=B5=D1=89=D0=B8=20=D0=9F=D0=BE=20=D1=86?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=20=D0=B4=D0=B2=D1=83=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/src/app.rs | 173 ++++++++++++++++++++++++++----------------- code/src/database.rs | 28 +++++-- code/src/models.rs | 8 ++ 3 files changed, 133 insertions(+), 76 deletions(-) diff --git a/code/src/app.rs b/code/src/app.rs index ddb1721..855d437 100644 --- a/code/src/app.rs +++ b/code/src/app.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use egui::mutex::RwLock; use egui_dock::{DockArea, Style, TabViewer}; use sqlx::{Connection, MySqlConnection, MySqlPool}; -use crate::{database::DBOperator, models::{self, Position, Salary, Worker}}; +use crate::{database::DBOperator, models::{self, Equipment, Position, Salary, Worker}}; static TABS_CAN_BE_WINDOWS: bool = false; @@ -85,7 +85,7 @@ impl eframe::App for App{ struct MainTabViewer { positions: Arc>>>, workers: Arc>>>, - equipment: std::vec::Vec, + equipment: Arc>>>, db_oper: DBOperator, worker_tabs: WorkerTabViewer, worker_tree: egui_dock::DockState, @@ -94,21 +94,24 @@ struct MainTabViewer { impl Default for MainTabViewer{ fn default() -> Self { - let db_oper = DBOperator::new(); + let rt = tokio::runtime::Runtime::new().unwrap(); + let db_oper = rt.block_on(async{ + DBOperator::new().await + }); Self{ positions: Arc::new(RwLock::new(Option::Some(rt.block_on(async{db_oper.get_position().await.unwrap()})))), workers: Arc::new(RwLock::new(Option::Some(rt.block_on(async{db_oper.get_workers().await.unwrap()})))), - equipment: vec![models::Equipment::default()], + equipment: Arc::new(RwLock::new(Option::Some(rt.block_on(async{db_oper.get_equipment().await.unwrap()})))), db_oper, worker_tabs: WorkerTabViewer::default(), worker_tree: egui_dock::DockState::new(vec![ Tab{ - title:"ГойдаЗов".to_owned(), + title:"Работники".to_owned(), tab_type:TabTypes::WorkerList, }, Tab{ - title:"Еееееее".to_owned(), + title:"Должности".to_owned(), tab_type:TabTypes::WorkerPosition, } ]), @@ -139,13 +142,21 @@ impl MainTabViewer{ // table = table.sense(egui::Sense::click()); //Это таблицы, с ними надо разобраться! - for eq in self.equipment.clone() { - ui.push_id(&eq.name, |ui|{ + for eq in self.equipment.read().clone().unwrap().iter() { + let id = ui.make_persistent_id(format!("{}:{}", eq.id, eq.name)); + ui.push_id(&id, |ui|{ egui::CollapsingHeader::new(&eq.name) .default_open(false) .show(ui, |ui|{ - ui.label(eq.inv_number); - ui.label(eq.worker.full_name); + ui.horizontal(|ui|{ + ui.monospace("Инвентарный номер: "); + ui.label(&eq.inv_number); + }); + ui.horizontal(|ui|{ + ui.monospace("Ответственный: "); + ui.label(&eq.worker.full_name); + }); + }); }); @@ -153,6 +164,68 @@ impl MainTabViewer{ } + + + + + fn show_worker(&mut self, ui: &mut egui::Ui){ + let id = ui.make_persistent_id("WorkerMenu"); + DockArea::new(&mut self.worker_tree) + .style(Style::from_egui(ui.style().as_ref())) + .id(id) + .show_inside(ui, &mut self.worker_tabs); + } + fn show_material(&mut self, ui: &mut egui::Ui){ + ui.label("Сырьё короче да"); + } + fn show_salary(&mut self, ui: &mut egui::Ui){ + + } +} + +impl egui_dock::TabViewer for MainTabViewer{ + type Tab = Tab; + + fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText{ + (&*tab.title).into() + } + fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab){ + match &tab.tab_type{ + TabTypes::Equipment => { + &self.show_equipment(ui); + }, + TabTypes::Worker => { + &self.show_worker(ui); + }, + TabTypes::Salary => { + &self.show_salary(ui); + }, + TabTypes::Material => { + &self.show_material(ui); + }, + _ =>{ + ui.label("This is not"); + } + } + + } + fn allowed_in_windows(&self, _tab: &mut Self::Tab) -> bool { + TABS_CAN_BE_WINDOWS + } + fn is_closeable(&self, _tab: &Self::Tab) -> bool { + false + } + fn id(&mut self, tab: &mut Self::Tab) -> egui::Id { + egui::Id::new(&tab.title) + } +} +struct WorkerTabViewer{ + workers: Arc>>>, + positions: Arc>>>, + +} + +impl WorkerTabViewer{ fn show_worker(&mut self, ui: &mut egui::Ui){ ui.horizontal(|ui|{ if ui.button("Добавить").clicked() { @@ -186,9 +259,7 @@ impl MainTabViewer{ }) }); } - } - - + } fn show_position(&mut self, ui: &mut egui::Ui){ for eq in self.positions.read().clone().unwrap().iter(){ @@ -202,61 +273,6 @@ impl MainTabViewer{ }); } } - fn show_salary(&mut self, ui: &mut egui::Ui){ - let id = ui.make_persistent_id("BotMenu"); - DockArea::new(&mut self.worker_tree) - .style(Style::from_egui(ui.style().as_ref())) - .id(id) - .show_inside(ui, &mut self.worker_tabs); - } - fn show_material(&mut self, ui: &mut egui::Ui){ - ui.label("Сырьё короче да"); - } -} - -impl egui_dock::TabViewer for MainTabViewer{ - type Tab = Tab; - - fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText{ - (&*tab.title).into() - } - fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab){ - match &tab.tab_type{ - TabTypes::Equipment => { - &self.show_equipment(ui); - }, - TabTypes::Worker => { - &self.show_worker(ui); - }, - TabTypes::Salary => { - &self.show_salary(ui); - }, - TabTypes::Material => { - &self.show_material(ui); - }, - TabTypes::Position =>{ - &self.show_position(ui); - } - _ =>{ - ui.label("This is not"); - } - } - - } - fn allowed_in_windows(&self, _tab: &mut Self::Tab) -> bool { - TABS_CAN_BE_WINDOWS - } - fn is_closeable(&self, _tab: &Self::Tab) -> bool { - false - } - fn id(&mut self, tab: &mut Self::Tab) -> egui::Id { - egui::Id::new(&tab.title) - } -} - -#[derive(Default)] -struct WorkerTabViewer{ - } impl egui_dock::TabViewer for WorkerTabViewer{ @@ -265,9 +281,28 @@ impl egui_dock::TabViewer for WorkerTabViewer{ (&*tab.title).into() } fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) { - + match &tab.tab_type{ + TabTypes::WorkerList => self.show_worker(ui), + TabTypes::WorkerPosition => self.show_position(ui), + _ => {ui.label("Nope");}, + } } fn id(&mut self, tab: &mut Self::Tab) -> egui::Id { egui::Id::new(&tab.title) } + fn allowed_in_windows(&self, _tab: &mut Self::Tab) -> bool { + TABS_CAN_BE_WINDOWS + } + fn is_closeable(&self, _tab: &Self::Tab) -> bool { + false + } +} +impl Default for WorkerTabViewer{ + fn default() -> Self { + let rt = tokio::runtime::Runtime::new().unwrap(); + let db_oper = rt.block_on(async{DBOperator::new().await}); + Self { workers: Arc::new(RwLock::new(Option::Some(rt.block_on(async{db_oper.get_workers().await.unwrap()})))) , + positions: Arc::new(RwLock::new(Option::Some(rt.block_on(async{db_oper.get_position().await.unwrap()})))), + } + } } \ No newline at end of file diff --git a/code/src/database.rs b/code/src/database.rs index b58a56e..d481ca7 100644 --- a/code/src/database.rs +++ b/code/src/database.rs @@ -9,23 +9,21 @@ use std::env; use crate::models::*; pub struct DBOperator{ - connection_string: String, + pool: MySqlPool, } impl DBOperator{ - pub fn new() -> Self{ + pub async fn new() -> Self{ dotenv_override().ok(); let db_url = env::var("DATABASE_URL").expect("DATABASE_URL установи!"); - Self{connection_string:db_url} + Self{pool: MySqlPool::connect(&db_url).await.unwrap()} } pub async fn get_position(&self) -> Result, sqlx::Error>{ - let pool = MySqlPool::connect(&self.connection_string).await?; - let rets: Vec = sqlx::query_as:: <_, Position>("SELECT * FROM `position`").fetch_all(&pool).await?; + let rets: Vec = sqlx::query_as:: <_, Position>("SELECT * FROM `position`").fetch_all(&self.pool).await?; Ok(rets) } pub async fn get_workers(&self) -> Result, sqlx::Error>{ - let pool = MySqlPool::connect(&self.connection_string).await?; - let pre_rets: Vec = sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker`").fetch_all(&pool).await?; + let pre_rets: Vec = sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker`").fetch_all(&self.pool).await?; let mut rets:Vec = Vec::new(); let pos = self.get_position().await.unwrap(); for worker in pre_rets{ @@ -40,6 +38,22 @@ impl DBOperator{ } Ok(rets) } + pub async fn get_equipment(&self) -> Result,sqlx::Error>{ + let pre_rets = sqlx::query_as::<_, EquipmentRow>("SELECT * FROM `equipment`").fetch_all(&self.pool).await?; + let mut rets: Vec = Vec::new(); + let workers = self.get_workers().await?; + for eq in pre_rets{ + let mut pworker = Worker::default(); + for worker in workers.clone(){ + if worker.id == eq.worker_id{ + pworker = worker.clone(); + break; + } + } + rets.push(Equipment { id: eq.id, name: eq.name, inv_number: eq.inv_number, maintenance_date: eq.maintenance_date, worker: pworker }); + } + Ok(rets) + } } diff --git a/code/src/models.rs b/code/src/models.rs index f12806a..5e97663 100644 --- a/code/src/models.rs +++ b/code/src/models.rs @@ -38,6 +38,14 @@ pub struct Equipment{ pub maintenance_date: chrono::DateTime, pub worker: Worker, } +#[derive(sqlx::FromRow)] +pub struct EquipmentRow{ + pub id: i32, + pub name: String, + pub inv_number: String, + pub maintenance_date: chrono::DateTime, + pub worker_id: i32, +} pub struct Material{ id: i32, name: String,