use std::collections::{BTreeMap}; use std::str::FromStr; use chrono::NaiveDateTime; use rust_decimal::Decimal; use tracing::info; use crate::{export_template}; use crate::swap_gate::gate_swap_rest_utils::GateSwapRest; use crate::utils::utils::BalanceConfigInfo; pub async fn export_balance(config_info: BalanceConfigInfo) { let config_info_clone = config_info.clone(); let start_time = NaiveDateTime::parse_from_str(&config_info.range_time[0].clone(), "%Y-%m-%d %H:%M:%S").unwrap().timestamp() - 8 * 3600; let end_time = NaiveDateTime::parse_from_str(&config_info.range_time[1].clone(), "%Y-%m-%d %H:%M:%S").unwrap().timestamp() - 8 * 3600; let count_start_time = NaiveDateTime::parse_from_str(&config_info.count_range_time[0].clone(), "%Y-%m-%d %H:%M:%S").unwrap().timestamp() - 8 * 3600; let count_end_time = NaiveDateTime::parse_from_str(&config_info.count_range_time[1].clone(), "%Y-%m-%d %H:%M:%S").unwrap().timestamp() - 8 * 3600; //获取不同账号的数据 let mut acc_all_data: BTreeMap>> = BTreeMap::new(); let mut account_name_list: Vec = vec![]; loop { if config_info_clone.account_list.len() == 0 { info!("没有账号信息"); return; } for account in config_info_clone.account_list.clone() { let mut account_info: BTreeMap = BTreeMap::new(); account_info.insert("account_name".to_string(), account[0].clone()); account_info.insert("access_key".to_string(), account[1].clone()); account_info.insert("secret_key".to_string(), account[2].clone()); let mut gate_exc = GateSwapRest::new(false, account_info.clone()); let data = gate_exc.account_book("usdt".to_string()).await; // info!("请求完成{:?}",data.clone()); if data.code.as_str() == "200" { let account_name = account_info.get("account_name").unwrap(); account_name_list.push(account_name.clone()); //账号 let json_value: serde_json::Value = serde_json::from_str(&data.data).unwrap(); if let serde_json::Value::Array(array) = json_value { let mut name_data_all: Vec> = vec![]; let mut times = 0; for item in array { let time = item["time"].as_i64().unwrap();//秒级 if time == times { continue; } times = time; let change = item["change"].as_str().unwrap(); let balance = item["balance"].as_str().unwrap(); let type_str = match item["type"].as_str().unwrap() { "dnw" => { "转入转出" } "pnl" => { "减仓盈亏" } "fee" => { "交易手续费"; continue; } "refr" => { "推荐人返佣"; continue; } "fund" => { "资金费用"; continue; } "point_dnw" => { "点卡转入转出"; continue; } "point_fee" => { "点卡交易手续费"; continue; } "point_refr" => { "点卡推荐人返佣"; continue; } _ => { "未知-变更类型"; continue; } }; let text = item["text"].as_str().unwrap(); let contract = item["contract"].as_str().unwrap(); let trade_id = item["trade_id"].as_str().unwrap(); let mut name_data_array: Vec = vec![]; name_data_array.push(time.to_string()); name_data_array.push(trade_id.to_string()); name_data_array.push(change.to_string()); name_data_array.push(balance.to_string()); name_data_array.push(type_str.to_string()); name_data_array.push(contract.to_string()); name_data_array.push(text.to_string()); name_data_all.push(name_data_array.clone()); } acc_all_data.insert(account_name.clone(), name_data_all.clone()); } else { info!("不是数组 检查数据"); } } // break; } break;//这里是为了 代码收纳,用了loop来放置代码 } // 根据账户变动填充 let mut count_time_list = vec![]; for (_account_name, account_info) in acc_all_data.clone() { for value in account_info { let time = value[0].clone().parse::().unwrap(); if !count_time_list.contains(&time) && time > count_start_time && time < count_end_time { count_time_list.push(time) } } }; count_time_list.sort_by(|a, b| a.cmp(&b)); let mut bbbbbb = supply_balance(acc_all_data.clone(), count_time_list.clone()); let aaaaa: Vec> = bbbbbb.clone().into_iter().filter(|value| { let t = value[1].clone().parse::().unwrap(); t >= start_time && t <= end_time }).collect(); bbbbbb = aaaaa; // 按小时取时间片 let mut last_timestamp: i64 = -1; let mut export_time_list: Vec = vec![]; for item in start_time..end_time { if item / 3600 != last_timestamp / 3600 { last_timestamp = item; export_time_list.push(last_timestamp); } } export_time_list.push(end_time); let mut data_array_all: Vec> = supply_balance(acc_all_data.clone(), export_time_list.clone()); //2. 数据根据时间片 补全数据 let data_array_all_array: Vec> = data_array_all.clone().into_iter().filter(|value| { let t = value[1].clone().parse::().unwrap(); t >= start_time && t <= end_time }).collect(); data_array_all = data_array_all_array; //生成 html account_name_list.push("sum_acc".to_string()); export_template::template_balance::export_html(config_info_clone.clone(), &account_name_list, &count_time_list, &bbbbbb); } pub fn supply_balance(source_balance_info: BTreeMap>>, time_slicer: Vec) -> Vec> { let mut balance_info_list: Vec> = vec![]; for time in time_slicer.clone() { // 根据时间片去拿数据 ,如果有添加没有,手动添加 let mut total_price = Decimal::ZERO; for (key, value) in source_balance_info.clone() { let mut balance_info = value.clone(); balance_info.sort_by(|a, b| a[0].cmp(&b[0])); let mut new_info: Option> = None; for mut info in balance_info.clone() { let info_time = info[0].parse::().unwrap(); if info_time == time { info.insert(0, key.clone()); new_info = Option::from(info.clone()); break; } } match new_info { None => { let balance_info_filter: Vec> = balance_info.iter().filter(|item| { item[0].parse::().unwrap() < time }).cloned().collect(); let mut last_balance_info = balance_info_filter[balance_info_filter.len() - 1].clone(); last_balance_info.insert(0, key.clone()); total_price += Decimal::from_str(&last_balance_info[4]).unwrap(); balance_info_list.push(last_balance_info); } Some(info) => { } } // //如果匹配到时间片,直接使用,没有则创建 // let new_d: Vec = match da { // None => { // let mut row: Vec = vec![]; // let filter_arrya: Vec> = value.clone().into_iter().filter(|s| { // // info!("读取time:{:?}",s); // let time_v = s[0].clone().parse::().unwrap(); // time_v < time.clone() // }).collect(); // // info!("计算filter_arrya:---{:?}",filter_arrya.clone()); // let acc_name = key.clone().to_string(); // let acc_time = time.to_string(); // let acc_o_id = "填补数据类型".to_string(); // let mut acc_change = "0".to_string(); // let mut acc_balance = "0".to_string(); // let acc_type = "填补数据类型".to_string(); // let mut acc_contract = "填补数据类型".to_string(); // // if filter_arrya.len() > 0 { // // info!("{:?}--{}--{:?}",acc_name, time, filter_arrya[filter_arrya.len() - 1].clone()); // let zj_v = filter_arrya[filter_arrya.len() - 1].clone(); // // acc_change = zj_v[2].clone(); // acc_balance = zj_v[3].clone(); // acc_contract = zj_v[5].clone(); // } // // let acc_balance_round = Decimal::from_str(&acc_balance).unwrap().round_dp(2); // // row.push(acc_name); // row.push(acc_time); // row.push(acc_o_id); // row.push(acc_change); // row.push(acc_balance_round.to_string()); // row.push(acc_type); // row.push(acc_contract); // row // } // Some(d) => { // let mut row: Vec = vec![]; // row.push(key.clone()); // row.extend(d.clone()); // row // } // }; // total_price = total_price + Decimal::from_str(&new_d[4]).unwrap(); // data_array_all.push(new_d); } let mut sum_row: Vec = vec![]; sum_row.push("sum_acc".to_string()); sum_row.push(time.clone().to_string()); sum_row.push("".to_string()); sum_row.push("0".to_string()); sum_row.push(total_price.to_string()); sum_row.push("".to_string()); sum_row.push("".to_string()); sum_row.push("".to_string()); balance_info_list.push(sum_row.clone()); }; println!("------------------{:?}", balance_info_list); balance_info_list }