Compare commits
10 Commits
f1908d1fc4
...
49499a88b3
Author | SHA1 | Date | |
---|---|---|---|
49499a88b3 | |||
3dc2b3d432 | |||
61b2edca36 | |||
db54dc28c0 | |||
a72344e7cc | |||
3ce29dcd2b | |||
e059757766 | |||
b2de036c61 | |||
8a12c47a1f | |||
3ead5ce0b6 |
35
Cargo.lock
generated
35
Cargo.lock
generated
@ -286,6 +286,15 @@ dependencies = [
|
||||
"cmake",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fltk-theme"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3539d27a815514b56af2afa6b8e7c6d6b9274a103239487d5a60daa6340a4868"
|
||||
dependencies = [
|
||||
"fltk",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluid-parser"
|
||||
version = "0.1.15"
|
||||
@ -376,6 +385,12 @@ dependencies = [
|
||||
"mach2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.69"
|
||||
@ -769,6 +784,12 @@ dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "0.3.3"
|
||||
@ -816,6 +837,17 @@ dependencies = [
|
||||
"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]]
|
||||
name = "serialport"
|
||||
version = "4.4.0"
|
||||
@ -1104,11 +1136,14 @@ dependencies = [
|
||||
"chrono",
|
||||
"fl2rust",
|
||||
"fltk",
|
||||
"fltk-theme",
|
||||
"lazy_static",
|
||||
"libsqlite3-sys",
|
||||
"log",
|
||||
"once_cell 0.1.8",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serialport",
|
||||
]
|
||||
|
||||
|
@ -8,6 +8,7 @@ edition = "2021"
|
||||
[dependencies]
|
||||
anyhow = "^1.0.86"
|
||||
fltk = { version = "^1.4", features = ["fltk-bundled"] }
|
||||
fltk-theme = "0.7.2"
|
||||
calamine = "0.25.0"
|
||||
serialport = "4.4.0"
|
||||
rusqlite = "0.25.4"
|
||||
@ -16,6 +17,13 @@ chrono = "0.4.38"
|
||||
log = "0.4.22"
|
||||
once_cell = "0.1.8"
|
||||
lazy_static = "1.5.0"
|
||||
serde= { version = "1.0.203", features = ["derive"] }
|
||||
serde_json="1.0.120"
|
||||
|
||||
[build-dependencies]
|
||||
fl2rust = "0.5.19"
|
||||
|
||||
[package.metadata.windows]
|
||||
# For windows subsystem
|
||||
link-args = ["/SUBSYSTEM:windows", "/ENTRY:mainCRTStartup"]
|
||||
subsystem = "windows"
|
BIN
IMEI_SN_INDEX.xlsx
Normal file
BIN
IMEI_SN_INDEX.xlsx
Normal file
Binary file not shown.
@ -1,10 +1,13 @@
|
||||
use fltk::{prelude::*, window::Window, *};
|
||||
use fltk::{*};
|
||||
use crate::services::ui_service::UiService;
|
||||
use fltk_theme::{WidgetTheme, ThemeType};
|
||||
mod services;
|
||||
mod models;
|
||||
mod ui;
|
||||
fn main() {
|
||||
let app = app::App::default();
|
||||
let widget_theme = WidgetTheme::new(ThemeType::Metro);
|
||||
widget_theme.apply();
|
||||
let mut ui_service = UiService::new();
|
||||
ui_service.init_components();
|
||||
app.run().unwrap();
|
||||
|
18
src/models/config_model.rs
Normal file
18
src/models/config_model.rs
Normal file
@ -0,0 +1,18 @@
|
||||
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 +1,2 @@
|
||||
pub(crate) mod work_model;
|
||||
pub(crate) mod work_model;
|
||||
pub(crate) mod config_model;
|
21
src/services/config_service.rs
Normal file
21
src/services/config_service.rs
Normal file
@ -0,0 +1,21 @@
|
||||
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,12 +1,10 @@
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use calamine::{Reader, open_workbook, Xlsx, Data, DataType};
|
||||
use anyhow::Result;
|
||||
use calamine::{Data, DataType, open_workbook, Reader, Xlsx};
|
||||
|
||||
use crate::models::work_model::WorkModel;
|
||||
|
||||
pub(crate) struct ExcelService {
|
||||
current_line: usize,
|
||||
work_book: Xlsx<BufReader<File>>,
|
||||
sheet: calamine::Range<Data>,
|
||||
}
|
||||
|
||||
@ -25,7 +23,6 @@ impl ExcelService {
|
||||
};
|
||||
let mut service = ExcelService {
|
||||
current_line: 0,
|
||||
work_book,
|
||||
sheet,
|
||||
};
|
||||
service.current_line = service.find_first_useful_line();
|
||||
@ -52,6 +49,15 @@ impl ExcelService {
|
||||
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> {
|
||||
let mut work_model = WorkModel::default();
|
||||
if let Some(imei) = self.sheet.get((self.current_line, 0)) {
|
||||
|
@ -0,0 +1,52 @@
|
||||
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))
|
||||
}
|
@ -3,4 +3,5 @@ pub(crate) mod sqlite_service;
|
||||
pub(crate) mod excel_service;
|
||||
pub(crate) mod ui_service;
|
||||
pub(crate) mod work_service;
|
||||
pub(crate) mod log_service;
|
||||
pub(crate) mod log_service;
|
||||
pub(crate) mod config_service;
|
@ -1,21 +1,23 @@
|
||||
use anyhow::Result;
|
||||
use serialport::*;
|
||||
use std::io::prelude::*;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Result;
|
||||
use serialport::*;
|
||||
|
||||
pub struct SerialService {
|
||||
port: Box<dyn SerialPort>,
|
||||
}
|
||||
|
||||
|
||||
impl SerialService {
|
||||
pub fn new(port_name: &str) -> Result<Box<Self>> {
|
||||
let port = serialport::new(port_name, 115_200)
|
||||
let port = new(port_name, 115_200)
|
||||
.timeout(Duration::from_millis(200))
|
||||
.open()?;
|
||||
Ok(Box::new(SerialService { port }))
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_ports() -> Result<Vec<String>> {
|
||||
let portinfos = serialport::available_ports()?;
|
||||
let mut portnames: Vec<String> = Vec::new();
|
||||
@ -54,6 +56,10 @@ impl SerialService {
|
||||
Err(err) => Err(err)
|
||||
};
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn close_serial(&mut self)->Result<()>{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,7 +1,8 @@
|
||||
use anyhow::Result;
|
||||
use crate::models::work_model::*;
|
||||
use rusqlite::{Connection};
|
||||
use chrono::Local;
|
||||
use rusqlite::Connection;
|
||||
|
||||
use crate::models::work_model::*;
|
||||
|
||||
pub(crate) struct SqliteService {
|
||||
conn: Connection,
|
||||
@ -19,7 +20,9 @@ impl Default for SqliteService {
|
||||
impl SqliteService {
|
||||
pub fn new(conn_str: String) -> Result<Self> {
|
||||
let conn = Connection::open(conn_str)?;
|
||||
Ok(Self { conn })
|
||||
let this = Self { conn };
|
||||
this.create_table()?;
|
||||
return Ok(this);
|
||||
}
|
||||
|
||||
pub fn create_table(&self) -> Result<()> {
|
||||
@ -45,20 +48,14 @@ impl SqliteService {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn check_sn(&self, sn: &str) -> Result<bool> {
|
||||
pub fn check_sn_has_insert(&self, sn: &str) -> Result<bool> {
|
||||
let mut stmt = self.conn.prepare("SELECT sn FROM write_results WHERE sn = ?1")?;
|
||||
let mut rows = stmt.query(&[&sn])?;
|
||||
Ok(rows.next()?.is_some())
|
||||
}
|
||||
pub fn check_imei(&self, imei: &str) -> Result<bool> {
|
||||
let mut stmt = self.conn.prepare("SELECT sn FROM write_results WHERE sn = ?1")?;
|
||||
pub fn check_imei_has_insert(&self, imei: &str) -> Result<bool> {
|
||||
let mut stmt = self.conn.prepare("SELECT imei FROM write_results WHERE imei = ?1")?;
|
||||
let mut rows = stmt.query(&[&imei])?;
|
||||
Ok(rows.next()?.is_some())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn create_sql_service_test() {
|
||||
let service = SqliteService::default();
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
use std::cell::RefCell;
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::rc::Rc;
|
||||
use fltk::prelude::{InputExt, WidgetExt};
|
||||
use crate::models::work_model::WorkModel;
|
||||
use crate::services::excel_service::ExcelService;
|
||||
use crate::services::serial_service::SerialService;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use fltk::prelude::{DisplayExt, InputExt, MenuExt, WidgetExt};
|
||||
use fltk::text::TextBuffer;
|
||||
|
||||
use crate::services::log_service::LOGGER;
|
||||
use crate::services::work_service::WorkService;
|
||||
use crate::ui::main_ui;
|
||||
use crate::ui::main_ui::*;
|
||||
@ -11,27 +14,106 @@ use crate::ui::main_ui::*;
|
||||
pub(crate) struct UiService {
|
||||
ui: Rc<RefCell<UserInterface>>,
|
||||
work_service: Rc<RefCell<WorkService>>,
|
||||
current_com: String
|
||||
}
|
||||
|
||||
impl UiService {
|
||||
pub(crate) fn new() -> Self {
|
||||
// Create the Rc<RefCell<>> instances
|
||||
let ui = Rc::new(RefCell::new(main_ui::UserInterface::make_window()));
|
||||
UiService { ui, work_service: Rc::new(RefCell::new(WorkService::new())), current_com: "".to_string() }
|
||||
let work_service_rc = Rc::new(RefCell::new(WorkService::new()));
|
||||
|
||||
// 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) {
|
||||
self.init_excel();
|
||||
self.init_start_btn();
|
||||
self.init_set_line_btn();
|
||||
self.init_log();
|
||||
self.init_refresh_com_button();
|
||||
self.init_exit_callback();
|
||||
}
|
||||
|
||||
pub fn init_start_btn(&mut self) {
|
||||
fn init_refresh_com_button(&mut self) {
|
||||
let ui_rc = Rc::clone(&self.ui);
|
||||
let ui_rc_clone = Rc::clone(&ui_rc);
|
||||
self.ui.borrow_mut().refresh_com_btn.set_callback(move |_| {
|
||||
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);
|
||||
ui_rc.borrow_mut().start_btn.set_callback(move |_| {
|
||||
self.ui.borrow_mut().main_window.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 work_service = work_service_rc.borrow_mut();
|
||||
if let Some(mut buffer) = ui.log_content.buffer() {
|
||||
buffer.set_text("");
|
||||
}
|
||||
match work_service.excel_service {
|
||||
None => {
|
||||
fltk::dialog::message_default("Please Select Excel File First;");
|
||||
@ -39,44 +121,54 @@ impl UiService {
|
||||
}
|
||||
Some(_) => {}
|
||||
}
|
||||
let selected_com = ui.com_textbox.value();
|
||||
let selected_com = ui.com_choice.choice().unwrap();
|
||||
if let Err(msg) = work_service.init_serial_service(selected_com) {
|
||||
fltk::dialog::message_default(&msg);
|
||||
return;
|
||||
}
|
||||
if let Some(mut model) = work_service.get_next_work_model() {
|
||||
if let Some(model) = work_service.get_next_work_model() {
|
||||
ui.current_write_model.set_value(&format!("{}: {}_{}", &model.line_number, &model.imei, &model.sn));
|
||||
match work_service.write_and_check(model) {
|
||||
Ok(_) => {}
|
||||
Err(msg) => { fltk::dialog::message_default(&msg) }
|
||||
Ok(_) => {
|
||||
let current_line = &work_service.get_current_line().to_string();
|
||||
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) {
|
||||
let ui_rc = Rc::new(&self.ui);
|
||||
let ui_clone = Rc::clone(&self.ui);
|
||||
let ui_rc = Rc::clone(&self.ui);
|
||||
let work_service_clone = Rc::clone(&self.work_service);
|
||||
ui_rc.borrow_mut().select_file_btn.set_callback(move |_| {
|
||||
let mut ui = ui_clone.borrow_mut();
|
||||
self.ui.borrow_mut().select_file_btn.set_callback(move |_| {
|
||||
let mut ui = ui_rc.borrow_mut();
|
||||
let mut work_service = work_service_clone.borrow_mut();
|
||||
let mut dialog = fltk::dialog::FileDialog::new(fltk::dialog::FileDialogType::BrowseFile);
|
||||
dialog.show();
|
||||
let binding = dialog.filename();
|
||||
let path = binding.to_str().unwrap();
|
||||
let current_line = &work_service.get_current_line().to_string();
|
||||
if path == "" { return; }
|
||||
work_service.init_excel_service(path.to_string()).unwrap();
|
||||
let current_line = &work_service.get_current_line().to_string();
|
||||
work_service.config_model.excel_path = path.to_string();
|
||||
work_service.config_model.current_line = current_line.parse::<usize>().unwrap();
|
||||
ui.excel_file_textbox.set_value(path);
|
||||
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,21 +1,34 @@
|
||||
use std::ptr::null;
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::models::config_model::ConfigModel;
|
||||
use crate::models::work_model::WorkModel;
|
||||
use crate::services::{serial_service::SerialService, sqlite_service::SqliteService, excel_service::ExcelService};
|
||||
use crate::services::{config_service::ConfigService, excel_service::ExcelService, serial_service::SerialService, sqlite_service::SqliteService};
|
||||
use crate::services::log_service::{init_logger};
|
||||
|
||||
pub struct WorkService {
|
||||
pub(crate) serial_service: Option<SerialService>,
|
||||
sqlite_service: SqliteService,
|
||||
pub(crate) excel_service: Option<ExcelService>,
|
||||
sqlite_service: SqliteService,
|
||||
pub(crate) config_model: ConfigModel,
|
||||
}
|
||||
|
||||
impl WorkService {
|
||||
pub fn new() -> Self {
|
||||
WorkService {
|
||||
init_logger().unwrap();
|
||||
let config = WorkService::load_config().unwrap_or_else(|_| ConfigModel::default());
|
||||
let mut this = WorkService {
|
||||
serial_service: Option::None,
|
||||
sqlite_service: SqliteService::new("data.db".to_string()).unwrap(),
|
||||
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> {
|
||||
//maybe should not use unwrap
|
||||
return SerialService::get_ports().unwrap();
|
||||
@ -24,6 +37,7 @@ impl WorkService {
|
||||
pub fn init_excel_service(&mut self, path: String) -> Result<bool, String> {
|
||||
return if let Ok(excel_service) = ExcelService::new(&path) {
|
||||
self.excel_service = Some(excel_service);
|
||||
self.config_model.excel_path = path;
|
||||
Ok(true)
|
||||
} else {
|
||||
Err("Cant Init ExcelService".to_string())
|
||||
@ -31,7 +45,51 @@ impl WorkService {
|
||||
}
|
||||
|
||||
pub fn write_and_check(&mut self, model: WorkModel) -> Result<bool, String> {
|
||||
fltk::dialog::message_default(&format!("{}:{}:{}", model.imei, model.sn, model.line_number));
|
||||
log::info!("Write Start");
|
||||
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)
|
||||
}
|
||||
|
||||
@ -42,15 +100,31 @@ impl WorkService {
|
||||
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> {
|
||||
if let Some(service) = &mut self.excel_service {
|
||||
if let Ok(model) = service.get_next_work_model() {
|
||||
self.config_model.current_line = service.get_current_line();
|
||||
return Some(model);
|
||||
} else { 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> {
|
||||
return if let Ok(sqlite_service) = SqliteService::new(db_path) {
|
||||
self.sqlite_service = sqlite_service;
|
||||
@ -63,6 +137,7 @@ impl WorkService {
|
||||
pub fn init_serial_service(&mut self, port_name: String) -> Result<bool, String> {
|
||||
return if let Ok(serial_service) = SerialService::new(&port_name) {
|
||||
self.serial_service = Some(*serial_service);
|
||||
self.config_model.last_com = port_name;
|
||||
Ok(true)
|
||||
} else {
|
||||
Err("Cant Init SerialService".to_string())
|
||||
@ -99,4 +174,12 @@ impl WorkService {
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
68
src/ui/main.fl
Normal file
68
src/ui/main.fl
Normal file
@ -0,0 +1,68 @@
|
||||
# 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