Коммит номер какой-то. Сделано что-то

master
Алексей Алексей 2026-06-07 15:07:07 +10:00
parent f6bb3306ee
commit 0b457af6f7
6 changed files with 173 additions and 84 deletions

View File

@ -1,4 +1,4 @@
use std::{collections::HashMap, ops::Deref, str::FromStr, sync::Arc};
use std::{collections::HashMap, default::Default, ops::Deref, str::FromStr, sync::Arc};
use crate::{
database::DBOperator,
@ -8,7 +8,7 @@ use crate::{
ModalWinState, Position, Worker,
},
tab::*,
worker_tab::*,
worker_tab::{self, *},
};
use egui::{TextBuffer, Vec2, mutex::RwLock};
use egui_dock::{DockArea, Style, TabViewer};
@ -22,11 +22,12 @@ pub struct App<'a> {
pub main_viewer: MainTabViewer,
pub db_oper: DBOperator,
pub rt: tokio::runtime::Runtime,
pub is_admin: bool,
}
impl Default for App<'_> {
fn default() -> Self {
let tree = egui_dock::DockState::new(vec![
let mut tree = egui_dock::DockState::new(vec![
Tab {
tab_type: TabTypes::Equipment,
title: "Оборудование".to_owned(),
@ -69,6 +70,7 @@ impl Default for App<'_> {
},
db_oper: rt.block_on(DBOperator::new()),
rt,
is_admin: false,
}
}
}
@ -104,28 +106,31 @@ impl eframe::App for App<'_> {
|| ui.input(|i| i.key_pressed(egui::Key::Enter))
{
let uname = self.login_modal_state.data.get("login").unwrap().clone();
if self.rt.block_on(async {
self.db_oper.check_username(uname.clone()).await.unwrap()
}) {
self.login_modal_state.fail = false;
let mut hashed_pass = Sha256::new();
hashed_pass
.update(self.login_modal_state.data.get("password").unwrap());
hashed_pass.update(self.login_modal_state.data.get("password").unwrap());
let pass_hash = hex::encode(hashed_pass.finalize());
if self.rt.block_on(async {
self.db_oper.check_password(uname, pass_hash).await.unwrap()
self.db_oper
.check_password(uname.clone(), pass_hash)
.await
.unwrap()
}) {
self.login_modal_state.fail = false;
self.login_modal_state.status =
crate::models::LoginStatus::Finished;
self.login_modal_state.status = crate::models::LoginStatus::Finished;
self.login_modal_state.is_open = false;
if self.rt.block_on(async {
self.db_oper.check_admin(uname.clone()).await.unwrap()
}) {
self.main_viewer.is_admin = true
} else {
self.login_modal_state.fail = true;
self.login_modal_state.fail_message = "Неверный пароль".to_string();
self.main_viewer.is_admin = false;
}
} else {
self.login_modal_state.fail = true;
self.login_modal_state.fail_message = "Неверный логин".to_string();
self.login_modal_state.fail_message =
"Неверные логин или пароль".to_string();
}
}
});
@ -158,6 +163,7 @@ struct MainTabViewer {
equipment_modal_state: ModalWinState,
is_dark_theme: bool,
interface_scale_ratio: f32,
is_admin: bool,
}
impl Default for MainTabViewer {
fn default() -> Self {
@ -211,11 +217,21 @@ impl Default for MainTabViewer {
]),
status: ModalStatus::Add,
},
is_admin: false,
}
}
}
impl MainTabViewer {
fn new(is_admin: bool) -> Self {
Self {
is_admin,
worker_tabs: WorkerTabViewer::new(is_admin),
material_tabs: MaterialTabViewer::new(is_admin),
..Default::default()
}
}
fn show_equipment(&mut self, ui: &mut egui::Ui) {
if self.is_admin {
ui.horizontal(|ui| {
if ui.button("Добавить").clicked() {
self.equipment_modal_state.is_open = true;
@ -234,6 +250,7 @@ impl MainTabViewer {
.insert("worker_id".into(), "0".into());
}
});
}
let mut table = TableBuilder::new(ui)
.striped(true)
.resizable(false)
@ -275,6 +292,7 @@ impl MainTabViewer {
ui.label(eq.maintenance_date.date_naive().to_string());
});
row.col(|ui| {
if self.is_admin {
if ui.button("Удалить").clicked() {
self.equipment_modal_state.is_open = true;
self.equipment_modal_state.status = ModalStatus::Remove;
@ -291,6 +309,7 @@ impl MainTabViewer {
.data
.insert("worker_id".into(), eq.worker.id.to_string());
}
}
});
if row.response().double_clicked() {
self.equipment_modal_state.is_open = true;

View File

@ -1,3 +1,4 @@
use sqlx::Row;
use sqlx::mysql::MySqlPool;
use sqlx::mysql::MySqlPoolOptions;
@ -283,22 +284,6 @@ impl DBOperator {
Err(_) => Ok(false),
}
}
pub async fn check_username(&self, username: String) -> Result<bool, sqlx::Error> {
let ans = sqlx::query("SELECT * FROM Brewery.profile WHERE login=?")
.bind(username)
.fetch_all(&self.pool)
.await;
match ans {
Ok(n) => {
if n.len() > 0 {
return Ok(true);
} else {
return Ok(false);
}
}
Err(_) => Ok(false),
}
}
pub async fn check_password(
&self,
username: String,
@ -320,6 +305,30 @@ impl DBOperator {
Err(_) => Ok(false),
}
}
pub async fn check_admin(&self, username: String) -> Result<bool, sqlx::Error> {
let ans: bool = sqlx::query_scalar(
r#"SELECT
position.is_admin,
profile.worker_id,
worker.id,
profile.login,
position.id
FROM
Brewery.profile
JOIN
Brewery.worker
JOIN
Brewery.position
ON profile.worker_id = worker.id
AND profile.login=?
AND worker.position_id =position.id"#,
)
.bind(username)
.fetch_one(&self.pool)
.await
.unwrap();
Ok(ans)
}
}
pub async fn estabilish_connection() -> Result<(), sqlx::Error> {

View File

@ -1,9 +1,13 @@
use std::{collections::HashMap, sync::Arc};
use std::{collections::HashMap, default::Default, sync::Arc};
use egui::mutex::RwLock;
use egui_extras::{Column, TableBuilder};
use crate::{database::DBOperator, models::{Material, MaterialCategory, MaterialRow, ModalStatus, ModalWinState}, tab::{TABS_CAN_BE_WINDOWS, Tab, TabTypes}};
use crate::{
database::DBOperator,
models::{Material, MaterialCategory, MaterialRow, ModalStatus, ModalWinState},
tab::{TABS_CAN_BE_WINDOWS, Tab, TabTypes},
};
pub struct MaterialTabViewer {
db_oper: DBOperator,
@ -14,8 +18,15 @@ pub struct MaterialTabViewer {
mat_cats: Arc<RwLock<Vec<MaterialCategory>>>,
mats: Arc<RwLock<Vec<Material>>>,
is_admin: bool,
}
impl MaterialTabViewer {
pub fn new(is_admin: bool) -> Self {
Self {
is_admin,
..Default::default()
}
}
fn update_material_category(&mut self) {
self.mat_cats = Arc::new(RwLock::new(
self.rt
@ -576,6 +587,7 @@ impl Default for MaterialTabViewer {
},
mat_cats,
mats,
is_admin: false,
}
}
}

View File

@ -112,6 +112,12 @@ pub struct Product<'a> {
price_per_unit: rust_decimal::Decimal,
}
#[derive(Default)]
pub struct User{
login: String,
is_admin: bool,
worker: Worker,
}
#[derive(Default)]
pub struct ModalWinState {
pub is_open: bool,
pub can_finish: bool,

View File

@ -1,8 +1,17 @@
use crate::tab::{Tab, TabTypes};
use std::default::Default;
struct RecipeTabViewer {}
struct RecipeTabViewer {
is_admin: bool,
}
impl RecipeTabViewer {
fn new(is_admin: bool) -> Self {
Self {
is_admin,
..Default::default()
}
}
fn show_recipe_list(&mut self, ui: &mut egui::Ui) {}
fn show_recipe_detail(&mut self, ui: &mut egui::Ui) {}
}
@ -27,3 +36,9 @@ impl egui_dock::TabViewer for RecipeTabViewer {
}
}
}
impl Default for RecipeTabViewer {
fn default() -> Self {
Self { is_admin: false }
}
}

View File

@ -1,16 +1,17 @@
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::{Arc};
use bigdecimal::BigDecimal;
use egui::mutex::RwLock;
use egui_extras::{Column, TableBuilder};
use std::collections::HashMap;
use std::default::Default;
use std::str::FromStr;
use std::sync::Arc;
use crate::models::{ModalStatus, ModalWinState, Position, Worker};
use crate::database::*;
use crate::models::{ModalStatus, ModalWinState, Position, Worker};
use crate::tab::*;
pub struct WorkerTabViewer {
db_oper: DBOperator,
workers: Arc<RwLock<Option<Vec<Worker>>>>,
workers: Arc<RwLock<Vec<Worker>>>,
positions: Arc<RwLock<Vec<Position>>>,
show_worker_add_modal: bool,
show_worker_edit_modal: bool,
@ -33,15 +34,23 @@ pub struct WorkerTabViewer {
rt: tokio::runtime::Runtime,
show_position_delete_modal: bool,
delete_position: Position,
process_worker_state: ModalWinState,
process_position_state: ModalWinState,
is_admin: bool,
}
impl WorkerTabViewer {
pub fn new(is_admin: bool) -> Self {
Self {
is_admin,
..Default::default()
}
}
fn update_workers(&mut self) {
self.workers = Arc::new(RwLock::new(Option::Some(
self.workers = Arc::new(RwLock::new(
self.rt
.block_on(async { self.db_oper.get_workers().await.unwrap() }),
)));
));
}
fn update_positions(&mut self) {
self.positions = Arc::new(RwLock::new(
@ -98,7 +107,7 @@ impl WorkerTabViewer {
.selected_text(format!("{}", self.add_worker_position.name))
.show_ui(ui, |ui| {
self.rt.block_on(async {
for pos in self.db_oper.get_position().await.unwrap().iter() {
for pos in self.positions.read().clone().iter() {
ui.selectable_value(
&mut self.add_worker_position,
pos.clone(),
@ -278,7 +287,7 @@ impl WorkerTabViewer {
.body(|mut body| {
body.ui_mut().style_mut().interaction.selectable_labels = false;
for wk in self.workers.read().clone().unwrap().iter() {
for wk in self.workers.read().clone().iter() {
body.row(25.0, |mut row| {
row.col(|ui| {
ui.label(&wk.full_name);
@ -420,7 +429,6 @@ impl WorkerTabViewer {
.workers
.read()
.clone()
.unwrap()
.iter()
.find(|wrkr| wrkr.position.id == self.delete_position.id)
.iter()
@ -493,9 +501,7 @@ impl egui_dock::TabViewer for WorkerTabViewer {
}
fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) {
match &tab.tab_type {
TabTypes::WorkerList => {
self.show_worker(ui)
},
TabTypes::WorkerList => self.show_worker(ui),
TabTypes::WorkerPosition => self.show_position(ui),
_ => {
ui.label("Nope");
@ -519,6 +525,9 @@ impl Default for WorkerTabViewer {
let positions = Arc::new(RwLock::new(
rt.block_on(async { db_oper.get_position().await.unwrap() }),
));
let workers = Arc::new(RwLock::new(
rt.block_on(async { db_oper.get_workers().await.unwrap() }),
));
let mut pos_map: HashMap<String, String> = HashMap::new();
pos_map.extend(|| -> Vec<(String, String)> {
let pos = positions.read()[0].clone();
@ -528,6 +537,20 @@ impl Default for WorkerTabViewer {
("wage".to_string(), pos.wage.to_string()),
]
}());
let mut worker_map: HashMap<String, String> = HashMap::new();
worker_map.extend(|| -> Vec<(String, String)> {
let worker = workers.read()[0].clone();
vec![
("id".to_string(), worker.id.to_string()),
("full_name".to_string(), worker.full_name),
("position_id".to_string(), worker.position.id.to_string()),
(
"hire_date".to_string(),
worker.hire_date.date_naive().format("%d-%m-%Y").to_string(),
),
("is_fired".to_string(), worker.is_fired.to_string()),
]
}());
Self {
process_position_state: ModalWinState {
is_open: false,
@ -535,9 +558,13 @@ impl Default for WorkerTabViewer {
data: pos_map,
status: ModalStatus::Add,
},
workers: Arc::new(RwLock::new(Option::Some(
rt.block_on(async { db_oper.get_workers().await.unwrap() }),
))),
process_worker_state: ModalWinState {
is_open: false,
can_finish: false,
data: worker_map,
status: ModalStatus::Add,
},
workers,
positions: positions,
show_worker_add_modal: false,
show_worker_edit_modal: false,
@ -561,6 +588,7 @@ impl Default for WorkerTabViewer {
db_oper,
rt,
is_admin: false,
}
}
}