Compare commits
No commits in common. "49499a88b364682948cc70e54da6bef9118c8b76" and "f1908d1fc4e849872613d96e2b07dcaf9704ad07" have entirely different histories.
49499a88b3
...
f1908d1fc4
35
Cargo.lock
generated
35
Cargo.lock
generated
@ -286,15 +286,6 @@ dependencies = [
|
|||||||
"cmake",
|
"cmake",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fltk-theme"
|
|
||||||
version = "0.7.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3539d27a815514b56af2afa6b8e7c6d6b9274a103239487d5a60daa6340a4868"
|
|
||||||
dependencies = [
|
|
||||||
"fltk",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluid-parser"
|
name = "fluid-parser"
|
||||||
version = "0.1.15"
|
version = "0.1.15"
|
||||||
@ -385,12 +376,6 @@ dependencies = [
|
|||||||
"mach2",
|
"mach2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "1.0.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.69"
|
version = "0.3.69"
|
||||||
@ -784,12 +769,6 @@ dependencies = [
|
|||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ryu"
|
|
||||||
version = "1.0.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@ -837,17 +816,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_json"
|
|
||||||
version = "1.0.120"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
|
||||||
dependencies = [
|
|
||||||
"itoa",
|
|
||||||
"ryu",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serialport"
|
name = "serialport"
|
||||||
version = "4.4.0"
|
version = "4.4.0"
|
||||||
@ -1136,14 +1104,11 @@ dependencies = [
|
|||||||
"chrono",
|
"chrono",
|
||||||
"fl2rust",
|
"fl2rust",
|
||||||
"fltk",
|
"fltk",
|
||||||
"fltk-theme",
|
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libsqlite3-sys",
|
"libsqlite3-sys",
|
||||||
"log",
|
"log",
|
||||||
"once_cell 0.1.8",
|
"once_cell 0.1.8",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"serialport",
|
"serialport",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "^1.0.86"
|
anyhow = "^1.0.86"
|
||||||
fltk = { version = "^1.4", features = ["fltk-bundled"] }
|
fltk = { version = "^1.4", features = ["fltk-bundled"] }
|
||||||
fltk-theme = "0.7.2"
|
|
||||||
calamine = "0.25.0"
|
calamine = "0.25.0"
|
||||||
serialport = "4.4.0"
|
serialport = "4.4.0"
|
||||||
rusqlite = "0.25.4"
|
rusqlite = "0.25.4"
|
||||||
@ -17,13 +16,6 @@ chrono = "0.4.38"
|
|||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
once_cell = "0.1.8"
|
once_cell = "0.1.8"
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
serde= { version = "1.0.203", features = ["derive"] }
|
|
||||||
serde_json="1.0.120"
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
fl2rust = "0.5.19"
|
fl2rust = "0.5.19"
|
||||||
|
|
||||||
[package.metadata.windows]
|
|
||||||
# For windows subsystem
|
|
||||||
link-args = ["/SUBSYSTEM:windows", "/ENTRY:mainCRTStartup"]
|
|
||||||
subsystem = "windows"
|
|
Binary file not shown.
@ -1,13 +1,10 @@
|
|||||||
use fltk::{*};
|
use fltk::{prelude::*, window::Window, *};
|
||||||
use crate::services::ui_service::UiService;
|
use crate::services::ui_service::UiService;
|
||||||
use fltk_theme::{WidgetTheme, ThemeType};
|
|
||||||
mod services;
|
mod services;
|
||||||
mod models;
|
mod models;
|
||||||
mod ui;
|
mod ui;
|
||||||
fn main() {
|
fn main() {
|
||||||
let app = app::App::default();
|
let app = app::App::default();
|
||||||
let widget_theme = WidgetTheme::new(ThemeType::Metro);
|
|
||||||
widget_theme.apply();
|
|
||||||
let mut ui_service = UiService::new();
|
let mut ui_service = UiService::new();
|
||||||
ui_service.init_components();
|
ui_service.init_components();
|
||||||
app.run().unwrap();
|
app.run().unwrap();
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
||||||
pub(crate) struct ConfigModel{
|
|
||||||
pub current_line: usize,
|
|
||||||
pub excel_path: String,
|
|
||||||
pub last_com: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ConfigModel {
|
|
||||||
fn default() -> Self {
|
|
||||||
ConfigModel {
|
|
||||||
current_line: 0,
|
|
||||||
excel_path: "".to_string(),
|
|
||||||
last_com: "".to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +1 @@
|
|||||||
pub(crate) mod work_model;
|
pub(crate) mod work_model;
|
||||||
pub(crate) mod config_model;
|
|
@ -1,21 +0,0 @@
|
|||||||
use std::fs;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
use crate::models::config_model::ConfigModel;
|
|
||||||
|
|
||||||
pub(crate) struct ConfigService;
|
|
||||||
|
|
||||||
impl ConfigService {
|
|
||||||
pub fn save_config(model: ConfigModel) ->Result<()> {
|
|
||||||
let json = serde_json::to_string(&model)?;
|
|
||||||
fs::write("config.json", json)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_config() -> Result<ConfigModel> {
|
|
||||||
let json = fs::read_to_string("config.json")?;
|
|
||||||
let model: ConfigModel = serde_json::from_str(&json)?;
|
|
||||||
Ok(model)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +1,12 @@
|
|||||||
|
use std::fs::File;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use calamine::{Reader, open_workbook, Xlsx, Data, DataType};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use calamine::{Data, DataType, open_workbook, Reader, Xlsx};
|
|
||||||
|
|
||||||
use crate::models::work_model::WorkModel;
|
use crate::models::work_model::WorkModel;
|
||||||
|
|
||||||
pub(crate) struct ExcelService {
|
pub(crate) struct ExcelService {
|
||||||
current_line: usize,
|
current_line: usize,
|
||||||
|
work_book: Xlsx<BufReader<File>>,
|
||||||
sheet: calamine::Range<Data>,
|
sheet: calamine::Range<Data>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +25,7 @@ impl ExcelService {
|
|||||||
};
|
};
|
||||||
let mut service = ExcelService {
|
let mut service = ExcelService {
|
||||||
current_line: 0,
|
current_line: 0,
|
||||||
|
work_book,
|
||||||
sheet,
|
sheet,
|
||||||
};
|
};
|
||||||
service.current_line = service.find_first_useful_line();
|
service.current_line = service.find_first_useful_line();
|
||||||
@ -49,15 +52,6 @@ impl ExcelService {
|
|||||||
current_line
|
current_line
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_current_line(&mut self, line: usize)->Result<(), String>{
|
|
||||||
self.current_line = line;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn roll_back(&mut self){
|
|
||||||
self.current_line -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_next_work_model(&mut self) -> Result<WorkModel, String> {
|
pub fn get_next_work_model(&mut self) -> Result<WorkModel, String> {
|
||||||
let mut work_model = WorkModel::default();
|
let mut work_model = WorkModel::default();
|
||||||
if let Some(imei) = self.sheet.get((self.current_line, 0)) {
|
if let Some(imei) = self.sheet.get((self.current_line, 0)) {
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
use chrono::Local;
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use log::{Level, Metadata, Record, SetLoggerError};
|
|
||||||
|
|
||||||
type LogCallback = Box<dyn Fn(&str) + Send + Sync>;
|
|
||||||
|
|
||||||
pub struct FltkLogger {
|
|
||||||
callback: Arc<Mutex<Option<LogCallback>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FltkLogger {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
FltkLogger {
|
|
||||||
callback: Arc::new(Mutex::new(None)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_callback<F>(&self, callback: F)
|
|
||||||
where
|
|
||||||
F: Fn(&str) + 'static + Send + Sync,
|
|
||||||
{
|
|
||||||
let mut cb = self.callback.lock().unwrap();
|
|
||||||
*cb = Some(Box::new(callback));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl log::Log for FltkLogger {
|
|
||||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
|
||||||
metadata.level() <= Level::Info
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log(&self, record: &Record) {
|
|
||||||
if self.enabled(record.metadata()) {
|
|
||||||
if let Some(callback) = self.callback.lock().unwrap().as_ref() {
|
|
||||||
callback(&format!("{}: {} - {}\r\n",Local::now().format("%Y-%m-%d %H:%M:%S"), record.level(), record.args()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref LOGGER: FltkLogger = FltkLogger::new();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_logger() -> Result<(), SetLoggerError> {
|
|
||||||
log::set_logger(&*LOGGER)
|
|
||||||
.map(|()| log::set_max_level(log::LevelFilter::Info))
|
|
||||||
}
|
|
@ -4,4 +4,3 @@ pub(crate) mod excel_service;
|
|||||||
pub(crate) mod ui_service;
|
pub(crate) mod ui_service;
|
||||||
pub(crate) mod work_service;
|
pub(crate) mod work_service;
|
||||||
pub(crate) mod log_service;
|
pub(crate) mod log_service;
|
||||||
pub(crate) mod config_service;
|
|
@ -1,23 +1,21 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use serialport::*;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use serialport::*;
|
|
||||||
|
|
||||||
pub struct SerialService {
|
pub struct SerialService {
|
||||||
port: Box<dyn SerialPort>,
|
port: Box<dyn SerialPort>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl SerialService {
|
impl SerialService {
|
||||||
pub fn new(port_name: &str) -> Result<Box<Self>> {
|
pub fn new(port_name: &str) -> Result<Box<Self>> {
|
||||||
let port = new(port_name, 115_200)
|
let port = serialport::new(port_name, 115_200)
|
||||||
.timeout(Duration::from_millis(200))
|
.timeout(Duration::from_millis(200))
|
||||||
.open()?;
|
.open()?;
|
||||||
Ok(Box::new(SerialService { port }))
|
Ok(Box::new(SerialService { port }))
|
||||||
}
|
}
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn get_ports() -> Result<Vec<String>> {
|
pub fn get_ports() -> Result<Vec<String>> {
|
||||||
let portinfos = serialport::available_ports()?;
|
let portinfos = serialport::available_ports()?;
|
||||||
let mut portnames: Vec<String> = Vec::new();
|
let mut portnames: Vec<String> = Vec::new();
|
||||||
@ -56,10 +54,6 @@ impl SerialService {
|
|||||||
Err(err) => Err(err)
|
Err(err) => Err(err)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn close_serial(&mut self)->Result<()>{
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use chrono::Local;
|
|
||||||
use rusqlite::Connection;
|
|
||||||
|
|
||||||
use crate::models::work_model::*;
|
use crate::models::work_model::*;
|
||||||
|
use rusqlite::{Connection};
|
||||||
|
use chrono::Local;
|
||||||
|
|
||||||
pub(crate) struct SqliteService {
|
pub(crate) struct SqliteService {
|
||||||
conn: Connection,
|
conn: Connection,
|
||||||
@ -20,9 +19,7 @@ impl Default for SqliteService {
|
|||||||
impl SqliteService {
|
impl SqliteService {
|
||||||
pub fn new(conn_str: String) -> Result<Self> {
|
pub fn new(conn_str: String) -> Result<Self> {
|
||||||
let conn = Connection::open(conn_str)?;
|
let conn = Connection::open(conn_str)?;
|
||||||
let this = Self { conn };
|
Ok(Self { conn })
|
||||||
this.create_table()?;
|
|
||||||
return Ok(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_table(&self) -> Result<()> {
|
pub fn create_table(&self) -> Result<()> {
|
||||||
@ -48,14 +45,20 @@ impl SqliteService {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_sn_has_insert(&self, sn: &str) -> Result<bool> {
|
pub fn check_sn(&self, sn: &str) -> Result<bool> {
|
||||||
let mut stmt = self.conn.prepare("SELECT sn FROM write_results WHERE sn = ?1")?;
|
let mut stmt = self.conn.prepare("SELECT sn FROM write_results WHERE sn = ?1")?;
|
||||||
let mut rows = stmt.query(&[&sn])?;
|
let mut rows = stmt.query(&[&sn])?;
|
||||||
Ok(rows.next()?.is_some())
|
Ok(rows.next()?.is_some())
|
||||||
}
|
}
|
||||||
pub fn check_imei_has_insert(&self, imei: &str) -> Result<bool> {
|
pub fn check_imei(&self, imei: &str) -> Result<bool> {
|
||||||
let mut stmt = self.conn.prepare("SELECT imei FROM write_results WHERE imei = ?1")?;
|
let mut stmt = self.conn.prepare("SELECT sn FROM write_results WHERE sn = ?1")?;
|
||||||
let mut rows = stmt.query(&[&imei])?;
|
let mut rows = stmt.query(&[&imei])?;
|
||||||
Ok(rows.next()?.is_some())
|
Ok(rows.next()?.is_some())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_sql_service_test() {
|
||||||
|
let service = SqliteService::default();
|
||||||
|
}
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::path::Path;
|
|
||||||
use std::process;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex};
|
use fltk::prelude::{InputExt, WidgetExt};
|
||||||
use fltk::prelude::{DisplayExt, InputExt, MenuExt, WidgetExt};
|
use crate::models::work_model::WorkModel;
|
||||||
use fltk::text::TextBuffer;
|
use crate::services::excel_service::ExcelService;
|
||||||
|
use crate::services::serial_service::SerialService;
|
||||||
use crate::services::log_service::LOGGER;
|
|
||||||
use crate::services::work_service::WorkService;
|
use crate::services::work_service::WorkService;
|
||||||
use crate::ui::main_ui;
|
use crate::ui::main_ui;
|
||||||
use crate::ui::main_ui::*;
|
use crate::ui::main_ui::*;
|
||||||
@ -14,106 +11,27 @@ use crate::ui::main_ui::*;
|
|||||||
pub(crate) struct UiService {
|
pub(crate) struct UiService {
|
||||||
ui: Rc<RefCell<UserInterface>>,
|
ui: Rc<RefCell<UserInterface>>,
|
||||||
work_service: Rc<RefCell<WorkService>>,
|
work_service: Rc<RefCell<WorkService>>,
|
||||||
|
current_com: String
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UiService {
|
impl UiService {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
// Create the Rc<RefCell<>> instances
|
|
||||||
let ui = Rc::new(RefCell::new(main_ui::UserInterface::make_window()));
|
let ui = Rc::new(RefCell::new(main_ui::UserInterface::make_window()));
|
||||||
let work_service_rc = Rc::new(RefCell::new(WorkService::new()));
|
UiService { ui, work_service: Rc::new(RefCell::new(WorkService::new())), current_com: "".to_string() }
|
||||||
|
|
||||||
// Clone the Rc<RefCell<>> to avoid moving them
|
|
||||||
let work_service_clone = Rc::clone(&work_service_rc);
|
|
||||||
let current_com;
|
|
||||||
let should_current_line;
|
|
||||||
let comports = WorkService::get_port_names();
|
|
||||||
for com in comports {
|
|
||||||
ui.borrow_mut().com_choice.add_choice(&com);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let work_service = work_service_clone.borrow_mut();
|
|
||||||
current_com = work_service.config_model.last_com.clone();
|
|
||||||
should_current_line = work_service.config_model.current_line;
|
|
||||||
}
|
|
||||||
|
|
||||||
if Path::exists(work_service_rc.borrow().config_model.excel_path.as_ref()) {
|
|
||||||
ui.borrow_mut().excel_file_textbox.set_value(&work_service_rc.borrow().config_model.excel_path);
|
|
||||||
ui.borrow_mut().current_line_textbox.set_value(&work_service_rc.borrow().config_model.current_line.to_string());
|
|
||||||
let index = ui.borrow().com_choice.find_index(¤t_com);
|
|
||||||
ui.borrow_mut().com_choice.set_value(index);
|
|
||||||
|
|
||||||
work_service_rc.borrow_mut().excel_service.as_mut().unwrap().set_current_line(should_current_line).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let ui_service = UiService {
|
|
||||||
ui,
|
|
||||||
work_service: work_service_rc,
|
|
||||||
};
|
|
||||||
|
|
||||||
ui_service
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn init_components(&mut self) {
|
pub(crate) fn init_components(&mut self) {
|
||||||
self.init_excel();
|
self.init_excel();
|
||||||
self.init_start_btn();
|
self.init_start_btn();
|
||||||
self.init_set_line_btn();
|
|
||||||
self.init_log();
|
|
||||||
self.init_refresh_com_button();
|
|
||||||
self.init_exit_callback();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_refresh_com_button(&mut self) {
|
pub fn init_start_btn(&mut self) {
|
||||||
let ui_rc = Rc::clone(&self.ui);
|
let ui_rc = Rc::clone(&self.ui);
|
||||||
self.ui.borrow_mut().refresh_com_btn.set_callback(move |_| {
|
let ui_rc_clone = Rc::clone(&ui_rc);
|
||||||
let comports = WorkService::get_port_names();
|
|
||||||
let mut ui = ui_rc.borrow_mut();
|
|
||||||
ui.com_choice.clear();
|
|
||||||
for com in comports {
|
|
||||||
ui.com_choice.add_choice(&com);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
fn init_exit_callback(&mut self) {
|
|
||||||
let work_service_rc = Rc::clone(&self.work_service);
|
let work_service_rc = Rc::clone(&self.work_service);
|
||||||
self.ui.borrow_mut().main_window.set_callback(move |_| {
|
ui_rc.borrow_mut().start_btn.set_callback(move |_| {
|
||||||
let work_service = work_service_rc.borrow_mut();
|
|
||||||
work_service.save_config();
|
|
||||||
process::exit(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_set_line_btn(&mut self) {
|
|
||||||
let ui_rc = Rc::clone(&self.ui);
|
|
||||||
let work_service_rc = Rc::clone(&self.work_service);
|
|
||||||
self.ui.borrow_mut().set_lines_btn.set_callback(move |_| {
|
|
||||||
let ui_clone = ui_rc.clone();
|
|
||||||
let mut set_dialog = UserInterface1::make_set_line_window();
|
|
||||||
let work_service_rc_clone = work_service_rc.clone();
|
|
||||||
set_dialog.ok_btn.set_callback(move |_| {
|
|
||||||
if let Ok(line) = set_dialog.line_textbox.value().parse::<usize>() {
|
|
||||||
match work_service_rc_clone.borrow_mut().set_current_line(line) {
|
|
||||||
Ok(_) => {
|
|
||||||
ui_clone.borrow_mut().current_line_textbox.set_value(&line.to_string());
|
|
||||||
}
|
|
||||||
Err(msg) => fltk::dialog::message_default(&msg)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fltk::dialog::message_default(&"Only Support Number")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_start_btn(&mut self) {
|
|
||||||
let ui_rc_clone = Rc::clone(&self.ui);
|
|
||||||
let work_service_rc = Rc::clone(&self.work_service);
|
|
||||||
self.ui.borrow_mut().start_btn.set_callback(move |_| {
|
|
||||||
let mut ui = ui_rc_clone.borrow_mut();
|
let mut ui = ui_rc_clone.borrow_mut();
|
||||||
let mut work_service = work_service_rc.borrow_mut();
|
let mut work_service = work_service_rc.borrow_mut();
|
||||||
if let Some(mut buffer) = ui.log_content.buffer() {
|
|
||||||
buffer.set_text("");
|
|
||||||
}
|
|
||||||
match work_service.excel_service {
|
match work_service.excel_service {
|
||||||
None => {
|
None => {
|
||||||
fltk::dialog::message_default("Please Select Excel File First;");
|
fltk::dialog::message_default("Please Select Excel File First;");
|
||||||
@ -121,54 +39,44 @@ impl UiService {
|
|||||||
}
|
}
|
||||||
Some(_) => {}
|
Some(_) => {}
|
||||||
}
|
}
|
||||||
let selected_com = ui.com_choice.choice().unwrap();
|
let selected_com = ui.com_textbox.value();
|
||||||
if let Err(msg) = work_service.init_serial_service(selected_com) {
|
if let Err(msg) = work_service.init_serial_service(selected_com) {
|
||||||
fltk::dialog::message_default(&msg);
|
fltk::dialog::message_default(&msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(model) = work_service.get_next_work_model() {
|
if let Some(mut model) = work_service.get_next_work_model() {
|
||||||
ui.current_write_model.set_value(&format!("{}: {}_{}", &model.line_number, &model.imei, &model.sn));
|
ui.current_write_model.set_value(&format!("{}: {}_{}", &model.line_number, &model.imei, &model.sn));
|
||||||
match work_service.write_and_check(model) {
|
match work_service.write_and_check(model) {
|
||||||
Ok(_) => {
|
Ok(_) => {}
|
||||||
let current_line = &work_service.get_current_line().to_string();
|
Err(msg) => { fltk::dialog::message_default(&msg) }
|
||||||
ui.current_line_textbox.set_value(current_line);
|
|
||||||
}
|
|
||||||
Err(msg) => {
|
|
||||||
work_service.roll_back();
|
|
||||||
fltk::dialog::message_default(&msg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_log(&mut self) {
|
|
||||||
let text_buffer = TextBuffer::default();
|
|
||||||
self.ui.borrow_mut().log_content.set_buffer(text_buffer.clone());
|
|
||||||
let text_buffer_arc = Arc::new(Mutex::new(text_buffer));
|
|
||||||
LOGGER.set_callback(move |msg| {
|
|
||||||
let mut text_buffer = text_buffer_arc.lock().unwrap();
|
|
||||||
text_buffer.append(&msg);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_excel(&mut self) {
|
fn init_excel(&mut self) {
|
||||||
let ui_rc = Rc::clone(&self.ui);
|
let ui_rc = Rc::new(&self.ui);
|
||||||
|
let ui_clone = Rc::clone(&self.ui);
|
||||||
let work_service_clone = Rc::clone(&self.work_service);
|
let work_service_clone = Rc::clone(&self.work_service);
|
||||||
self.ui.borrow_mut().select_file_btn.set_callback(move |_| {
|
ui_rc.borrow_mut().select_file_btn.set_callback(move |_| {
|
||||||
let mut ui = ui_rc.borrow_mut();
|
let mut ui = ui_clone.borrow_mut();
|
||||||
let mut work_service = work_service_clone.borrow_mut();
|
let mut work_service = work_service_clone.borrow_mut();
|
||||||
let mut dialog = fltk::dialog::FileDialog::new(fltk::dialog::FileDialogType::BrowseFile);
|
let mut dialog = fltk::dialog::FileDialog::new(fltk::dialog::FileDialogType::BrowseFile);
|
||||||
dialog.show();
|
dialog.show();
|
||||||
let binding = dialog.filename();
|
let binding = dialog.filename();
|
||||||
let path = binding.to_str().unwrap();
|
let path = binding.to_str().unwrap();
|
||||||
if path == "" { return; }
|
|
||||||
work_service.init_excel_service(path.to_string()).unwrap();
|
|
||||||
let current_line = &work_service.get_current_line().to_string();
|
let current_line = &work_service.get_current_line().to_string();
|
||||||
work_service.config_model.excel_path = path.to_string();
|
work_service.init_excel_service(path.to_string()).unwrap();
|
||||||
work_service.config_model.current_line = current_line.parse::<usize>().unwrap();
|
|
||||||
ui.excel_file_textbox.set_value(path);
|
ui.excel_file_textbox.set_value(path);
|
||||||
ui.current_line_textbox.set_value(current_line);
|
ui.current_line_textbox.set_value(current_line);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_serial_service(&mut self) {
|
||||||
|
let port_name = self.ui.borrow().com_textbox.value();
|
||||||
|
match self.work_service.borrow_mut().init_serial_service(port_name) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(_) => { fltk::dialog::message_default("Cant Open serial") }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,34 +1,21 @@
|
|||||||
use anyhow::Result;
|
use std::ptr::null;
|
||||||
|
|
||||||
use crate::models::config_model::ConfigModel;
|
|
||||||
use crate::models::work_model::WorkModel;
|
use crate::models::work_model::WorkModel;
|
||||||
use crate::services::{config_service::ConfigService, excel_service::ExcelService, serial_service::SerialService, sqlite_service::SqliteService};
|
use crate::services::{serial_service::SerialService, sqlite_service::SqliteService, excel_service::ExcelService};
|
||||||
use crate::services::log_service::{init_logger};
|
|
||||||
|
|
||||||
pub struct WorkService {
|
pub struct WorkService {
|
||||||
pub(crate) serial_service: Option<SerialService>,
|
pub(crate) serial_service: Option<SerialService>,
|
||||||
pub(crate) excel_service: Option<ExcelService>,
|
|
||||||
sqlite_service: SqliteService,
|
sqlite_service: SqliteService,
|
||||||
pub(crate) config_model: ConfigModel,
|
pub(crate) excel_service: Option<ExcelService>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkService {
|
impl WorkService {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
init_logger().unwrap();
|
WorkService {
|
||||||
let config = WorkService::load_config().unwrap_or_else(|_| ConfigModel::default());
|
|
||||||
let mut this = WorkService {
|
|
||||||
serial_service: Option::None,
|
serial_service: Option::None,
|
||||||
sqlite_service: SqliteService::new("data.db".to_string()).unwrap(),
|
sqlite_service: SqliteService::new("data.db".to_string()).unwrap(),
|
||||||
excel_service: Option::None,
|
excel_service: Option::None,
|
||||||
config_model: config,
|
|
||||||
};
|
|
||||||
if this.config_model.excel_path != "" {
|
|
||||||
this.init_excel_service(this.config_model.excel_path.clone()).unwrap();
|
|
||||||
}
|
}
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn get_port_names() -> Vec<String> {
|
pub fn get_port_names() -> Vec<String> {
|
||||||
//maybe should not use unwrap
|
//maybe should not use unwrap
|
||||||
return SerialService::get_ports().unwrap();
|
return SerialService::get_ports().unwrap();
|
||||||
@ -37,7 +24,6 @@ impl WorkService {
|
|||||||
pub fn init_excel_service(&mut self, path: String) -> Result<bool, String> {
|
pub fn init_excel_service(&mut self, path: String) -> Result<bool, String> {
|
||||||
return if let Ok(excel_service) = ExcelService::new(&path) {
|
return if let Ok(excel_service) = ExcelService::new(&path) {
|
||||||
self.excel_service = Some(excel_service);
|
self.excel_service = Some(excel_service);
|
||||||
self.config_model.excel_path = path;
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
Err("Cant Init ExcelService".to_string())
|
Err("Cant Init ExcelService".to_string())
|
||||||
@ -45,51 +31,7 @@ impl WorkService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_and_check(&mut self, model: WorkModel) -> Result<bool, String> {
|
pub fn write_and_check(&mut self, model: WorkModel) -> Result<bool, String> {
|
||||||
log::info!("Write Start");
|
fltk::dialog::message_default(&format!("{}:{}:{}", model.imei, model.sn, model.line_number));
|
||||||
match self.sqlite_service.check_imei_has_insert(&model.imei) {
|
|
||||||
Ok(true) => {
|
|
||||||
log::error!("Imei Exist: {}", model.imei);
|
|
||||||
self.serial_service = None;
|
|
||||||
return Err("Imei Exist".to_string());
|
|
||||||
}
|
|
||||||
_ => {log::info!("Check Imei From Db Pass")}
|
|
||||||
}
|
|
||||||
match self.sqlite_service.check_sn_has_insert(&model.sn) {
|
|
||||||
Ok(true) => {
|
|
||||||
log::error!("Imei Exist: {}", model.sn);
|
|
||||||
self.serial_service = None;
|
|
||||||
return Err("Imei Exist".to_string());
|
|
||||||
}
|
|
||||||
_ => {log::info!("Check Sn From Db Pass")}
|
|
||||||
}
|
|
||||||
if let Err(msg) = self.write_imei(model.imei.clone()) {
|
|
||||||
log::error!("Write Imei Error:{}", msg);
|
|
||||||
return Err(msg);
|
|
||||||
}
|
|
||||||
log::info!("Write Imei:{}", model.imei);
|
|
||||||
if let Err(msg) = self.write_sn(model.sn.clone()) {
|
|
||||||
log::error!("Write Sn Error:{}", msg);
|
|
||||||
return Err(msg);
|
|
||||||
}
|
|
||||||
log::info!("Write Imei:{}", model.sn);
|
|
||||||
log::info!("Write End");
|
|
||||||
log::info!("Check Start");
|
|
||||||
if let Err(msg) = self.check_imei(&model.imei) {
|
|
||||||
log::error!("Check Imei Error:{}", msg);
|
|
||||||
return Err(msg);
|
|
||||||
}
|
|
||||||
log::info!("Check Imei:{}", model.imei);
|
|
||||||
if let Err(msg) = self.check_sn(&model.sn) {
|
|
||||||
log::error!("Check Sn Error:{}", msg);
|
|
||||||
return Err(msg);
|
|
||||||
}
|
|
||||||
log::info!("Check Sn:{}", model.sn);
|
|
||||||
log::info!("Check End");
|
|
||||||
self.serial_service = None;
|
|
||||||
match self.sqlite_service.insert(model) {
|
|
||||||
Err(msg) => { log::error!("Insert Error:{}",msg); }
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,31 +42,15 @@ impl WorkService {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_current_line(&mut self, line: usize) -> Result<(), String> {
|
|
||||||
if let Some(service) = &mut self.excel_service {
|
|
||||||
return service.set_current_line(line);
|
|
||||||
} else {
|
|
||||||
Err("Cant Set Line".to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_next_work_model(&mut self) -> Option<WorkModel> {
|
pub fn get_next_work_model(&mut self) -> Option<WorkModel> {
|
||||||
if let Some(service) = &mut self.excel_service {
|
if let Some(service) = &mut self.excel_service {
|
||||||
if let Ok(model) = service.get_next_work_model() {
|
if let Ok(model) = service.get_next_work_model() {
|
||||||
self.config_model.current_line = service.get_current_line();
|
|
||||||
return Some(model);
|
return Some(model);
|
||||||
} else { return None; }
|
} else { return None; }
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn roll_back(&mut self) {
|
|
||||||
return if let Some(service) = &mut self.excel_service {
|
|
||||||
service.roll_back();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn init_sqlite_service(&mut self, db_path: String) -> Result<bool, String> {
|
pub fn init_sqlite_service(&mut self, db_path: String) -> Result<bool, String> {
|
||||||
return if let Ok(sqlite_service) = SqliteService::new(db_path) {
|
return if let Ok(sqlite_service) = SqliteService::new(db_path) {
|
||||||
self.sqlite_service = sqlite_service;
|
self.sqlite_service = sqlite_service;
|
||||||
@ -137,7 +63,6 @@ impl WorkService {
|
|||||||
pub fn init_serial_service(&mut self, port_name: String) -> Result<bool, String> {
|
pub fn init_serial_service(&mut self, port_name: String) -> Result<bool, String> {
|
||||||
return if let Ok(serial_service) = SerialService::new(&port_name) {
|
return if let Ok(serial_service) = SerialService::new(&port_name) {
|
||||||
self.serial_service = Some(*serial_service);
|
self.serial_service = Some(*serial_service);
|
||||||
self.config_model.last_com = port_name;
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
Err("Cant Init SerialService".to_string())
|
Err("Cant Init SerialService".to_string())
|
||||||
@ -174,12 +99,4 @@ impl WorkService {
|
|||||||
}
|
}
|
||||||
return Err("Cant Init ServialService".to_string());
|
return Err("Cant Init ServialService".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_config(&self) {
|
|
||||||
ConfigService::save_config(self.config_model.clone()).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_config() -> Result<ConfigModel> {
|
|
||||||
return ConfigService::load_config();
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,68 +0,0 @@
|
|||||||
# data file for the Fltk User Interface Designer (fluid)
|
|
||||||
version 1.0400
|
|
||||||
header_name {.h}
|
|
||||||
code_name {.cxx}
|
|
||||||
class UserInterface {open
|
|
||||||
} {
|
|
||||||
Function {make_window()} {open
|
|
||||||
} {
|
|
||||||
Fl_Window main_window {
|
|
||||||
label WriteTool_RS open
|
|
||||||
xywh {721 399 693 467} type Double visible
|
|
||||||
} {
|
|
||||||
Fl_Output current_write_model {
|
|
||||||
label LastImeiAndSn
|
|
||||||
xywh {135 107 375 35}
|
|
||||||
}
|
|
||||||
Fl_Output excel_file_textbox {
|
|
||||||
label {CurrentExcelFile:}
|
|
||||||
xywh {135 20 375 35}
|
|
||||||
}
|
|
||||||
Fl_Button select_file_btn {
|
|
||||||
label SelectFile
|
|
||||||
xywh {535 20 90 30}
|
|
||||||
}
|
|
||||||
Fl_Output current_line_textbox {
|
|
||||||
label CurrentLine
|
|
||||||
xywh {135 62 375 35}
|
|
||||||
}
|
|
||||||
Fl_Button set_lines_btn {
|
|
||||||
label SetLines
|
|
||||||
xywh {535 60 90 30}
|
|
||||||
}
|
|
||||||
Fl_Button start_btn {
|
|
||||||
label Start
|
|
||||||
xywh {532 156 138 35} shortcut 0xff0d color 51 labeltype ENGRAVED_LABEL labelsize 18
|
|
||||||
}
|
|
||||||
Fl_Text_Display log_content {selected
|
|
||||||
xywh {10 210 670 250}
|
|
||||||
}
|
|
||||||
Fl_Choice com_choice {
|
|
||||||
label {Com:} open
|
|
||||||
xywh {135 156 235 35} down_box BORDER_BOX
|
|
||||||
} {}
|
|
||||||
Fl_Button refresh_com_btn {
|
|
||||||
label Refresh
|
|
||||||
xywh {390 156 120 35}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class UserInterface1 {open
|
|
||||||
} {
|
|
||||||
Function {make_set_line_window()} {} {
|
|
||||||
Fl_Window {} {open
|
|
||||||
xywh {1171 275 228 43} type Double visible
|
|
||||||
} {
|
|
||||||
Fl_Input line_textbox {
|
|
||||||
label {Line:}
|
|
||||||
xywh {40 5 130 35}
|
|
||||||
}
|
|
||||||
Fl_Button ok_btn {
|
|
||||||
label ok
|
|
||||||
xywh {175 5 45 35}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
BIN
test_excel.xlsx
BIN
test_excel.xlsx
Binary file not shown.
Loading…
Reference in New Issue
Block a user