Штирлиц ходил на задание без трусов. Только со смелыми.

master
Алексей Алексей 2026-05-17 13:15:42 +10:00
parent c08817d049
commit 666cd516c2
5 changed files with 89 additions and 9 deletions

4
code/Cargo.lock generated
View File

@ -3803,6 +3803,7 @@ dependencies = [
"base64",
"bigdecimal",
"bytes",
"chrono",
"crc",
"crossbeam-queue",
"either",
@ -3879,6 +3880,7 @@ dependencies = [
"bitflags 2.11.1",
"byteorder",
"bytes",
"chrono",
"crc",
"digest",
"dotenvy",
@ -3921,6 +3923,7 @@ dependencies = [
"bigdecimal",
"bitflags 2.11.1",
"byteorder",
"chrono",
"crc",
"dotenvy",
"etcetera",
@ -3956,6 +3959,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea"
dependencies = [
"atoi",
"chrono",
"flume",
"futures-channel",
"futures-core",

View File

@ -12,7 +12,7 @@ egui = "0.34.2"
egui_dock = "0.19.1"
egui_extras = "0.34.2"
rust_decimal = {version = "1.42.0", features = ["macros"]}
sqlx = {version="0.8.6", features = ["runtime-tokio", "mysql","bigdecimal"]}
sqlx = {version="0.8.6", features = ["runtime-tokio", "mysql","bigdecimal","chrono"]}
tokio={version = "1.52.3", features = ["full"]}
[target.'cfg(target_os="windows")'.dependencies]

View File

@ -1,9 +1,9 @@
use std::sync::Arc;
use egui::mutex::RwLock;
use egui_dock::{DockArea, Style};
use egui_dock::{DockArea, Style, TabViewer};
use sqlx::{Connection, MySqlConnection, MySqlPool};
use crate::{database::DBOperator, models::{self, Position}};
use crate::{database::DBOperator, models::{self, Position, Salary, Worker}};
static TABS_CAN_BE_WINDOWS: bool = false;
@ -51,7 +51,7 @@ impl Default for App{
},
Tab{
tab_type: TabTypes::Recipe,
title: "Рецеты".to_owned(),
title: "Рецепты".to_owned(),
},
Tab{
tab_type: TabTypes::Product,
@ -80,8 +80,10 @@ impl eframe::App for App{
struct MainTabViewer {
positions: Arc<RwLock<Option<Vec<Position>>>>,
workers: Arc<RwLock<Option<Vec<Worker>>>>,
equipment: std::vec::Vec<crate::models::Equipment>,
db_oper: DBOperator,
worker_tabs: WorkerTabViewer,
}
impl Default for MainTabViewer{
@ -90,8 +92,10 @@ impl Default for MainTabViewer{
let rt = tokio::runtime::Runtime::new().unwrap();
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()],
db_oper
db_oper,
worker_tabs: WorkerTabViewer{}
}
}
}
@ -133,7 +137,41 @@ impl MainTabViewer{
}
fn show_worker(&mut self, ui: &mut egui::Ui){
todo!()
let rt = tokio::runtime::Runtime::new().unwrap();
ui.horizontal(|ui|{
if ui.button("Добавить").clicked() {
};
if ui.button("Уволить").clicked() {
}
});
rt.block_on(async{
for wk in self.workers.read().clone().unwrap().iter(){
ui.push_id(format!("{}:{}",&wk.full_name,&wk.id),|ui| {
egui::CollapsingHeader::new(format!("#{:08} | {}",&wk.id,&wk.full_name))
.default_open(false)
.show(ui, |ui|{
ui.horizontal(|ui|{
ui.label("Нанят: ");
ui.label(format!("{}",wk.hire_date.date_naive().format("%d-%m-%Y").to_string()));
});
ui.horizontal(|ui|{
ui.label("Должность: ");
ui.label(&wk.position.name);
});
ui.horizontal(|ui|{
ui.label("Уволен: ");
ui.label(if wk.is_fired {
"Да"
}else{
"Нет"
})
})
})
});
}
})
}
fn show_position(&mut self, ui: &mut egui::Ui){
@ -152,7 +190,7 @@ impl MainTabViewer{
})
}
fn show_salary(&mut self, ui: &mut egui::Ui){
ui.label("Salary");
self.worker_tabs.
}
fn show_material(&mut self, ui: &mut egui::Ui){
ui.label("Сырьё короче да");
@ -195,3 +233,16 @@ impl egui_dock::TabViewer for MainTabViewer{
false
}
}
struct WorkerTabViewer{
}
impl egui_dock::TabViewer for WorkerTabViewer{
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) {
}
}

View File

@ -22,6 +22,23 @@ impl DBOperator{
let rets: Vec<Position> = sqlx::query_as:: <_, Position>("SELECT * FROM `position`").fetch_all(&pool).await?;
Ok(rets)
}
pub async fn get_workers(&self) -> Result<Vec<Worker>, sqlx::Error>{
let pool = MySqlPool::connect(&self.connection_string).await?;
let pre_rets: Vec<WorkerRow> = sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker`").fetch_all(&pool).await?;
let mut rets:Vec<Worker> = Vec::new();
let pos = self.get_position().await.unwrap();
for worker in pre_rets{
let mut ppos = Position::default();
for position in pos.clone(){
if position.id == worker.position_id{
ppos = position.clone();
break;
}
}
rets.push(Worker{ id: worker.id, full_name: worker.full_name, hire_date: worker.hire_date, position: ppos, is_fired: worker.is_fired });
}
Ok(rets)
}
}

View File

@ -1,4 +1,4 @@
use sqlx::types::BigDecimal;
use sqlx::types::{BigDecimal, chrono::DateTime};
#[derive(Default, Clone, Hash, sqlx::FromRow)]
@ -11,10 +11,18 @@ pub struct Position{
pub struct Worker{
pub id: i32,
pub full_name: String,
pub hire_date: chrono::DateTime<chrono::Local>,
pub hire_date: DateTime<chrono::Local>,
pub position: Position,
pub is_fired: bool,
}
#[derive(sqlx::FromRow)]
pub struct WorkerRow{
pub id: i32,
pub full_name: String,
pub hire_date: DateTime<chrono::Local>,
pub position_id: i32,
pub is_fired: bool,
}
pub struct Salary{
id: i32,
worker: Worker,