template_balance.rs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. use std::collections::BTreeMap;
  2. use std::fs::File;
  3. use std::io::Write;
  4. use chrono::NaiveDateTime;
  5. use handlebars::Handlebars;
  6. use serde_json::json;
  7. use tracing::info;
  8. use crate::utils::utils::{BalanceConfigInfo};
  9. pub fn export_html(config: BalanceConfigInfo, acc_name_all: &Vec<String>, x_time: &Vec<i64>, data_list: &Vec<Vec<String>>, statistic_result: String) {
  10. info!("正在生成网页,请稍后!");
  11. let export_path = if config.export_path == "" { "./" } else { config.export_path.as_str() };
  12. let export_name = if config.export_name == "" { "export_balance" } else { config.export_name.as_str() };
  13. let path = format!("{}/{}.html", export_path, export_name).replace("//", "/");
  14. // 创建 Handlebars 实例
  15. let mut handlebars = Handlebars::new();
  16. //时间片数据组装
  17. let mut time_str_x = vec![];
  18. for time in x_time {
  19. let time_str = NaiveDateTime::from_timestamp_millis((time + 8 * 3600) * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string();
  20. time_str_x.push(time_str);
  21. }
  22. //每个账号的数据
  23. let mut map: BTreeMap<String, Vec<f64>> = BTreeMap::new();
  24. for acc_name in acc_name_all.clone() {
  25. let mut pr_data: Vec<f64> = vec![];
  26. let z = acc_name.clone();
  27. let key = z.as_str();
  28. if map.contains_key(key) {
  29. pr_data = map.get(key).unwrap().clone();
  30. }
  31. for data in data_list.clone() {
  32. if data[0].clone().as_str() == key {
  33. let pr = data[4].clone().parse::<f64>().unwrap();
  34. pr_data.push(pr);
  35. }
  36. }
  37. map.insert(key.to_string(), pr_data);
  38. }
  39. let mut series_all = Vec::new();
  40. for (key, val) in map {
  41. let series = json!({"name": key.to_string(), "type": "line", "smooth": true, "data": val});
  42. series_all.push(series);
  43. }
  44. let series_array = if config.is_total { [series_all[series_all.len() - 1].clone()].to_vec() } else { series_all };
  45. let json = json!({
  46. "data":series_array
  47. });
  48. let series_str = format!("{}", json["data"]);
  49. let data = serde_json::json!({
  50. "chart_title": format!("账户合约余额变更历史"),
  51. "acc_name_all": acc_name_all.clone(),
  52. "statistic_result": statistic_result.clone()
  53. });
  54. // HTML 模板
  55. let template = r#"
  56. <!DOCTYPE html>
  57. <html>
  58. <head>
  59. <meta charset="UTF-8">
  60. <title>{{chart_title}}</title>
  61. <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
  62. <script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.10/dayjs.min.js"></script>
  63. <style>
  64. * {
  65. margin: 0;
  66. padding: 0;
  67. }
  68. #main {
  69. margin: 50px auto 0;
  70. width: calc(100vw - 100px);
  71. height: calc(100vh - 100px);
  72. }
  73. .info_wp{
  74. padding: 0 40px;
  75. }
  76. </style>
  77. </head>
  78. <body>
  79. <div id="main"></div>
  80. <div class="info_wp">{{statistic_result}}</div>
  81. </body>
  82. <script>
  83. var exchangeColor = {binance: '#F4BC0C', gate: '#0068FF', okx: '#171F30'};
  84. var chartDom = document.getElementById('main');
  85. var myChart = echarts.init(chartDom);
  86. var option;
  87. option = {
  88. title: {
  89. text: '{{chart_title}}'
  90. },
  91. tooltip: {
  92. trigger: 'axis'
  93. },
  94. toolbox: {
  95. feature: {
  96. dataZoom: {},
  97. brush: {
  98. type: ['rect', 'clear']
  99. }
  100. }
  101. },
  102. legend: {
  103. data: "#.to_owned() + format!("{:?}", acc_name_all).as_ref() + r#"
  104. },
  105. xAxis: {
  106. type: 'category',
  107. data: "# + format!("{:?}", time_str_x).as_ref() + r#"
  108. },
  109. yAxis: {
  110. type: 'value',
  111. scale: true
  112. },
  113. series: "# + format!("{}", series_str).as_ref() + r#"
  114. };
  115. option && myChart.setOption(option);
  116. </script>
  117. </html>
  118. "#;
  119. // 编译模板
  120. handlebars
  121. .register_template_string("page", template)
  122. .expect("编译模版失败!");
  123. // 渲染模板
  124. let output = handlebars
  125. .render("page", &data)
  126. .expect("渲染模版失败!");
  127. // 将 HTML 写入文件
  128. let mut file = File::create(&path).expect("创建文件失败!");
  129. file.write_all(output.as_bytes()).expect("写入文件到本地失败!");
  130. info!("Balance信息网页生成成功!路径:{:?}\n\n", path);
  131. }