Skip to content

Commit d782af3

Browse files
v0.5.2:support futures main
1 parent 43703ba commit d782af3

13 files changed

Lines changed: 175 additions & 113 deletions

File tree

UpdateRecord.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
### version: 0.5.2 (2025年2月7日01:20:52)
2+
1. 优化了历史k线保存的逻辑。
3+
2. 优化了应用的启动过程。
4+
15
### version: 0.5.1 (2025年2月5日15:47:11)
26
1. 完善了日志模块,现在panic也会被记录到日志中。
37
2. 现在期货数据支持主力合约。
48

59
### version: 0.5.0 (2025年2月4日23:46:44)
610
1. 修复了一个bug,今后在"全部"分组中使用“从当前分组移除”功能将会直接删除该股票以及所有相关数据。
7-
2. 添加新功能,现在支持期货。
11+
2. 添加新功能,现在支持期货。https://aktools.akfamily.xyz/aktools/)
812

913
### version: 0.4.16 (2025年1月16日01:51:02)
1014
1. 修复了一个bug,该bug导致当前最新日k线显示不正确。

src-tauri/Cargo.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "trade_tip"
3-
version = "0.5.1"
3+
version = "0.5.2"
44
description = "金融助手"
55
authors = ["xbss"]
66
edition = "2021"
@@ -39,6 +39,8 @@ encoding_rs = "0.8.34"
3939
tauri-plugin-dialog = "2"
4040
ashares = "0.1.0"
4141
itertools = "0.14.0"#支持多个迭代器的扁平化组合,计算均线时要用
42+
43+
async-recursion = "1.1.1"
4244
[features]
4345
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
4446
custom-protocol = ["tauri/custom-protocol"]

src-tauri/src/main.rs

Lines changed: 67 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod utils;
1313

