Compare commits
	
		
			9 Commits
		
	
	
		
			fd87bf7fce
			...
			master
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 906648bf93 | |||
| 8b1532d213 | |||
| 32cfe3d7df | |||
| c5d17ba613 | |||
| eff2d8a7af | |||
| 727249692b | |||
| 969e2c2d5e | |||
| 410a2ad5e1 | |||
| 85939e7fc4 | 
							
								
								
									
										5
									
								
								.idea/inspectionProfiles/Project_Default.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								.idea/inspectionProfiles/Project_Default.xml
									
									
									
										generated
									
									
									
								
							@@ -1,6 +1,11 @@
 | 
			
		||||
<component name="InspectionProjectProfileManager">
 | 
			
		||||
  <profile version="1.0">
 | 
			
		||||
    <option name="myName" value="Project Default" />
 | 
			
		||||
    <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
 | 
			
		||||
      <Languages>
 | 
			
		||||
        <language minSize="168" name="Rust" />
 | 
			
		||||
      </Languages>
 | 
			
		||||
    </inspection_tool>
 | 
			
		||||
    <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
 | 
			
		||||
      <option name="ignoredPackages">
 | 
			
		||||
        <value>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,5 +16,5 @@ crossbeam = "0.8"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[package.metadata.windows]
 | 
			
		||||
link-args=["/SUBSYSTEM:WINDOWS"]
 | 
			
		||||
subsystem="windows"
 | 
			
		||||
link-args = ["/SUBSYSTEM:windows", "/ENTRY:mainCRTStartup"]
 | 
			
		||||
subsystem = "windows"
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
use crate::download_wrapper::DownloadError::JlinkNotFindError;
 | 
			
		||||
use anyhow::Error;
 | 
			
		||||
use std::path::{Path, PathBuf};
 | 
			
		||||
use std::fmt::Display;
 | 
			
		||||
use std::fs;
 | 
			
		||||
use std::io::Write;
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
use std::process::Command;
 | 
			
		||||
 | 
			
		||||
pub struct DownloadWrapper {
 | 
			
