Compare commits

...

2 Commits

3 changed files with 334 additions and 281 deletions

View File

@ -1,7 +1,9 @@
use crate::download_wrapper::DownloadError::JlinkNotFindError; use crate::download_wrapper::DownloadError::JlinkNotFindError;
use anyhow::Error; use anyhow::Error;
use std::fs;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use std::io::Write;
pub struct DownloadWrapper { pub struct DownloadWrapper {
commander_path: PathBuf, commander_path: PathBuf,
@ -36,6 +38,7 @@ pub enum DownloadError {
DownloadBootloaderError, DownloadBootloaderError,
DownloadAppError, DownloadAppError,
DownloadRailError, DownloadRailError,
NoLabel,
} }
impl Default for DownloadWrapper { impl Default for DownloadWrapper {
@ -65,9 +68,7 @@ impl DownloadWrapper {
.expect("Failed to execute command"); .expect("Failed to execute command");
if output.status.success() { if output.status.success() {
let result_str = String::from_utf8_lossy(&output.stdout).to_string(); let result_str = String::from_utf8_lossy(&output.stdout).to_string();
let result = result_str let result = result_str.split("\r\n").collect::<Vec<&str>>();
.split("\r\n")
.collect::<Vec<&str>>();
let device_index_str: Vec<String> = result let device_index_str: Vec<String> = result
.iter() .iter()
.filter(|&&str| str.starts_with("deviceCount")) .filter(|&&str| str.starts_with("deviceCount"))
@ -115,7 +116,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 commander_path_str = self.commander_path.to_str().unwrap();
let output = Command::new(commander_path_str) let output = Command::new(commander_path_str)
.arg("device") .arg("device")
@ -125,9 +126,7 @@ impl DownloadWrapper {
.output() .output()
.expect("Failed to execute command"); .expect("Failed to execute command");
let result_str = String::from_utf8_lossy(&output.stdout).to_string(); let result_str = String::from_utf8_lossy(&output.stdout).to_string();
let result = result_str let result = result_str.split("\r\n").collect::<Vec<&str>>();
.split("\r\n")
.collect::<Vec<&str>>();
if !result if !result
.iter() .iter()
.filter(|&&str| str.trim().starts_with("ERROR")) .filter(|&&str| str.trim().starts_with("ERROR"))
@ -141,20 +140,28 @@ impl DownloadWrapper {
{ {
Err(DownloadError::EraseError) Err(DownloadError::EraseError)
} else { } else {
Ok(()) let Some(label) = label else { return Err(DownloadError::NoLabel) };
match self.save_log(label, result_str.clone()) {
Ok(res) => {
Ok(result_str)
}
Err(e) => {
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; let mut binding: PathBuf;
match download_type { match download_type {
DownloadType::Bootloader=> { DownloadType::Bootloader => {
binding = self.bin_path.join(&self.bootloader_name); binding = self.bin_path.join(&self.bootloader_name);
} }
DownloadType::App=>{ DownloadType::App => {
binding = self.bin_path.join(&self.app_name); binding = self.bin_path.join(&self.app_name);
} }
DownloadType::Rail=>{ DownloadType::Rail => {
binding = self.bin_path.join(&self.rail_name); binding = self.bin_path.join(&self.rail_name);
} }
} }
@ -169,9 +176,7 @@ impl DownloadWrapper {
.output() .output()
.expect("Failed to execute command"); .expect("Failed to execute command");
let result_str = String::from_utf8_lossy(&output.stdout).to_string(); let result_str = String::from_utf8_lossy(&output.stdout).to_string();
let result = result_str let result = result_str.split("\r\n").collect::<Vec<&str>>();
.split("\r\n")
.collect::<Vec<&str>>();
println!("{:?}", result); println!("{:?}", result);
if !result if !result
.iter() .iter()
@ -186,23 +191,36 @@ impl DownloadWrapper {
{ {
Err(DownloadError::DownloadBootloaderError) Err(DownloadError::DownloadBootloaderError)
} else { } else {
Ok(()) let Some(label) = label else { return Err(DownloadError::NoLabel) };
match self.save_log(label, result_str.clone()) {
Ok(res) => {
Ok(result_str)
}
Err(e) => {
Err(DownloadError::DownloadBootloaderError)
}
}
} }
} }
pub fn download_app(&self) -> Result<bool, DownloadError> { fn save_log(& self, label: String, log: String) -> Result<bool, DownloadError> {
todo!() if !fs::exists("./log").unwrap() {
fs::create_dir("./log").expect("Cant Create Log Folder");
} }
let mut file = fs::OpenOptions::new()
pub fn download_rail(&self) -> Result<bool, DownloadError> { .create(true)
todo!() .append(true)
.open(format!("./log/{label}.txt"))
.expect("file not found");
writeln!(file, "{}",log).expect("write failed");
Ok(true)
} }
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::download_wrapper::DownloadWrapper;
use crate::download_wrapper::DownloadType; use crate::download_wrapper::DownloadType;
use crate::download_wrapper::DownloadWrapper;
#[test] #[test]
fn test_download_wrapper() { fn test_download_wrapper() {
@ -237,23 +255,23 @@ mod test {
} }
#[test] #[test]
fn test_download_bootloader(){ fn test_download_bootloader() {
let dw = DownloadWrapper::new(); let dw = DownloadWrapper::new();
let result = dw.download(DownloadType::Bootloader); let result = dw.download(DownloadType::Bootloader);
assert_eq!(result.is_ok(), true); assert_eq!(result.is_ok(), true);
} }
#[test] #[test]
fn test_download_app(){ fn test_download_app() {
let dw = DownloadWrapper::new(); let dw = DownloadWrapper::new();
let result = dw.download(DownloadType::App); let result = dw.download(DownloadType::App);
assert_eq!(result.is_ok(), true); assert_eq!(result.is_ok(), true);
} }
#[test] #[test]
fn test_download_rail(){ fn test_download_rail() {
let dw = DownloadWrapper::new(); let dw = DownloadWrapper::new();
let result = dw.download(DownloadType::Rail); let result = dw.download(DownloadType::Rail);
assert_eq!(result.is_ok(), true); assert_eq!(result.is_ok(), true);
} }
} }

View File

@ -1,19 +1,23 @@
mod download_wrapper; mod download_wrapper;
mod mes_service; mod mes_service;
use std::any::Any; use crate::mes_service::MesService;
use std::fs;
use crossbeam::channel; use crossbeam::channel;
use std::sync::{Arc, Mutex, LazyLock};
use crossbeam::channel::Sender; use crossbeam::channel::Sender;
use iced::widget::{button, checkbox, column, container, radio, row, text_editor, text_input}; use download_wrapper::DownloadType;
use iced::{event, window, Element, Event, Length, Subscription, Task, time};
use iced::application::Title; use iced::application::Title;
use iced::widget::progress_bar::Style;
use iced::widget::text_editor::Action::Scroll; use iced::widget::text_editor::Action::Scroll;
use iced::widget::text_editor::Edit; 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, Background, Border, Color, Element, Event, Length, Subscription, Task};
use serde_json::Map; use serde_json::Map;
use download_wrapper::DownloadType; use std::any::Any;
use crate::mes_service::MesService; use std::fs;
use std::io::Write;
use std::sync::{Arc, LazyLock, Mutex};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("WisunDownload V0.1", MainWindow::update, MainWindow::view) iced::application("WisunDownload V0.1", MainWindow::update, MainWindow::view)
@ -23,9 +27,7 @@ pub fn main() -> iced::Result {
.run() .run()
} }
static logs: LazyLock<Arc<Mutex<Vec<String>>>> = LazyLock::new(|| { static LOGS: LazyLock<Arc<Mutex<Vec<String>>>> = LazyLock::new(|| Arc::new(Mutex::new(Vec::new())));
Arc::new(Mutex::new(Vec::new()))
});
struct MainWindow { struct MainWindow {
is_online: bool, is_online: bool,
@ -35,19 +37,21 @@ struct MainWindow {
log_content: text_editor::Content, log_content: text_editor::Content,
sender: Sender<Message>, sender: Sender<Message>,
receiver: channel::Receiver<Message>, receiver: channel::Receiver<Message>,
result_background: Color
} }
impl Default for MainWindow { impl Default for MainWindow {
fn default() -> Self { fn default() -> Self {
let (sender, receiver) =channel::unbounded(); let (sender, receiver) = channel::unbounded();
Self { Self {
is_online: true, is_online: true,
mysql_config: MysqlConfig::default(), mysql_config: MysqlConfig::default(),
selection: None, selection: None,
label: String::new(), label: String::new(),
log_content: text_editor::Content::default(), log_content: text_editor::Content::default(),
result_background: Color::from_rgb8(255,255,255),
sender, sender,
receiver receiver,
} }
} }
} }
@ -76,21 +80,23 @@ enum Message {
AddLog(String), AddLog(String),
LogContentChanged(text_editor::Action), LogContentChanged(text_editor::Action),
SaveConfig, SaveConfig,
DownloadEnd(bool), DownloadEnd((String, bool)),
WindowEvent(Event), WindowEvent(Event),
ClearLog,
Tick, Tick,
} }
pub fn add_log<'a>(msg: String) { pub fn add_log<'a>(msg: String) {
let time_now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); let time_now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
let really_msg = format!("{time_now} [Info]: {msg}"); let really_msg = format!("{time_now} [Info]: {msg}");
logs.lock().unwrap().push(really_msg); LOGS.lock().unwrap().push(really_msg);
} }
impl MainWindow { impl MainWindow {
fn update(&mut self, message: Message) -> Task<Message> { fn update(&mut self, message: Message) -> Task<Message> {
match message { match message {
Message::Start() => { Message::Start() => {
self.result_background = Color::from_rgb8(255,255,255);
self.start(self.sender.clone()); self.start(self.sender.clone());
Task::none() Task::none()
} }
@ -130,64 +136,75 @@ impl MainWindow {
self.is_online = is_online; self.is_online = is_online;
Task::none() 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) => { Message::AddLog(log) => {
for c in log.chars() { 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(); 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() Task::none()
} }
Message::Tick => { Message::Tick => {
for log in logs.lock().unwrap().iter() { for log in LOGS.lock().unwrap().iter() {
for c in log.chars() { 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(); 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() { match self.receiver.try_recv() {
Ok(event) => { Ok(event) => match event {
match event{ Message::DownloadEnd((label, res)) => {
Message::DownloadEnd(res)=>{ let _ = self.update(Message::DownloadEnd((label, res)));
if res{
add_log("下载成功 By Ui Thread".to_string());
}else{
add_log("下载失败 By Ui Thread".to_string());
}
}
_=>{
}
}
}
Err(channel::TryRecvError::Empty) => {
} }
_ => {}
},
Err(channel::TryRecvError::Empty) => {}
Err(channel::TryRecvError::Disconnected) => { Err(channel::TryRecvError::Disconnected) => {
println!("Disconnected"); println!("Disconnected");
} }
}; };
Task::none() Task::none()
} }
Message::LogContentChanged(action) => { Message::LogContentChanged(action) => match action {
match action{
Scroll { lines } => { Scroll { lines } => {
self.log_content.perform(Scroll { lines }); self.log_content.perform(Scroll { lines });
Task::none() Task::none()
} }
_=>{ _ => Task::none(),
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)
Message::DownloadEnd(res)=>{ .append(true)
.open(format!("./uilog/{label}.txt"))
.unwrap();
writeln!(file, "{:?}", self.log_content.text().clone()).unwrap();
if res{ if res{
add_log("下载成功 By Ui Thread".to_string()); self.result_background = Color::from_rgb8(0, 255,0);
}else{ }else{
add_log("下载失败 By Ui Thread".to_string()); self.result_background = Color::from_rgb8(255, 0,0);
} }
Task::none() Task::none()
} }
@ -205,53 +222,59 @@ impl MainWindow {
}; };
Task::none() Task::none()
} }
_ => { Task::none() } _ => Task::none(),
} }
} }
fn view(&self) -> Element<Message> { fn view(&self) -> Element<Message> {
let ip_input = text_input( let ip_input = text_input("IP Address", &self.mysql_config.ip).on_input(Message::IpChanged);
"IP Address", let port_input = text_input("Port", &self.mysql_config.port).on_input(Message::PortChanged);
&self.mysql_config.ip, let username_input =
).on_input(Message::IpChanged); text_input("Username", &self.mysql_config.username).on_input(Message::UsernameChanged);
let port_input = text_input( let password_input =
"Port", text_input("Password", &self.mysql_config.password).on_input(Message::PasswordChanged);
&self.mysql_config.port, let database_input =
).on_input(Message::PortChanged); text_input("Database", &self.mysql_config.database).on_input(Message::DatabaseChanged);
let username_input = text_input( let work_order_input = text_input("WorkOrder", &self.mysql_config.work_order)
"Username", .on_input(Message::WorkOrderChanged);
&self.mysql_config.username, let label_input = text_input("label", &self.label)
).on_input(Message::UsernameChanged); .on_input(Message::LabelChanged)
let password_input = text_input( .on_submit(Message::Start())
"Password", .width(Length::Fill);
&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![ let content = column![
row![ip_input, port_input].spacing(5), row![ip_input, port_input].spacing(5),
row![username_input, password_input].spacing(5), row![username_input, password_input].spacing(5),
row![database_input, work_order_input].spacing(5), row![database_input, work_order_input].spacing(5),
row![ row![
radio("BootLoader", DownloadType::Bootloader,self.selection,Message::TypeSelected), radio(
radio("App", DownloadType::App,self.selection,Message::TypeSelected), "App",
radio("Cal", DownloadType::Rail,self.selection,Message::TypeSelected), DownloadType::App,
checkbox("online", self.is_online).on_toggle(Message::OnlineChecked) self.selection,
].spacing(10), Message::TypeSelected
row![label_input,button("Start").on_press(Message::Start())].spacing(10), ),
text_editor(&self.log_content).on_action(Message::LogContentChanged).height(Length::Fill) radio(
].spacing(10).padding(5); "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); let container = container(content).padding(20);
container.into() container.into()
} }
@ -259,44 +282,54 @@ impl MainWindow {
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
Subscription::batch(vec![ Subscription::batch(vec![
event::listen().map(Message::WindowEvent), event::listen().map(Message::WindowEvent),
time::every(time::Duration::from_millis(50)) time::every(time::Duration::from_millis(50)).map(|_| Message::Tick),
.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 mes_config = self.mysql_config.clone();
let label = self.label.clone(); let label = self.label.clone();
let download_type: DownloadType = self.selection.unwrap(); let download_type: DownloadType = self.selection.unwrap();
let online = self.is_online.clone(); let online = self.is_online.clone();
if label == ""{ if label == "" {
add_log("请输入Label".to_string()); add_log("请输入Label".to_string());
return; return;
} }
std::thread::spawn(move || { std::thread::spawn(move || {
let mut download_wrapper = download_wrapper::DownloadWrapper::new(); let mut download_wrapper = download_wrapper::DownloadWrapper::new();
let mut mes_service: MesService; let mut mes_service: MesService;
sender.send(Message::ClearLog).unwrap();
if online { if online {
add_log("当前为在线模式, 正在连接数据库".to_string()); 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, Ok(service) => mes_service = service,
Err(e) =>{ Err(e) => {
add_log(format!("连接数据库失败: {:?}", e.to_string())); add_log(format!("连接数据库失败: {:?}", e.to_string()));
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; return;
} }
} }
add_log("连接成功".to_string()); add_log("连接成功".to_string());
add_log("正在过站检测".to_string()); 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 { if let Err(res) = check_result {
add_log(format!("过站检测失败: {:?}", res.to_string())); add_log(format!("过站检测失败: {:?}", res.to_string()));
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; return;
} else if let Ok(res) = check_result { } else if let Ok(res) = check_result {
if !res { if !res {
add_log("过站检测失败".to_string()); add_log("过站检测失败".to_string());
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; return;
} }
add_log("过站检测成功".to_string()); add_log("过站检测成功".to_string());
@ -305,98 +338,121 @@ impl MainWindow {
add_log("正在检查JLink连接".to_string()); add_log("正在检查JLink连接".to_string());
if let Err(e) = download_wrapper.check_jlink() { if let Err(e) = download_wrapper.check_jlink() {
add_log("JLink检查失败, 请检查是否安装驱动或连接是否异常".to_string()); add_log("JLink检查失败, 请检查是否安装驱动或连接是否异常".to_string());
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; return;
} }
add_log("JLink检查成功".to_string()); add_log("JLink检查成功".to_string());
add_log("正在检查设备连接".to_string()); add_log("正在检查设备连接".to_string());
if let Err(e) = download_wrapper.check_device() { if let Err(e) = download_wrapper.check_device() {
add_log("设备检查失败, 请检查设备是否连接".to_string()); add_log("设备检查失败, 请检查设备是否连接".to_string());
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; return;
} }
add_log("设备检查成功".to_string()); add_log("设备检查成功".to_string());
match download_type { match download_type {
DownloadType::Bootloader =>{ DownloadType::Bootloader => {}
DownloadType::App => {
add_log("正在擦除Flash".to_string()); add_log("正在擦除Flash".to_string());
if let Err(e) = download_wrapper.erase(){ if let Err(e) = download_wrapper.erase(Some(label.clone())) {
add_log("擦除失败".to_string()); add_log("擦除失败".to_string());
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; return;
} }
add_log("擦除成功".to_string()); add_log("擦除成功".to_string());
add_log("正在下载BootLoader".to_string()); add_log("正在下载BootLoader".to_string());
if let Err(e) = download_wrapper.download(download_type){ if let Err(e) =
download_wrapper.download(DownloadType::Bootloader, Some(label.clone()))
{
add_log("下载BootLoader失败".to_string()); add_log("下载BootLoader失败".to_string());
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; return;
} }
add_log("下载成功".to_string()); add_log("下载BootLoader成功".to_string());
}
DownloadType::App =>{
add_log("正在下载App".to_string()); add_log("正在下载App".to_string());
if let Err(e) = download_wrapper.download(download_type){ if let Err(e) = download_wrapper.download(download_type, Some(label.clone())) {
add_log("下载App失败".to_string()); add_log("下载App失败".to_string());
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; return;
} }
add_log("下载成功".to_string()); add_log("下载App成功".to_string());
} }
DownloadType::Rail=>{ DownloadType::Rail => {
add_log("正在下载Rail".to_string()); add_log("正在下载Rail".to_string());
if let Err(e) = download_wrapper.download(download_type){ if let Err(e) = download_wrapper.download(download_type, Some(label.clone())) {
add_log("下载Rail失败".to_string()); add_log("下载Rail失败".to_string());
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; return;
} }
add_log("下载成功".to_string()); add_log("下载Rail成功".to_string());
} }
} }
return if online { 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, Ok(service) => mes_service = service,
Err(e) =>{ Err(e) => {
add_log(format!("连接数据库失败: {:?}", e.to_string())); add_log(format!("连接数据库失败: {:?}", e.to_string()));
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; 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 { if let Err(e) = update_result {
add_log(format!("上传失败: {:?}", e.to_string())); add_log(format!("上传失败: {:?}", e.to_string()));
sender.send(Message::DownloadEnd(false)).unwrap(); sender.send(Message::DownloadEnd((label, false))).unwrap();
return; return;
} }
sender.send(Message::DownloadEnd(true)).unwrap(); sender.send(Message::DownloadEnd((label, true))).unwrap();
return; return;
} else { } else {
add_log("当前为离线模式".to_string()); add_log("当前为离线模式".to_string());
sender.send(Message::DownloadEnd(true)).unwrap(); sender.send(Message::DownloadEnd((label, true))).unwrap();
return; return;
} };
}); });
} }
fn save_config(&mut self){ fn save_config(&mut self) {
let mut config = Map::new(); let mut config = Map::new();
config.insert("ip".to_string(), self.mysql_config.ip.clone().into()); config.insert("ip".to_string(), self.mysql_config.ip.clone().into());
config.insert("port".to_string(), self.mysql_config.port.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(
config.insert("password".to_string(), self.mysql_config.password.clone().into()); "username".to_string(),
config.insert("database".to_string(), self.mysql_config.database.clone().into()); self.mysql_config.username.clone().into(),
config.insert("work_order".to_string(), self.mysql_config.work_order.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("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(); 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){ fn read_config(&mut self) {
if !fs::exists("config.json").unwrap(){ if !fs::exists("./config.json").unwrap() {
return; 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(); 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.ip = config["ip"].as_str().unwrap().to_string();
self.mysql_config.port = config["port"].as_str().unwrap().to_string(); self.mysql_config.port = config["port"].as_str().unwrap().to_string();
@ -405,24 +461,19 @@ impl MainWindow {
self.mysql_config.database = config["database"].as_str().unwrap().to_string(); 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.mysql_config.work_order = config["work_order"].as_str().unwrap().to_string();
self.is_online = config["is_online"].as_bool().unwrap(); self.is_online = config["is_online"].as_bool().unwrap();
match config["selection"].as_str().unwrap(){ match config["selection"].as_str().unwrap() {
"BootLoader"=>{ "BootLoader" => {
self.selection = Some(DownloadType::Bootloader); self.selection = Some(DownloadType::Bootloader);
} }
"App"=>{ "App" => {
self.selection = Some(DownloadType::App); self.selection = Some(DownloadType::App);
} }
"Rail"=>{ "Rail" => {
self.selection = Some(DownloadType::Rail); self.selection = Some(DownloadType::Rail);
} }
_=>{ _ => {
self.selection = None; self.selection = None;
} }
} }
} }
fn save_ui_log(&mut self){
todo!()
}
} }

View File

@ -7,7 +7,13 @@ pub(crate) struct MesService {
} }
impl 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!( let url = format!(
"mysql://{}:{}@{}:{}/{}", "mysql://{}:{}@{}:{}/{}",
username, password, ip, port, database username, password, ip, port, database
@ -30,17 +36,8 @@ impl MesService {
download_type: DownloadType, download_type: DownloadType,
) -> Result<bool, Error> { ) -> Result<bool, Error> {
match download_type { match download_type {
DownloadType::Bootloader => { DownloadType::App => Ok(true),
let mut conn = self.pool.get_conn()?; DownloadType::Rail => {
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 mut conn = self.pool.get_conn()?;
let check_result: Vec<String> = conn.query(format!( let check_result: Vec<String> = conn.query(format!(
"SELECT `Station1` FROM {work_order} WHERE `Barcode` = {label}" "SELECT `Station1` FROM {work_order} WHERE `Barcode` = {label}"
@ -50,47 +47,55 @@ impl MesService {
} }
Ok(check_result[0] == "1") Ok(check_result[0] == "1")
} }
DownloadType::Rail => { DownloadType::Bootloader => Err(Error::msg("Not implemented yet")),
let mut conn = self.pool.get_conn()?;
let check_result: Vec<String> = conn.query(format!(
"SELECT `Station2` FROM {work_order} WHERE `Barcode` = {label}"
))?;
if check_result.is_empty() {
return Ok(false);
}
Ok(check_result[0] == "1")
}
} }
} }
pub fn update_station(&self, work_order: String, label: String, download_type: DownloadType) -> Result<(), Error> { pub fn update_station(
&self,
work_order: String,
label: String,
download_type: DownloadType,
) -> Result<(), Error> {
match download_type { match download_type {
DownloadType::Bootloader => { 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::App => { DownloadType::App => {
let mut conn = self.pool.get_conn()?; let mut conn = self.pool.get_conn()?;
let _: Vec<String> = conn.exec(format!( let work_order_id: Vec<u32> = conn.query(format!(
"UPDATE {work_order} SET `Station2` = 1 WHERE `Barcode` = {label}" "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`) VALUES ({work_order_id}, {label}, {label}, '1') \
ON DUPLICATE KEY UPDATE `Barcode` = VALUES(`Barcode`), `IMEI_1` = VALUES(`IMEI_1`), `Station1` = VALUES(`Station1`)"
),
()
)?;
} else {
return Ok(());
}
} }
DownloadType::Rail => { DownloadType::Rail => {
let mut conn = self.pool.get_conn()?; let mut conn = self.pool.get_conn()?;
let _: Vec<String> = conn.exec(format!( let _: Vec<String> = conn.exec(
"UPDATE {work_order} SET `Station3` = 1 WHERE `Barcode` = {label}" format!("UPDATE {work_order} SET `Station2` = 1 WHERE `Barcode` = {label}"),
), ())?; (),
)?;
} }
} }
Ok(()) Ok(())
} }
#[cfg(test)] #[cfg(test)]
fn reset(&self){ fn reset(&self) {
let mut conn = self.pool.get_conn().unwrap(); 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();
} }
} }
@ -119,29 +124,8 @@ mod test {
"".to_string(), "".to_string(),
"MOBILETEK_WISUN".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); assert_ne!(work_orders.len(), 0);
println!("{:?}", work_orders); println!("{:?}", work_orders);
} }
#[test]
fn test_check_station_and_update_station() {
let mes = MesService::new(
"192.168.1.17".to_string(),
"3306".to_string(),
"root".to_string(),
"".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();
}
} }