1414
use crate::app_errors::AppResult;
1515
use crate::cache::intraday_chart_cache::IntradayChartCache;
16-
use crate::config::config::Config;
16+
use crate::config::config::{Config, DataConfig};
1717
use crate::entities::init_db_coon;
1818
use crate::service::command::tauri_command::{
1919
add_stock_info, create_group, delete_all_transaction_records, delete_graphic_by_group_id,
@@ -35,12 +35,14 @@ use std::collections::HashMap;
3535
use std::{env, panic};
3636
use std::sync::atomic::{AtomicBool};
3737
use std::sync::{Arc, LazyLock, Mutex};
38+
use std::time::Duration;
3839
use log4rs::append::console::ConsoleAppender;
3940
use log4rs::append::file::FileAppender;
4041
use log4rs::encode::pattern::PatternEncoder;
4142
use log4rs::filter::threshold::ThresholdFilter;
42-
use tauri::{AppHandle, Manager};
43+
use tauri::{Manager};
4344
use tokio::sync::mpsc;
45+
use tokio::sync::mpsc::Receiver;
4446
use tokio::task::JoinHandle;
4547

4648
///是否需要实时更新
@@ -118,23 +120,14 @@ pub async fn get_close_prices(
118120
#[tokio::main]
119121
async fn main() {
120122
init_app().await;
121-
//todo 下面这俩更新如果出错了在前端页面是没有提醒的,如果想要emit一个错误事件到前端的话,有可能存在前端页面还没渲染完就emit了,就收不到了;
122-
// 如果弄一个本地变量保存错误信息,前端页面渲染完成后主动来invoke读取这个变量判断是否出错应该可以,但是目前懒得搞。
123-
tokio::spawn(async {
124-
info!("update stock info start");
125-
if let Err(e) = service::curd::update_all_day_k().await{
126-
error!("update stock info failed:{}",e)
127-
}
128-
// update().await;
129-
});
130-
tokio::spawn(async {
131-
info!("update position start");
132-
if let Err(e) = service::curd::update_all_position().await{
133-
error!("update position failed:{}",e)
134-
}
135-
});
123+
124+
let config = Config::load().await;
125+
let data_config = config.data_config.clone();
126+
let (send,recv) = mpsc::channel::<()>(1);
127+
init_data_server_daily_position(recv,data_config).await;
128+
136129
let state = MyState::new().await;
137-
info!("ui start");
130+
info!("tauri start...");
138131
tauri::Builder::default()
139132
.plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
140133
error!("the app is already running, args: {:?}, cwd: {}", args, cwd);
@@ -147,40 +140,29 @@ async fn main() {
147140
.manage(state)
148141
.manage(IntradayChartCache::new())
149142
// .manage(Mutex::new(Config::load().await))
150-
.manage(Mutex::new(Config::load().await))
143+
.manage(Mutex::new(config))
144+
.manage(send)
151145
.plugin(tauri_plugin_shell::init())
152146
.plugin(tauri_plugin_fs::init())
153147
.plugin(tauri_plugin_window_state::Builder::default().build())
154-
.setup(|app| {
155-
let app_handle: &AppHandle = app.app_handle();
156-
let config = app_handle.state::<Mutex<Config>>();
157-
let data_config = config.lock().unwrap().data_config.clone();
158-
let (send,recv) = mpsc::channel::<()>(1);
159-
app.manage(send);
160-
tokio::spawn(async move{
161-
if let Err(e) = start_data_server(&data_config,recv).await{
162-
error!("start data server error:{}",e);
163-
}
164-
});
165-
Ok(())
166-
})
167-
// .setup(|app|{
168-
// info!("{:?}",app.app_handle().path().app_config_dir().unwrap()); //"C:\\Users\\Xbss\\AppData\\Roaming\\com.xbss.trade-tip"
169-
// let main_window = app.get_webview_window("main").unwrap();
170-
// // main_window.as_ref().window().restore_state(StateFlags::all())
171-
// let tool_window = app.get_webview_window("tool").unwrap();
148+
// .setup(|app| {
149+
// let app_handle: &AppHandle = app.app_handle();
150+
// let config = app_handle.state::<Mutex<Config>>();
151+
// let data_config = config.lock().unwrap().data_config.clone();
152+
// let (send,recv) = mpsc::channel::<()>(1);
153+
// app.manage(send);
172154
// tokio::spawn(async move{
173-
// // let mut result = main_window.restore_state(StateFlags::all());
174-
// // info!("restore main window state result:{:?}",result);
175-
// // if result.is_err(){
176-
// // error!("restore main window state error:{}",result.err().unwrap().to_string());
177-
// // };
178-
// main_window.show().unwrap();
179-
// // result = tool_window.restore_state(StateFlags::all());
180-
// // if result.is_err(){
181-
// // error!("restore tool window state error:{}",result.err().unwrap().to_string());
182-
// // };
155+
// tokio::spawn(async move{
156+
// info!("update daily info start...");
157+
// if let Err(e) = service::curd::update_all_day_k(data_config.use_ak_share).await{
158+
// error!("update daily info failed:{}",e)
159+
// };
160+
// });
161+
// if let Err(e) = start_data_server(&data_config,recv).await{
162+
// error!("start data server error:{}",e);
163+
// };
183164
// });
165+
// info!("setup ok.");
184166
// Ok(())
185167
// })
186168
.invoke_handler(tauri::generate_handler![
@@ -285,24 +267,44 @@ async fn init_logger() {
285267
}
286268
}));
287269
}
288-
// async fn update() {
289-
// match service::curd::update_all_day_k().await {
290-
// Ok(_) => {
291-
// info!("更新日线数据成功");
292-
// NOTICE
293-
// .lock()
294-
// .unwrap()
295-
// .replace("更新日线数据成功".to_string());
296-
// }
297-
// Err(e) => {
298-
// error!("更新日线数据失败:{}", e);
299-
// NOTICE
300-
// .lock()
301-
// .unwrap()
302-
// .replace(format!("更新日线数据失败:{}", e.to_string()));
303-
// }
304-
// };
305-
// }
270+
async fn init_data_server_daily_position(recv:Receiver<()>,data_config:DataConfig){
271+
let can_handle_futures = data_config.use_ak_share;
272+
tokio::spawn(async move{
273+
if let Err(e) = start_data_server(&data_config,recv).await{
274+
error!("start data server error:{}",e);
275+
};
276+
});
277+
//todo 下面这俩更新如果出错了在前端页面是没有提醒的,如果想要emit一个错误事件到前端的话,有可能存在前端页面还没渲染完就emit了,就收不到了;
278+
// 如果弄一个本地变量保存错误信息,前端页面渲染完成后主动来invoke读取这个变量判断是否出错应该可以,但是目前懒得搞。
279+
tokio::spawn(async move{
280+
info!("update daily info start...");
281+
if let Err(e) = service::curd::update_all_day_k(can_handle_futures,false).await{
282+
error!("update daily info failed:{:?}.",e)
283+
}
284+
info!("update daily info end.");
285+
// match service::curd::update_all_day_k(can_handle_futures).await {
286+
// Ok(failure) => {
287+
// if failure {
288+
// error!("first update daily info failed, 20s later will retry again.");
289+
// sleep(Duration::from_secs(20)).await;
290+
// match service::curd::update_all_day_k(can_handle_futures).await{
291+
// Ok(failure) =>{
292+
//
293+
// }
294+
// Err(e) => {error!("second update stock info failed:{:?}",e)}
295+
// }
296+
// }
297+
// }
298+
// Err(e) => {error!("update stock info failed:{:?}",e)}
299+
// }
300+
});
301+
tokio::spawn(async {
302+
info!("update position start");
303+
if let Err(e) = service::curd::update_all_position().await{
304+
error!("update position failed:{}",e)
305+
}
306+
});
307+
}
306308
// ///判断是否开市,先发起一个请求,然后sleep 1秒,再发起一个请求,如果两个请求的返回值不一样,则证明开市了,否则证明闭市了。
307309
// async fn judge_market_open() {
308310
// let response1 = REQUEST.get().unwrap().get("https://qt.gtimg.cn/q=sz159992").await.unwrap();

src-tauri/src/service/command/tauri_command.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use crate::service::curd::stock_data_curd::StockDataCurd;
1010
use crate::service::curd::stock_group_curd::StockGroupCurd;
1111
use crate::service::curd::stock_info_curd::StockInfoCurd;
1212
use crate::service::curd::transaction_record_curd::TransactionRecordCurd;
13-
use crate::service::curd::update_all_day_k;
1413
use crate::service::http::{init_http, REQUEST};
1514
use crate::{get_close_prices, MyState, IS_MARKET_OPEN, UPDATEING};
1615
use log::{error, info};
@@ -27,7 +26,7 @@ use crate::service::curd::position_curd::PositionCurd;
2726
#[tauri::command]
2827
pub async fn update_live_state<'r>(
2928
state: State<'r, MyState>,
30-
app_handle: tauri::AppHandle,
29+
app_handle: AppHandle,
3130
config: State<'r, Mutex<Config>>,
3231
group_name: String,
3332
live_state: bool,
@@ -39,17 +38,17 @@ pub async fn update_live_state<'r>(
3938
}
4039
Ok(())
4140
}
42-
#[tauri::command]
43-
pub async fn update_all_stock_day_k() -> Result<String, String> {
44-
// state.update_live_state(live_state);
45-
match update_all_day_k().await {
46-
Ok(_) => Ok("更新成功".to_string()),
47-
Err(e) => {
48-
handle_error("更新日线数据失败", e.to_string())
49-
// Err(format!("更新日线数据失败:{}",e.to_string()))
50-
}
51-
}
52-
}
41+
// #[tauri::command]
42+
// pub async fn update_all_stock_day_k() -> Result<String, String> {
43+
// // state.update_live_state(live_state);
44+
// match update_all_day_k().await {
45+
// Ok(_) => Ok("更新成功".to_string()),
46+
// Err(e) => {
47+
// handle_error("更新日线数据失败", e.to_string())
48+
// // Err(format!("更新日线数据失败:{}",e.to_string()))
49+
// }
50+
// }
51+
// }
5352
#[tauri::command]
5453
pub async fn get_response(url: String) -> Result<String, String> {
5554
match REQUEST.get().unwrap().get_response(&url).await {
@@ -112,9 +111,11 @@ pub async fn query_all_groups() -> Result<Vec<StockGroup>, String> {
112111

113112
#[tauri::command]
114113
pub async fn query_stocks_by_group_name(name: String) -> Result<Vec<StockInfoG>, String> {
114+
// error!("根据分组名查询分组中的股票:{}",name);
115115
if name == "持有" {
116116
return match StockInfoCurd::query_all_hold_info().await {
117117
Ok(more_infos) => {
118+
// error!("查询持有分组成功:{:?}",more_infos);
118119
Ok(more_infos)
119120
}
120121
Err(e) => {
@@ -501,7 +502,10 @@ pub async fn query_live_stocks_data_by_group_name<'r>(
501502
group_name: String,
502503
app_handle: AppHandle,
503504
) -> Result<(), String> {
504-
info!("查询{}分组内的实时数据", group_name);
505+
if group_name.is_empty(){//应用刚启动会有一个空的分组名进来,不知道哪里传来
506+
return Ok(());
507+
}
508+
error!("查询{}分组内的实时数据", group_name);
505509
// if !IS_MARKET_OPEN.load(Ordering::Relaxed) {
506510
// info!("市场未开市,不进行查询操作!");
507511
// return Ok(());
@@ -510,10 +514,9 @@ pub async fn query_live_stocks_data_by_group_name<'r>(
510514
let result = if group_name == "持有" {
511515
StockInfoCurd::query_all_hold_only_code().await
512516
} else {
513-
GroupStockRelationCurd::query_only_code_by_group_name(group_name).await
517+
GroupStockRelationCurd::query_only_code_by_group_name(group_name.clone()).await
514518
};
515519
let update_freq = config.lock().unwrap().data_config.update_freq;
516-
info!("更新频率为{}秒", update_freq);
517520
match result {
518521
Ok(codes) => {
519522
if codes.is_empty() {
@@ -542,7 +545,6 @@ pub async fn query_live_stocks_data_by_group_name<'r>(
542545
.await
543546
{
544547
Ok(_) => {
545-
// info!("查询成功:{:?}",stock_data_list);
546548
app_handle
547549
.emit("live_stock_data", stock_data_list)
548550
.unwrap();

0 commit comments

Comments
 (0)