		||||
@@ -18,13 +20,14 @@ pub enum DownloadType {
 | 
			
		||||
    Rail,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ToString for DownloadType {
 | 
			
		||||
    fn to_string(&self) -> String {
 | 
			
		||||
        match self {
 | 
			
		||||
impl Display for DownloadType {
 | 
			
		||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        let str = match self {
 | 
			
		||||
            DownloadType::Bootloader => "BootLoader".to_string(),
 | 
			
		||||
            DownloadType::App => "App".to_string(),
 | 
			
		||||
            DownloadType::Rail => "Rail".to_string(),
 | 
			
		||||
        }
 | 
			
		||||
        };
 | 
			
		||||
        write!(f, "{}", str)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -36,17 +39,32 @@ pub enum DownloadError {
 | 
			
		||||
    DownloadBootloaderError,
 | 
			
		||||
    DownloadAppError,
 | 
			
		||||
    DownloadRailError,
 | 
			
		||||
    NoLabel,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for DownloadWrapper {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        let config_str = fs::read_to_string("config.json").unwrap();
 | 
			
		||||
        let config: serde_json::Value = serde_json::from_str(&config_str).unwrap();
 | 
			
		||||
        let bootloader_name = config["bootloader_name"]
 | 
			
		||||
            .as_str()
 | 
			
		||||
            .unwrap_or("RAWM00-2-0-0_silicon-wisun_bootloader_D20241008.s37")
 | 
			
		||||
            .to_string();
 | 
			
		||||
        let app_name = config["app_name"]
 | 
			
		||||
            .as_str()
 | 
			
		||||
            .unwrap_or("RAWM00-2-0-0_silicon-combine-V1-D20241230-BZ.hex")
 | 
			
		||||
            .to_string();
 | 
			
		||||
        let rail_name = config["rail_name"]
 | 
			
		||||
            .as_str()
 | 
			
		||||
            .unwrap_or("rail_soc_railtest_sisdk(silabs).hex")
 | 
			
		||||
            .to_string();
 | 
			
		||||
        Self {
 | 
			
		||||
            commander_path: PathBuf::from(std::env::current_dir().unwrap())
 | 
			
		||||
                .join("commander/Simplicity Commander/commander.exe"),
 | 
			
		||||
            bin_path: PathBuf::from(std::env::current_dir().unwrap()).join("bin/"),
 | 
			
		||||
            bootloader_name: String::from("RAWM00-2-0-0_silicon-wisun_bootloader_D20241008.s37"),
 | 
			
		||||
            app_name: String::from("RAWM00-2-0-0_silicon-wisun_APP-V1_D20240927.s37"),
 | 
			
		||||
            rail_name: String::from("rail_soc_railtest_sisdk.s37"),
 | 
			
		||||
            bootloader_name,
 | 
			
		||||
            app_name,
 | 
			
		||||
            rail_name
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -64,10 +82,8 @@ impl DownloadWrapper {
 | 
			
		||||
            .output()
 | 
			
		||||
            .expect("Failed to execute command");
 | 
			
		||||
        if output.status.success() {
 | 
			
		||||
            let result_str  = String::from_utf8_lossy(&output.stdout).to_string();
 | 
			
		||||
            let result = result_str
 | 
			
		||||
                .split("\r\n")
 | 
			
		||||
                .collect::<Vec<&str>>();
 | 
			
		||||
            let result_str = String::from_utf8_lossy(&output.stdout).to_string();
 | 
			
		||||
            let result = result_str.split("\r\n").collect::<Vec<&str>>();
 | 
			
		||||
            let device_index_str: Vec<String> = result
 | 
			
		||||
                .iter()
 | 
			
		||||
                .filter(|&&str| str.starts_with("deviceCount"))
 | 
			
		||||
@@ -115,7 +131,7 @@ impl DownloadWrapper {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn erase(&self) -> Result<(), DownloadError> {
 | 
			
		||||
    pub fn erase(&self, label: Option<String>) -> Result<String, DownloadError> {
 | 
			
		||||
        let commander_path_str = self.commander_path.to_str().unwrap();
 | 
			
		||||
        let output = Command::new(commander_path_str)
 | 
			
		||||
            .arg("device")
 | 
			
		||||
@@ -125,9 +141,7 @@ impl DownloadWrapper {
 | 
			
		||||
            .output()
 | 
			
		||||
            .expect("Failed to execute command");
 | 
			
		||||
        let result_str = String::from_utf8_lossy(&output.stdout).to_string();
 | 
			
		||||
        let result = result_str
 | 
			
		||||
            .split("\r\n")
 | 
			
		||||
            .collect::<Vec<&str>>();
 | 
			
		||||
        let result = result_str.split("\r\n").collect::<Vec<&str>>();
 | 
			
		||||
        if !result
 | 
			
		||||
            .iter()
 | 
			
		||||
            .filter(|&&str| str.trim().starts_with("ERROR"))
 | 
			
		||||
@@ -141,20 +155,30 @@ impl DownloadWrapper {
 | 
			
		||||
        {
 | 
			
		||||
            Err(DownloadError::EraseError)
 | 
			
		||||
        } else {
 | 
			
		||||
            Ok(())
 | 
			
		||||
            let Some(label) = label else {
 | 
			
		||||
                return Err(DownloadError::NoLabel);
 | 
			
		||||
            };
 | 
			
		||||
            match self.save_log(label, result_str.clone()) {
 | 
			
		||||
                Ok(_) => Ok(result_str),
 | 
			
		||||
                Err(_) => Err(DownloadError::DownloadBootloaderError),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn download(&self, download_type: DownloadType) -> Result<(), DownloadError> {
 | 
			
		||||
    pub fn download(
 | 
			
		||||
        &self,
 | 
			
		||||
        download_type: DownloadType,
 | 
			
		||||
        label: Option<String>,
 | 
			
		||||
    ) -> Result<String, DownloadError> {
 | 
			
		||||
        let mut binding: PathBuf;
 | 
			
		||||
        match download_type {
 | 
			
		||||
            DownloadType::Bootloader=> {
 | 
			
		||||
            DownloadType::Bootloader => {
 | 
			
		||||
                binding = self.bin_path.join(&self.bootloader_name);
 | 
			
		||||
            }
 | 
			
		||||
            DownloadType::App=>{
 | 
			
		||||
            DownloadType::App => {
 | 
			
		||||
                binding = self.bin_path.join(&self.app_name);
 | 
			
		||||
            }
 | 
			
		||||
            DownloadType::Rail=>{
 | 
			
		||||
            DownloadType::Rail => {
 | 
			
		||||
                binding = self.bin_path.join(&self.rail_name);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -169,9 +193,7 @@ impl DownloadWrapper {
 | 
			
		||||
            .output()
 | 
			
		||||
            .expect("Failed to execute command");
 | 
			
		||||
        let result_str = String::from_utf8_lossy(&output.stdout).to_string();
 | 
			
		||||
        let result = result_str
 | 
			
		||||
            .split("\r\n")
 | 
			
		||||
            .collect::<Vec<&str>>();
 | 
			
		||||
        let result = result_str.split("\r\n").collect::<Vec<&str>>();
 | 
			
		||||
        println!("{:?}", result);
 | 
			
		||||
        if !result
 | 
			
		||||
            .iter()
 | 
			
		||||
@@ -179,30 +201,41 @@ impl DownloadWrapper {
 | 
			
		||||
            .collect::<Vec<&&str>>()
 | 
			
		||||
            .is_empty()
 | 
			
		||||
            || result
 | 
			
		||||
            .iter()
 | 
			
		||||
            .filter(|&&str| str.trim().contains("successfully"))
 | 
			
		||||
            .collect::<Vec<&&str>>()
 | 
			
		||||
            .is_empty()
 | 
			
		||||
                .iter()
 | 
			
		||||
                .filter(|&&str| str.trim().contains("successfully"))
 | 
			
		||||
                .collect::<Vec<&&str>>()
 | 
			
		||||
                .is_empty()
 | 
			
		||||
        {
 | 
			
		||||
            Err(DownloadError::DownloadBootloaderError)
 | 
			
		||||
        } else {
 | 
			
		||||
            Ok(())
 | 
			
		||||
            let Some(label) = label else {
 | 
			
		||||
                return Err(DownloadError::NoLabel);
 | 
			
		||||
            };
 | 
			
		||||
            match self.save_log(label, result_str.clone()) {
 | 
			
		||||
                Ok(_) => Ok(result_str),
 | 
			
		||||
                Err(_) => Err(DownloadError::DownloadBootloaderError),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn download_app(&self) -> Result<bool, DownloadError> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn download_rail(&self) -> Result<bool, DownloadError> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    fn save_log(&self, label: String, log: String) -> Result<bool, DownloadError> {
 | 
			
		||||
        if !fs::exists("./log").unwrap() {
 | 
			
		||||
            fs::create_dir("./log").expect("Cant Create Log Folder");
 | 
			
		||||
        }
 | 
			
		||||
        let mut file = fs::OpenOptions::new()
 | 
			
		||||
            .create(true)
 | 
			
		||||
            .append(true)
 | 
			
		||||
            .open(format!("./log/{label}.txt"))
 | 
			
		||||
            .expect("file not found");
 | 
			
		||||
        writeln!(file, "{}", log).expect("write failed");
 | 
			
		||||
        Ok(true)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod test {
 | 
			
		||||
    use crate::download_wrapper::DownloadWrapper;
 | 
			
		||||
    use crate::download_wrapper::DownloadType;
 | 
			
		||||
    use crate::download_wrapper::DownloadWrapper;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_download_wrapper() {
 | 
			
		||||
@@ -232,28 +265,28 @@ mod test {
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_erase_device() {
 | 
			
		||||
        let dw = DownloadWrapper::new();
 | 
			
		||||
        let result = dw.erase();
 | 
			
		||||
        let result = dw.erase(Some("111".to_string()));
 | 
			
		||||
        assert_eq!(result.is_ok(), true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_download_bootloader(){
 | 
			
		||||
    fn test_download_bootloader() {
 | 
			
		||||
        let dw = DownloadWrapper::new();
 | 
			
		||||
        let result = dw.download(DownloadType::Bootloader);
 | 
			
		||||
        let result = dw.download(DownloadType::Bootloader, Some("111".to_string()));
 | 
			
		||||
        assert_eq!(result.is_ok(), true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_download_app(){
 | 
			
		||||
    fn test_download_app() {
 | 
			
		||||
        let dw = DownloadWrapper::new();
 | 
			
		||||
        let result = dw.download(DownloadType::App);
 | 
			
		||||
        let result = dw.download(DownloadType::App, Some("111".to_string()));
 | 
			
		||||
        assert_eq!(result.is_ok(), true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_download_rail(){
 | 
			
		||||
    fn test_download_rail() {
 | 
			
		||||
        let dw = DownloadWrapper::new();
 | 
			
		||||
        let result = dw.download(DownloadType::Rail);
 | 
			
		||||
        let result = dw.download(DownloadType::Rail, Some("111".to_string()));
 | 
			
		||||
        assert_eq!(result.is_ok(), true);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										368
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										368
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -1,19 +1,26 @@
 | 
			
		||||
#![windows_subsystem = "windows"]
 | 
			
		||||
 | 
			
		||||
mod download_wrapper;
 | 
			
		||||
mod mes_service;
 | 
			
		||||
 | 
			
		||||
use std::any::Any;
 | 
			
		||||
use std::fs;
 | 
			
		||||
use crate::mes_service::MesService;
 | 
			
		||||
use crossbeam::channel;
 | 
			
		||||
use std::sync::{Arc, Mutex, LazyLock};
 | 
			
		||||
use crossbeam::channel::Sender;
 | 
			
		||||
use iced::widget::{button, checkbox, column, container, radio, row, text_editor, text_input};
 | 
			
		||||
use iced::{event, window, Element, Event, Length, Subscription, Task, time};
 | 
			
		||||
use download_wrapper::DownloadType;
 | 
			
		||||
use iced::application::Title;
 | 
			
		||||
use iced::widget::progress_bar::Style;
 | 
			
		||||
use iced::widget::text_editor::Action::Scroll;
 | 
			
		||||
use iced::widget::text_editor::Edit;
 | 
			
		||||
use iced::widget::{
 | 
			
		||||
    button, checkbox, column, container, progress_bar, radio, row, text_editor, text_input,
 | 
			
		||||
};
 | 
			
		||||
use iced::{event, time, window, Border, Color, Element, Event, Length, Subscription, Task};
 | 
			
		||||
use serde_json::Map;
 | 
			
		||||
use download_wrapper::DownloadType;
 | 
			
		||||
use crate::mes_service::MesService;
 | 
			
		||||
use std::any::Any;
 | 
			
		||||
use std::fs;
 | 
			
		||||
use std::io::Write;
 | 
			
		||||
use std::sync::{Arc, LazyLock, Mutex};
 | 
			
		||||
use std::thread::sleep;
 | 
			
		||||
 | 
			
		||||
pub fn main() -> iced::Result {
 | 
			
		||||
    iced::application("WisunDownload V0.1", MainWindow::update, MainWindow::view)
 | 
			
		||||
@@ -23,9 +30,7 @@ pub fn main() -> iced::Result {
 | 
			
		||||
        .run()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static logs: LazyLock<Arc<Mutex<Vec<String>>>> = LazyLock::new(|| {
 | 
			
		||||
    Arc::new(Mutex::new(Vec::new()))
 | 
			
		||||
});
 | 
			
		||||
static LOGS: LazyLock<Arc<Mutex<Vec<String>>>> = LazyLock::new(|| Arc::new(Mutex::new(Vec::new())));
 | 
			
		||||
 | 
			
		||||
struct MainWindow {
 | 
			
		||||
    is_online: bool,
 | 
			
		||||
@@ -35,19 +40,21 @@ struct MainWindow {
 | 
			
		||||
    log_content: text_editor::Content,
 | 
			
		||||
    sender: Sender<Message>,
 | 
			
		||||
    receiver: channel::Receiver<Message>,
 | 
			
		||||
    result_background: Color
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for MainWindow {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        let (sender, receiver) =channel::unbounded();
 | 
			
		||||
        let (sender, receiver) = channel::unbounded();
 | 
			
		||||
        Self {
 | 
			
		||||
            is_online: true,
 | 
			
		||||
            mysql_config: MysqlConfig::default(),
 | 
			
		||||
            selection: None,
 | 
			
		||||
            label: String::new(),
 | 
			
		||||
            log_content: text_editor::Content::default(),
 | 
			
		||||
            result_background: Color::from_rgb8(255,255,255),
 | 
			
		||||
            sender,
 | 
			
		||||
            receiver
 | 
			
		||||
            receiver,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -76,21 +83,23 @@ enum Message {
 | 
			
		||||
    AddLog(String),
 | 
			
		||||
    LogContentChanged(text_editor::Action),
 | 
			
		||||
    SaveConfig,
 | 
			
		||||
    DownloadEnd(bool),
 | 
			
		||||
    DownloadEnd((String, bool)),
 | 
			
		||||
    WindowEvent(Event),
 | 
			
		||||
    ClearLog,
 | 
			
		||||
    Tick,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn add_log<'a>(msg: String) {
 | 
			
		||||
    let time_now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
 | 
			
		||||
    let really_msg = format!("{time_now} [Info]: {msg}");
 | 
			
		||||
    logs.lock().unwrap().push(really_msg);
 | 
			
		||||
    LOGS.lock().unwrap().push(really_msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl MainWindow {
 | 
			
		||||
    fn update(&mut self, message: Message) -> Task<Message> {
 | 
			
		||||
        match message {
 | 
			
		||||
            Message::Start() => {
 | 
			
		||||
                self.result_background = Color::from_rgb8(255,255,255);
 | 
			
		||||
                self.start(self.sender.clone());
 | 
			
		||||
                Task::none()
 | 
			
		||||
            }
 | 
			
		||||
@@ -130,73 +139,85 @@ impl MainWindow {
 | 
			
		||||
                self.is_online = is_online;
 | 
			
		||||
                Task::none()
 | 
			
		||||
            }
 | 
			
		||||
            Message::ClearLog => {
 | 
			
		||||
                self.log_content.perform(text_editor::Action::SelectAll);
 | 
			
		||||
                self.log_content
 | 
			
		||||
                    .perform(text_editor::Action::Edit(Edit::Backspace));
 | 
			
		||||
                Task::none()
 | 
			
		||||
            }
 | 
			
		||||
            Message::AddLog(log) => {
 | 
			
		||||
                for c in log.chars() {
 | 
			
		||||
                    self.log_content.perform(text_editor::Action::Edit(Edit::Insert(c)))
 | 
			
		||||
                    self.log_content
 | 
			
		||||
                        .perform(text_editor::Action::Edit(Edit::Insert(c)))
 | 
			
		||||
                }
 | 
			
		||||
                self.log_content.perform(text_editor::Action::Edit(Edit::Enter));
 | 
			
		||||
                self.log_content
 | 
			
		||||
                    .perform(text_editor::Action::Edit(Edit::Enter));
 | 
			
		||||
                let line_size = self.log_content.lines().count();
 | 
			
		||||
                self.log_content.perform(Scroll { lines: line_size as i32 });
 | 
			
		||||
                self.log_content.perform(Scroll {
 | 
			
		||||
                    lines: line_size as i32,
 | 
			
		||||
                });
 | 
			
		||||
                Task::none()
 | 
			
		||||
            }
 | 
			
		||||
            Message::Tick => {
 | 
			
		||||
                for log in logs.lock().unwrap().iter() {
 | 
			
		||||
                for log in LOGS.lock().unwrap().iter() {
 | 
			
		||||
                    for c in log.chars() {
 | 
			
		||||
                        self.log_content.perform(text_editor::Action::Edit(Edit::Insert(c)))
 | 
			
		||||
                        self.log_content
 | 
			
		||||
                            .perform(text_editor::Action::Edit(Edit::Insert(c)))
 | 
			
		||||
                    }
 | 
			
		||||
                    self.log_content.perform(text_editor::Action::Edit(Edit::Enter));
 | 
			
		||||
                    self.log_content
 | 
			
		||||
                        .perform(text_editor::Action::Edit(Edit::Enter));
 | 
			
		||||
                    let line_size = self.log_content.lines().count();
 | 
			
		||||
                    self.log_content.perform(Scroll { lines: line_size as i32 });
 | 
			
		||||
                    self.log_content.perform(Scroll {
 | 
			
		||||
                        lines: line_size as i32,
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
                logs.lock().unwrap().clear();
 | 
			
		||||
                LOGS.lock().unwrap().clear();
 | 
			
		||||
 | 
			
		||||
                match self.receiver.try_recv() {
 | 
			
		||||
                    Ok(event) => {
 | 
			
		||||
                        match event{
 | 
			
		||||
                            Message::DownloadEnd(res)=>{
 | 
			
		||||
                                if res{
 | 
			
		||||
                                    add_log("下载成功 By Ui Thread".to_string());
 | 
			
		||||
                                }else{
 | 
			
		||||
                                    add_log("下载失败 By Ui Thread".to_string());
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            _=>{
 | 
			
		||||
                            }
 | 
			
		||||
                    Ok(event) => match event {
 | 
			
		||||
                        Message::DownloadEnd((label, res)) => {
 | 
			
		||||
                            let _ = self.update(Message::DownloadEnd((label, res)));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    Err(channel::TryRecvError::Empty) => {
 | 
			
		||||
                    }
 | 
			
		||||
                        _ => {}
 | 
			
		||||
                    },
 | 
			
		||||
                    Err(channel::TryRecvError::Empty) => {}
 | 
			
		||||
                    Err(channel::TryRecvError::Disconnected) => {
 | 
			
		||||
                        println!("Disconnected");
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
                Task::none()
 | 
			
		||||
            }
 | 
			
		||||
            Message::LogContentChanged(action) => {
 | 
			
		||||
                match action{
 | 
			
		||||
                    Scroll { lines } => {
 | 
			
		||||
                        self.log_content.perform(Scroll { lines });
 | 
			
		||||
                        Task::none()
 | 
			
		||||
                    }
 | 
			
		||||
                    _=>{
 | 
			
		||||
                        Task::none()
 | 
			
		||||
                    }
 | 
			
		||||
            Message::LogContentChanged(action) => match action {
 | 
			
		||||
                Scroll { lines } => {
 | 
			
		||||
                    self.log_content.perform(Scroll { lines });
 | 
			
		||||
                    Task::none()
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Message::DownloadEnd(res)=>{
 | 
			
		||||
                _ => Task::none(),
 | 
			
		||||
            },
 | 
			
		||||
            Message::DownloadEnd((label, res)) => {
 | 
			
		||||
                if !fs::exists("./uilog").unwrap() {
 | 
			
		||||
                    fs::create_dir("./uilog").expect("Cant Create UiLog Folder");
 | 
			
		||||
                }
 | 
			
		||||
                let mut file = fs::OpenOptions::new()
 | 
			
		||||
                    .create(true)
 | 
			
		||||
                    .append(true)
 | 
			
		||||
                    .open(format!("./uilog/{label}.txt"))
 | 
			
		||||
                    .unwrap();
 | 
			
		||||
                writeln!(file, "{:?}", self.log_content.text().clone()).unwrap();
 | 
			
		||||
                if res{
 | 
			
		||||
                    add_log("下载成功 By Ui Thread".to_string());
 | 
			
		||||
                    self.result_background = Color::from_rgb8(0, 255,0);
 | 
			
		||||
                }else{
 | 
			
		||||
                    add_log("下载失败 By Ui Thread".to_string());
 | 
			
		||||
                    self.result_background = Color::from_rgb8(255, 0,0);
 | 
			
		||||
                }
 | 
			
		||||
                self.label = "".to_string();
 | 
			
		||||
                Task::none()
 | 
			
		||||
            }
 | 
			
		||||
            Message::WindowEvent(event) => {
 | 
			
		||||
                //println!("{:?}", event);
 | 
			
		||||
                if let Event::Window(window::Event::Opened { position, size }) = event {
 | 
			
		||||
                if let Event::Window(window::Event::Opened { position: _position, size: _size }) = event {
 | 
			
		||||
                    println!("Opened");
 | 
			
		||||
                    self.read_config();
 | 
			
		||||
                    return Task::none();
 | 
			
		||||
                    return Task::none()
 | 
			
		||||
                };
 | 
			
		||||
                if let Event::Window(window::Event::CloseRequested) = event {
 | 
			
		||||
                    println!("Request Close");
 | 
			
		||||
@@ -205,53 +226,59 @@ impl MainWindow {
 | 
			
		||||
                };
 | 
			
		||||
                Task::none()
 | 
			
		||||
            }
 | 
			
		||||
            _ => { Task::none() }
 | 
			
		||||
            _ => Task::none(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn view(&self) -> Element<Message> {
 | 
			
		||||
        let ip_input = text_input(
 | 
			
		||||
            "IP Address",
 | 
			
		||||
            &self.mysql_config.ip,
 | 
			
		||||
        ).on_input(Message::IpChanged);
 | 
			
		||||
        let port_input = text_input(
 | 
			
		||||
            "Port",
 | 
			
		||||
            &self.mysql_config.port,
 | 
			
		||||
        ).on_input(Message::PortChanged);
 | 
			
		||||
        let username_input = text_input(
 | 
			
		||||
            "Username",
 | 
			
		||||
            &self.mysql_config.username,
 | 
			
		||||
        ).on_input(Message::UsernameChanged);
 | 
			
		||||
        let password_input = text_input(
 | 
			
		||||
            "Password",
 | 
			
		||||
            &self.mysql_config.password,
 | 
			
		||||
        ).on_input(Message::PasswordChanged);
 | 
			
		||||
        let database_input = text_input(
 | 
			
		||||
            "Database",
 | 
			
		||||
            &self.mysql_config.database,
 | 
			
		||||
        ).on_input(Message::DatabaseChanged);
 | 
			
		||||
        let work_order_input = text_input(
 | 
			
		||||
            "WorkOrder",
 | 
			
		||||
            &self.mysql_config.work_order,
 | 
			
		||||
        ).on_input(Message::WorkOrderChanged);
 | 
			
		||||
        let label_input = text_input(
 | 
			
		||||
            "label",
 | 
			
		||||
            &self.label,
 | 
			
		||||
        ).on_input(Message::LabelChanged).on_submit(Message::Start()).width(Length::Fill);
 | 
			
		||||
        let ip_input = text_input("IP Address", &self.mysql_config.ip).on_input(Message::IpChanged);
 | 
			
		||||
        let port_input = text_input("Port", &self.mysql_config.port).on_input(Message::PortChanged);
 | 
			
		||||
        let username_input =
 | 
			
		||||
            text_input("Username", &self.mysql_config.username).on_input(Message::UsernameChanged);
 | 
			
		||||
        let password_input =
 | 
			
		||||
            text_input("Password", &self.mysql_config.password).on_input(Message::PasswordChanged);
 | 
			
		||||
        let database_input =
 | 
			
		||||
            text_input("Database", &self.mysql_config.database).on_input(Message::DatabaseChanged);
 | 
			
		||||
        let work_order_input = text_input("WorkOrder", &self.mysql_config.work_order)
 | 
			
		||||
            .on_input(Message::WorkOrderChanged);
 | 
			
		||||
        let label_input = text_input("label", &self.label)
 | 
			
		||||
            .on_input(Message::LabelChanged)
 | 
			
		||||
            .on_submit(Message::Start())
 | 
			
		||||
            .width(Length::Fill);
 | 
			
		||||
        let content = column![
 | 
			
		||||
            row![ip_input, port_input].spacing(5),
 | 
			
		||||
            row![username_input, password_input].spacing(5),
 | 
			
		||||
            row![database_input, work_order_input].spacing(5),
 | 
			
		||||
            row![
 | 
			
		||||
                radio("BootLoader", DownloadType::Bootloader,self.selection,Message::TypeSelected),
 | 
			
		||||
                radio("App", DownloadType::App,self.selection,Message::TypeSelected),
 | 
			
		||||
                radio("Cal", DownloadType::Rail,self.selection,Message::TypeSelected),
 | 
			
		||||
                checkbox("online", self.is_online).on_toggle(Message::OnlineChecked)
 | 
			
		||||
            ].spacing(10),
 | 
			
		||||
            row![label_input,button("Start").on_press(Message::Start())].spacing(10),
 | 
			
		||||
            text_editor(&self.log_content).on_action(Message::LogContentChanged).height(Length::Fill)
 | 
			
		||||
        ].spacing(10).padding(5);
 | 
			
		||||
 | 
			
		||||
                radio(
 | 
			
		||||
                    "App",
 | 
			
		||||
                    DownloadType::App,
 | 
			
		||||
                    self.selection,
 | 
			
		||||
                    Message::TypeSelected
 | 
			
		||||
                ),
 | 
			
		||||
                radio(
 | 
			
		||||
                    "Cal",
 | 
			
		||||
                    DownloadType::Rail,
 | 
			
		||||
                    self.selection,
 | 
			
		||||
                    Message::TypeSelected
 | 
			
		||||
                ),
 | 
			
		||||
                checkbox("online", self.is_online).on_toggle(Message::OnlineChecked),
 | 
			
		||||
            ]
 | 
			
		||||
            .spacing(10),
 | 
			
		||||
            row![label_input, button("Start").on_press(Message::Start())].spacing(10),
 | 
			
		||||
            text_editor(&self.log_content)
 | 
			
		||||
                .on_action(Message::LogContentChanged)
 | 
			
		||||
                .height(Length::Fill),
 | 
			
		||||
            progress_bar(0.0..=100.0, 0.0).style(|_|{
 | 
			
		||||
                Style {
 | 
			
		||||
                    background: self.result_background.into(),
 | 
			
		||||
                    bar: self.result_background.into(),
 | 
			
		||||
                    border: Border::default(),
 | 
			
		||||
                }
 | 
			
		||||
            }),
 | 
			
		||||
        ]
 | 
			
		||||
        .spacing(10)
 | 
			
		||||
        .padding(5);
 | 
			
		||||
        let container = container(content).padding(20);
 | 
			
		||||
        container.into()
 | 
			
		||||
    }
 | 
			
		||||
@@ -259,144 +286,192 @@ impl MainWindow {
 | 
			
		||||
    fn subscription(&self) -> Subscription<Message> {
 | 
			
		||||
        Subscription::batch(vec![
 | 
			
		||||
            event::listen().map(Message::WindowEvent),
 | 
			
		||||
            time::every(time::Duration::from_millis(50))
 | 
			
		||||
                .map(|_| Message::Tick)
 | 
			
		||||
            time::every(time::Duration::from_millis(50)).map(|_| Message::Tick),
 | 
			
		||||
        ])
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn start(&mut self, sender: Sender<Message>) -> (){
 | 
			
		||||
    fn start(&mut self, sender: Sender<Message>) -> () {
 | 
			
		||||
        let mes_config = self.mysql_config.clone();
 | 
			
		||||
        let label = self.label.clone();
 | 
			
		||||
        let mut label = self.label.clone();
 | 
			
		||||
        let download_type: DownloadType = self.selection.unwrap();
 | 
			
		||||
        let online = self.is_online.clone();
 | 
			
		||||
        if label == ""{
 | 
			
		||||
        if label == "" {
 | 
			
		||||
            add_log("请输入Label".to_string());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        label = label.replace(":", "");
 | 
			
		||||
        label = label.to_uppercase();
 | 
			
		||||
        add_log("Label: ".to_string() + label.as_str());
 | 
			
		||||
        std::thread::spawn(move || {
 | 
			
		||||
            sleep(std::time::Duration::from_secs(5));
 | 
			
		||||
            let mut download_wrapper = download_wrapper::DownloadWrapper::new();
 | 
			
		||||
            let mut mes_service: MesService;
 | 
			
		||||
            sender.send(Message::ClearLog).unwrap();
 | 
			
		||||
            if online {
 | 
			
		||||
                add_log("当前为在线模式, 正在连接数据库".to_string());
 | 
			
		||||
                match MesService::new(mes_config.ip.clone(), mes_config.port.clone(), mes_config.username.clone(), mes_config.password.clone(), mes_config.database.clone()){
 | 
			
		||||
                match MesService::new(
 | 
			
		||||
                    mes_config.ip.clone(),
 | 
			
		||||
                    mes_config.port.clone(),
 | 
			
		||||
                    mes_config.username.clone(),
 | 
			
		||||
                    mes_config.password.clone(),
 | 
			
		||||
                    mes_config.database.clone(),
 | 
			
		||||
                ) {
 | 
			
		||||
                    Ok(service) => mes_service = service,
 | 
			
		||||
                    Err(e) =>{
 | 
			
		||||
                    Err(e) => {
 | 
			
		||||
                        add_log(format!("连接数据库失败: {:?}", e.to_string()));
 | 
			
		||||
                        sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                        sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                add_log("连接成功".to_string());
 | 
			
		||||
                // match mes_service.get_order_number(mes_config.work_order.clone()){
 | 
			
		||||
                //     Ok(batch) => {
 | 
			
		||||
                //         label = batch + &label[label.len() - 6..];
 | 
			
		||||
                //         add_log("获取订单号成功".to_string());
 | 
			
		||||
                //     },
 | 
			
		||||
                //     Err(e) =>{
 | 
			
		||||
                //         add_log(e.to_string());
 | 
			
		||||
                //         sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                //         return;
 | 
			
		||||
                //     }
 | 
			
		||||
                // }
 | 
			
		||||
                add_log("正在过站检测".to_string());
 | 
			
		||||
                let check_result = mes_service.check_station(mes_config.work_order.clone(), label.clone(), download_type);
 | 
			
		||||
                let check_result = mes_service.check_station(
 | 
			
		||||
                    mes_config.work_order.clone(),
 | 
			
		||||
                    label.clone(),
 | 
			
		||||
                    download_type,
 | 
			
		||||
                );
 | 
			
		||||
                if let Err(res) = check_result {
 | 
			
		||||
                    add_log(format!("过站检测失败: {:?}", res.to_string()));
 | 
			
		||||
                    sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                    sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                    return;
 | 
			
		||||
                } else if let Ok(res) = check_result {
 | 
			
		||||
                    if !res {
 | 
			
		||||
                        add_log("过站检测失败".to_string());
 | 
			
		||||
                        sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                        sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    add_log("过站检测成功".to_string());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            add_log("正在检查JLink连接".to_string());
 | 
			
		||||
            if let Err(e) = download_wrapper.check_jlink() {
 | 
			
		||||
            if let Err(_) = download_wrapper.check_jlink() {
 | 
			
		||||
                add_log("JLink检查失败, 请检查是否安装驱动或连接是否异常".to_string());
 | 
			
		||||
                sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            add_log("JLink检查成功".to_string());
 | 
			
		||||
            add_log("正在检查设备连接".to_string());
 | 
			
		||||
            if let Err(e) = download_wrapper.check_device() {
 | 
			
		||||
            if let Err(_) = download_wrapper.check_device() {
 | 
			
		||||
                add_log("设备检查失败, 请检查设备是否连接".to_string());
 | 
			
		||||
                sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            add_log("设备检查成功".to_string());
 | 
			
		||||
            match download_type {
 | 
			
		||||
                DownloadType::Bootloader =>{
 | 
			
		||||
                DownloadType::Bootloader => {}
 | 
			
		||||
                DownloadType::App => {
 | 
			
		||||
                    add_log("正在擦除Flash".to_string());
 | 
			
		||||
                    if let Err(e) = download_wrapper.erase(){
 | 
			
		||||
                    if let Err(_) = download_wrapper.erase(Some(label.clone())) {
 | 
			
		||||
                        add_log("擦除失败".to_string());
 | 
			
		||||
                        sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                        sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    add_log("擦除成功".to_string());
 | 
			
		||||
                    add_log("正在下载BootLoader".to_string());
 | 
			
		||||
                    if let Err(e) = download_wrapper.download(download_type){
 | 
			
		||||
                    if let Err(_) =
 | 
			
		||||
                        download_wrapper.download(DownloadType::Bootloader, Some(label.clone()))
 | 
			
		||||
                    {
 | 
			
		||||
                        add_log("下载BootLoader失败".to_string());
 | 
			
		||||
                        sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                        sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    add_log("下载成功".to_string());
 | 
			
		||||
                }
 | 
			
		||||
                DownloadType::App =>{
 | 
			
		||||
                    add_log("下载BootLoader成功".to_string());
 | 
			
		||||
                    add_log("正在下载App".to_string());
 | 
			
		||||
                    if let Err(e) = download_wrapper.download(download_type){
 | 
			
		||||
                    if let Err(_) = download_wrapper.download(download_type, Some(label.clone())) {
 | 
			
		||||
                        add_log("下载App失败".to_string());
 | 
			
		||||
                        sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                        sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    add_log("下载成功".to_string());
 | 
			
		||||
                    add_log("下载App成功".to_string());
 | 
			
		||||
                }
 | 
			
		||||
                DownloadType::Rail=>{
 | 
			
		||||
                DownloadType::Rail => {
 | 
			
		||||
                    add_log("正在下载Rail".to_string());
 | 
			
		||||
                    if let Err(e) = download_wrapper.download(download_type){
 | 
			
		||||
                    if let Err(_) = download_wrapper.download(download_type, Some(label.clone())) {
 | 
			
		||||
                        add_log("下载Rail失败".to_string());
 | 
			
		||||
                        sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                        sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    add_log("下载成功".to_string());
 | 
			
		||||
                    add_log("下载Rail成功".to_string());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return if online {
 | 
			
		||||
                match MesService::new(mes_config.ip.clone(), mes_config.port.clone(), mes_config.username.clone(), mes_config.password.clone(), mes_config.database.clone()){
 | 
			
		||||
                match MesService::new(
 | 
			
		||||
                    mes_config.ip.clone(),
 | 
			
		||||
                    mes_config.port.clone(),
 | 
			
		||||
                    mes_config.username.clone(),
 | 
			
		||||
                    mes_config.password.clone(),
 | 
			
		||||
                    mes_config.database.clone(),
 | 
			
		||||
                ) {
 | 
			
		||||
                    Ok(service) => mes_service = service,
 | 
			
		||||
                    Err(e) =>{
 | 
			
		||||
                    Err(e) => {
 | 
			
		||||
                        add_log(format!("连接数据库失败: {:?}", e.to_string()));
 | 
			
		||||
                        sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                        sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                }                add_log("正在上传数据".to_string());
 | 
			
		||||
                let update_result = mes_service.update_station(mes_config.work_order, label, download_type);
 | 
			
		||||
                }
 | 
			
		||||
                add_log("正在上传数据".to_string());
 | 
			
		||||
                let update_result =
 | 
			
		||||
                    mes_service.update_station(mes_config.work_order, label.clone(), download_type);
 | 
			
		||||
                if let Err(e) = update_result {
 | 
			
		||||
                    add_log(format!("上传失败: {:?}", e.to_string()));
 | 
			
		||||
                    sender.send(Message::DownloadEnd(false)).unwrap();
 | 
			
		||||
                    sender.send(Message::DownloadEnd((label, false))).unwrap();
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                sender.send(Message::DownloadEnd(true)).unwrap();
 | 
			
		||||
                sender.send(Message::DownloadEnd((label, true))).unwrap();
 | 
			
		||||
                return;
 | 
			
		||||
            } else {
 | 
			
		||||
                add_log("当前为离线模式".to_string());
 | 
			
		||||
                sender.send(Message::DownloadEnd(true)).unwrap();
 | 
			
		||||
                sender.send(Message::DownloadEnd((label, true))).unwrap();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            };
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn save_config(&mut self){
 | 
			
		||||
    fn save_config(&mut self) {
 | 
			
		||||
        let mut config = Map::new();
 | 
			
		||||
        config.insert("ip".to_string(), self.mysql_config.ip.clone().into());
 | 
			
		||||
        config.insert("port".to_string(), self.mysql_config.port.clone().into());
 | 
			
		||||
        config.insert("username".to_string(), self.mysql_config.username.clone().into());
 | 
			
		||||
        config.insert("password".to_string(), self.mysql_config.password.clone().into());
 | 
			
		||||
        config.insert("database".to_string(), self.mysql_config.database.clone().into());
 | 
			
		||||
        config.insert("work_order".to_string(), self.mysql_config.work_order.clone().into());
 | 
			
		||||
        config.insert(
 | 
			
		||||
            "username".to_string(),
 | 
			
		||||
            self.mysql_config.username.clone().into(),
 | 
			
		||||
        );
 | 
			
		||||
        config.insert(
 | 
			
		||||
            "password".to_string(),
 | 
			
		||||
            self.mysql_config.password.clone().into(),
 | 
			
		||||
        );
 | 
			
		||||
        config.insert(
 | 
			
		||||
            "database".to_string(),
 | 
			
		||||
            self.mysql_config.database.clone().into(),
 | 
			
		||||
        );
 | 
			
		||||
        config.insert(
 | 
			
		||||
            "work_order".to_string(),
 | 
			
		||||
            self.mysql_config.work_order.clone().into(),
 | 
			
		||||
        );
 | 
			
		||||
        config.insert("is_online".to_string(), self.is_online.clone().into());
 | 
			
		||||
        config.insert("selection".to_string(), self.selection.unwrap().to_string().into());
 | 
			
		||||
        config.insert(
 | 
			
		||||
            "selection".to_string(),
 | 
			
		||||
            self.selection.unwrap().to_string().into(),
 | 
			
		||||
        );
 | 
			
		||||
        let config_str = serde_json::to_string(&config).unwrap();
 | 
			
		||||
        fs::write("config.json", config_str).unwrap();
 | 
			
		||||
        fs::write("./config.json", config_str).unwrap();
 | 
			
		||||
    }
 | 
			
		||||
    fn read_config(&mut self){
 | 
			
		||||
        if !fs::exists("config.json").unwrap(){
 | 
			
		||||
    fn read_config(&mut self) {
 | 
			
		||||
        if !fs::exists("./config.json").unwrap() {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        let config_str = fs::read_to_string("config.json").unwrap();
 | 
			
		||||
        let config_str = fs::read_to_string("./config.json").unwrap();
 | 
			
		||||
        let config: Map<String, serde_json::Value> = serde_json::from_str(&config_str).unwrap();
 | 
			
		||||
        self.mysql_config.ip = config["ip"].as_str().unwrap().to_string();
 | 
			
		||||
        self.mysql_config.port = config["port"].as_str().unwrap().to_string();
 | 
			
		||||
@@ -405,24 +480,19 @@ impl MainWindow {
 | 
			
		||||
        self.mysql_config.database = config["database"].as_str().unwrap().to_string();
 | 
			
		||||
        self.mysql_config.work_order = config["work_order"].as_str().unwrap().to_string();
 | 
			
		||||
        self.is_online = config["is_online"].as_bool().unwrap();
 | 
			
		||||
        match config["selection"].as_str().unwrap(){
 | 
			
		||||
            "BootLoader"=>{
 | 
			
		||||
        match config["selection"].as_str().unwrap() {
 | 
			
		||||
            "BootLoader" => {
 | 
			
		||||
                self.selection = Some(DownloadType::Bootloader);
 | 
			
		||||
            }
 | 
			
		||||
            "App"=>{
 | 
			
		||||
            "App" => {
 | 
			
		||||
                self.selection = Some(DownloadType::App);
 | 
			
		||||
            }
 | 
			
		||||
            "Rail"=>{
 | 
			
		||||
            "Rail" => {
 | 
			
		||||
                self.selection = Some(DownloadType::Rail);
 | 
			
		||||
            }
 | 
			
		||||
            _=>{
 | 
			
		||||
            _ => {
 | 
			
		||||
                self.selection = None;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    fn save_ui_log(&mut self){
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -7,7 +7,13 @@ pub(crate) struct MesService {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl MesService {
 | 
			
		||||
    pub fn new(ip: String, port: String, username: String, password: String, database: String) -> Result<Self, Error> {
 | 
			
		||||
    pub fn new(
 | 
			
		||||
        ip: String,
 | 
			
		||||
        port: String,
 | 
			
		||||
        username: String,
 | 
			
		||||
        password: String,
 | 
			
		||||
        database: String,
 | 
			
		||||
    ) -> Result<Self, Error> {
 | 
			
		||||
        let url = format!(
 | 
			
		||||
            "mysql://{}:{}@{}:{}/{}",
 | 
			
		||||
            username, password, ip, port, database
 | 
			
		||||
@@ -30,74 +36,99 @@ impl MesService {
 | 
			
		||||
        download_type: DownloadType,
 | 
			
		||||
    ) -> Result<bool, Error> {
 | 
			
		||||
        match download_type {
 | 
			
		||||
            DownloadType::Bootloader => {
 | 
			
		||||
                let mut conn = self.pool.get_conn()?;
 | 
			
		||||
                let work_order_id:Vec<u32>= conn.query(format!("SELECT `id` FROM wisun_ordertables WHERE `OrderId` = '{work_order}'"))?;
 | 
			
		||||
                if let Some(work_order_id) = work_order_id.first(){
 | 
			
		||||
                    let _: Vec<String> = conn.exec(format!("INSERT INTO {work_order} (`ID`,`Barcode`,`IMEI_1`) VALUES ({work_order_id},{label},{label})").to_string(), ())?;
 | 
			
		||||
                }else{
 | 
			
		||||
                    return Ok(false);
 | 
			
		||||
                }
 | 
			
		||||
                Ok(true)
 | 
			
		||||
            },
 | 
			
		||||
            DownloadType::App => {
 | 
			
		||||
                let mut conn = self.pool.get_conn()?;
 | 
			
		||||
                let check_result: Vec<String> = conn.query(format!(
 | 
			
		||||
                    "SELECT `Station1` FROM {work_order} WHERE `Barcode` = {label}"
 | 
			
		||||
                ))?;
 | 
			
		||||
                if check_result.is_empty() {
 | 
			
		||||
                    return Ok(false);
 | 
			
		||||
                }
 | 
			
		||||
                Ok(check_result[0] == "1")
 | 
			
		||||
            }
 | 
			
		||||
            DownloadType::Rail => {
 | 
			
		||||
                let mut conn = self.pool.get_conn()?;
 | 
			
		||||
                let check_result: Vec<String> = conn.query(format!(
 | 
			
		||||
                    "SELECT `Station2` FROM {work_order} WHERE `Barcode` = {label}"
 | 
			
		||||
                    "SELECT `Station2` FROM `{work_order}` WHERE `Barcode` = '{label}'"
 | 
			
		||||
                ))?;
 | 
			
		||||
                if check_result.is_empty() {
 | 
			
		||||
                    return Ok(false);
 | 
			
		||||
                }
 | 
			
		||||
                Ok(check_result[0] == "1")
 | 
			
		||||
            }
 | 
			
		||||
            DownloadType::App => {
 | 
			
		||||
                let mut conn = self.pool.get_conn()?;
 | 
			
		||||
                let check_result: Vec<String> = conn.query(format!(
 | 
			
		||||
                    "SELECT `IMEI_1` FROM `{work_order}` WHERE `Barcode` = '{label}';"
 | 
			
		||||
                ))?;
 | 
			
		||||
                if check_result.is_empty() {
 | 
			
		||||
                    Ok(true)
 | 
			
		||||
                } else {
 | 
			
		||||
                    Ok(false)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            DownloadType::Bootloader => Ok(true),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn update_station(&self, work_order: String, label: String, download_type: DownloadType) -> Result<(), Error> {
 | 
			
		||||
    pub fn get_order_number(&self, work_order: String)->Result<String, Error>{
 | 
			
		||||
        let mut conn = self.pool.get_conn()?;
 | 
			
		||||
        let order_number: Vec<String> = conn.query(format!(
 | 
			
		||||
            "SELECT `Batch` FROM wisun_ordertables WHERE `OrderId` = '{work_order}'"
 | 
			
		||||
        ))?;
 | 
			
		||||
        if order_number.is_empty() {
 | 
			
		||||
            Err(Error::msg("No order number found"))
 | 
			
		||||
        }else{
 | 
			
		||||
            Ok(order_number[0].clone())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn update_station(
 | 
			
		||||
        &self,
 | 
			
		||||
        work_order: String,
 | 
			
		||||
        label: String,
 | 
			
		||||
        download_type: DownloadType,
 | 
			
		||||
    ) -> Result<(), Error> {
 | 
			
		||||
        let time_now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
 | 
			
		||||
        match download_type {
 | 
			
		||||
            DownloadType::Bootloader => {
 | 
			
		||||
                let mut conn = self.pool.get_conn()?;
 | 
			
		||||
                let _: Vec<String> = conn.exec(format!(
 | 
			
		||||
                    "UPDATE {work_order} SET `Station1` = 1 WHERE `Barcode` = {label}"
 | 
			
		||||
                ), ())?;
 | 
			
		||||
            }
 | 
			
		||||
            DownloadType::Bootloader => {}
 | 
			
		||||
            DownloadType::App => {
 | 
			
		||||
                let mut conn = self.pool.get_conn()?;
 | 
			
		||||
                let _: Vec<String> = conn.exec(format!(
 | 
			
		||||
                    "UPDATE {work_order} SET `Station2` = 1 WHERE `Barcode` = {label}"
 | 
			
		||||
                ), ())?;
 | 
			
		||||
                let work_order_id: Vec<u32> = conn.query(format!(
 | 
			
		||||
                    "SELECT `id` FROM wisun_ordertables WHERE `OrderId` = '{work_order}'"
 | 
			
		||||
                ))?;
 | 
			
		||||
                if let Some(work_order_id) = work_order_id.first() {
 | 
			
		||||
                    let _: Vec<String> = conn.exec(
 | 
			
		||||
                        format!(
 | 
			
		||||
                            "INSERT INTO `{work_order}` (`ID`, `Barcode`, `IMEI_1`, `Station1`, `Station1Time`) VALUES ( {work_order_id}, '{label}', '{label}', '1', '{time_now}') \
 | 
			
		||||
        ON DUPLICATE KEY UPDATE `Barcode` = VALUES(`Barcode`), `IMEI_1` = VALUES(`IMEI_1`), `Station1` = VALUES(`Station1`), `Station1Time`= VALUES(`Station1Time`)",
 | 
			
		||||
                            work_order_id = work_order_id,
 | 
			
		||||
                            label = label,
 | 
			
		||||
                            time_now = time_now
 | 
			
		||||
                        ),
 | 
			
		||||
                        ()
 | 
			
		||||
                    )?;
 | 
			
		||||
                } else {
 | 
			
		||||
                    return Ok(());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            DownloadType::Rail => {
 | 
			
		||||
                let mut conn = self.pool.get_conn()?;
 | 
			
		||||
                let _: Vec<String> = conn.exec(format!(
 | 
			
		||||
                    "UPDATE {work_order} SET `Station3` = 1 WHERE `Barcode` = {label}"
 | 
			
		||||
                ), ())?;
 | 
			
		||||
                let _: Vec<String> = conn.exec(
 | 
			
		||||
                    format!("UPDATE `{work_order}` SET Station3 = 1, Station3Time='{time_now}' WHERE Barcode = '{label}'"),
 | 
			
		||||
                    (),
 | 
			
		||||
                )?;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(test)]
 | 
			
		||||
    fn reset(&self){
 | 
			
		||||
    fn reset(&self) {
 | 
			
		||||
        let mut conn = self.pool.get_conn().unwrap();
 | 
			
		||||
        let _: Vec<String> = conn.query("UPDATE rrr SET `Station1` = 0, `Station2` = 0, `Station3` = 0 WHERE `Barcode` = 1".to_string()).unwrap();
 | 
			
		||||
        let _: Vec<String> = conn
 | 
			
		||||
            .query(
 | 
			
		||||
                "UPDATE rrr SET `Station1` = 0, `Station2` = 0, `Station3` = 0 WHERE `Barcode` = 1"
 | 
			
		||||
                    .to_string(),
 | 
			
		||||
            )
 | 
			
		||||
            .unwrap();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod test {
 | 
			
		||||
    use crate::download_wrapper::DownloadType;
 | 
			
		||||
    use crate::mes_service::MesService;
 | 
			
		||||
    use mysql::prelude::*;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_mes_service() {
 | 
			
		||||
@@ -119,13 +150,13 @@ mod test {
 | 
			
		||||
            "".to_string(),
 | 
			
		||||
            "MOBILETEK_WISUN".to_string(),
 | 
			
		||||
        );
 | 
			
		||||
        let work_orders = mes.get_work_orders().unwrap();
 | 
			
		||||
        let work_orders = mes.unwrap().get_work_orders().unwrap();
 | 
			
		||||
        assert_ne!(work_orders.len(), 0);
 | 
			
		||||
        println!("{:?}", work_orders);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_check_station_and_update_station() {
 | 
			
		||||
    fn test_check_station() {
 | 
			
		||||
        let mes = MesService::new(
 | 
			
		||||
            "192.168.1.17".to_string(),
 | 
			
		||||
            "3306".to_string(),
 | 
			
		||||
@@ -133,15 +164,14 @@ mod test {
 | 
			
		||||
            "".to_string(),
 | 
			
		||||
            "MOBILETEK_WISUN".to_string(),
 | 
			
		||||
        );
 | 
			
		||||
        mes.reset();
 | 
			
		||||
        assert_eq!(mes.check_station("rrr".to_string(),"1".to_string(),DownloadType::Bootloader).unwrap(),true);
 | 
			
		||||
        assert_eq!(mes.check_station("rrr".to_string(), "1".to_string(), DownloadType::App).unwrap(),false);
 | 
			
		||||
        mes.update_station("rrr".to_string(), "1".to_string(), DownloadType::Bootloader).unwrap();
 | 
			
		||||
        assert_eq!(mes.check_station("rrr".to_string(), "1".to_string(), DownloadType::App).unwrap(),true);
 | 
			
		||||
        assert_eq!(mes.check_station("rrr".to_string(), "1".to_string(), DownloadType::Rail).unwrap(),false);
 | 
			
		||||
        mes.update_station("rrr".to_string(), "1".to_string(), DownloadType::App).unwrap();
 | 
			
		||||
        assert_eq!(mes.check_station("rrr".to_string(), "1".to_string(), DownloadType::Rail).unwrap(),true);
 | 
			
		||||
        mes.update_station("rrr".to_string(), "1".to_string(), DownloadType::Rail).unwrap();
 | 
			
		||||
        let mut conn = mes.unwrap().pool.get_conn().unwrap();
 | 
			
		||||
        let work_order = "3333";
 | 
			
		||||
        let label = "202400154Y000016";
 | 
			
		||||
        let check_result: Vec<String> = conn
 | 
			
		||||
            .query(format!(
 | 
			
		||||
                "SELECT `COUNT` FROM `{work_order}` WHERE `Barcode` = '{label}';"
 | 
			
		||||
            ))
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        println!("{:?}", check_result);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user