Skip to content

Commit

Permalink
✨ feat(command): 添加其他小工具:查别人流量和电费功能
Browse files Browse the repository at this point in the history
  • Loading branch information
CakeAL committed Oct 27, 2024
1 parent 599388c commit 9b2aff7
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 54 deletions.
60 changes: 41 additions & 19 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,29 @@ use tauri::{utils::config::WindowConfig, Manager};

use crate::{
entities::{AppState, EveryLoginData},
requests::{
get_address, get_load_user_flow, get_mac_address, get_month_pay, get_refresh_account,
get_user_login_log, simulate_login, simulate_login_via_vpn, unbind_macs,
},
requests::*,
setting::Setting,
};

// 没地方放它了
#[tauri::command(async)]
pub async fn load_user_flow(
account: String,
session_id: &str,
via_vpn: bool,
app_state: tauri::State<'_, AppState>,
) -> Result<String, String> {
get_load_user_flow(&account, session_id, via_vpn)
let via_vpn = *app_state.login_via_vpn.read().unwrap();
let mut session_id = String::new();
if via_vpn {
session_id = match app_state.jsessionid.read().unwrap().clone() {
Some(s) => s,
None => return Err("SessionID为空,是否已经登录并单击获取Cookie按钮?".to_string()),
};
}
get_load_user_flow(&account, &session_id, via_vpn)
.await
.map_err(|e| format!("Error while loading user flow: {}", e))
.map(|res| res.to_string())
}

// 对 headless browser 进行操作,获取登陆后的 Cookie
#[tauri::command(async)]
pub async fn get_cookie(
app_state: tauri::State<'_, AppState>,
Expand Down Expand Up @@ -86,7 +89,6 @@ pub async fn get_cookie_vpn(

#[tauri::command(async)]
pub fn logout(
app: tauri::AppHandle,
app_state: tauri::State<'_, AppState>,
window: tauri::Webview,
) -> Result<String, String> {
Expand All @@ -95,14 +97,6 @@ pub fn logout(
}
*app_state.jsessionid.write().unwrap() = None;
*app_state.login_via_vpn.write().unwrap() = false; // 这之前有个bug一直没人发现,说明没人用我的 app 😭
Setting::write_setting(
&Setting {
browser_path: app_state.setting.read().unwrap().browser_path.to_owned(),
..Default::default()
},
&app,
)
.map_err(|err| format!("写入配置错误: {}", err))?;
window
.eval("window.location.reload();")
.map_err(|err| format!("刷新网页错误:{}", err))?;
Expand Down Expand Up @@ -375,10 +369,38 @@ pub async fn manually_check_update(app: tauri::AppHandle) -> Result<(), String>
crate::update(app, true)
.await
.map_err(|err| err.to_string())?;

if cfg!(target_os = "android") {
Err("安卓暂时不支持更新,请到 GitHub 查看是否有更新。".into())
} else {
Ok(())
}
}

#[tauri::command(async)]
pub async fn load_ammeter(
app: tauri::AppHandle,
app_state: tauri::State<'_, AppState>,
ammeter_number: u32,
) -> Result<String, String> {
let kwh = get_ammeter(ammeter_number)
.await
.map_err(|err| err.to_string())?;
match kwh {
Some(kwh) => {
app_state
.setting
.write()
.unwrap()
.set_ammeter_number(ammeter_number);
app_state
.setting
.read()
.unwrap()
.write_setting(&app)
.map_err(|err| err.to_string())?;
Ok(format!("{}", kwh))
}
None => Err("获取用电量失败,可能是电表号错误".to_string()),
}
}
10 changes: 10 additions & 0 deletions src-tauri/src/entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,13 @@ pub struct AppState {
pub setting: RwLock<Setting>,
pub login_via_vpn: RwLock<bool>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AmmeterData {
#[serde(rename = "ServiceKey")]
pub service_key: String,
#[serde(rename = "message")]
pub message: String,
#[serde(rename = "statusCode")]
pub status_code: String,
}
4 changes: 3 additions & 1 deletion src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ pub fn run() {
logout,
get_cookie_vpn,
load_monthly_login_log,
manually_check_update
manually_check_update,
load_ammeter,
load_user_flow
])
.setup(|app| {
#[cfg(not(target_os = "android"))]
Expand Down
19 changes: 18 additions & 1 deletion src-tauri/src/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use reqwest::{header::SET_COOKIE, Client};
use scraper::{Html, Selector};
use serde_json::Value;

use crate::entities::{EveryLoginData, MacAddress, MonthPayInfo, MonthlyData, UserLoginLog};
use crate::entities::{AmmeterData, EveryLoginData, MacAddress, MonthPayInfo, MonthlyData, UserLoginLog};

// Ciallo~(∠・ω< )⌒☆
pub async fn get_load_user_flow(account: &str, session_id: &str, via_vpn: bool) -> Result<Value> {
Expand Down Expand Up @@ -548,6 +548,23 @@ pub async fn get_address() -> Result<Vec<String>> {
Ok(vec![v4_resp, v6_resp])
}

pub async fn get_ammeter(num: u32) -> Result<Option<i32>, Box<dyn std::error::Error>> {
let response = Client::new()
.post("http://fspapp.ustb.edu.cn/app.GouDian/index.jsp?m=alipay&c=AliPay&a=getDbYe")
.header("Content-Type", "application/x-www-form-urlencoded")
.body(format!("DBNum={}", num))
.send()
.await?;
let res_text = response.text().await?;
let ammeter_data: AmmeterData = serde_json::from_str(&res_text)?;
let kwh = ammeter_data.service_key.parse::<i32>();
if ammeter_data.status_code != "200".to_string() || kwh.is_err() {
Ok(None)
} else {
Ok(Some(kwh.unwrap()))
}
}

#[cfg(test)]
mod tests {
// use crate::entities::{GetUserFlowFailed, UserFlow};
Expand Down
34 changes: 4 additions & 30 deletions src-tauri/src/setting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use tauri::Manager;
pub struct Setting {
pub username: Option<String>,
pub password: Option<String>,
pub browser_path: Option<String>,
pub ammeter_number: Option<u32>,
}

impl Setting {
Expand Down Expand Up @@ -48,8 +48,8 @@ impl Setting {
self.password = Some(password);
}

pub fn set_browser_path(&mut self, path: Option<String>) {
self.browser_path = path;
pub fn set_ammeter_number(&mut self, ammeter_number: u32) {
self.ammeter_number = Some(ammeter_number);
}
}

Expand All @@ -66,32 +66,6 @@ fn get_config_path(app: &tauri::AppHandle) -> Result<PathBuf> {
}
None => return Err(anyhow!("There is no such app data dir!")),
};
// dbg!(&path);
dbg!(&path);
Ok(path)
}

// #[cfg(test)]
// mod tests {
// use super::*;

// #[test]
// fn test_write_setting() {
// let mut setting = Setting::default();
// setting.username = Some("user_name".to_string());
// setting.password = Some("password".to_string());
// setting.browser_path = Some("/path/to/browser".to_string());
// setting.write_setting().unwrap();
// }

// #[test]
// fn test_load_setting() {
// let setting = Setting::load_setting().unwrap();
// println!("{:?}", setting);
// }

// #[test]
// fn test_get_config_path() {
// let path = get_config_path().unwrap();
// println!("{:?}", path.to_str());
// }
// }
2 changes: 2 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import UserLoginLog from "./pages/UserLoginLog.vue";
import UnbindMacs from "./pages/UnbindMacs.vue";
import SpeedTest from "./pages/SpeedTest.vue";
import MonthlyUserLog from "./pages/MonthlyUserLog.vue";
import OtherTools from "./pages/OtherTools.vue";
type RouteComponent = DefineComponent<{}, {}, any>;
interface Routes {
Expand All @@ -27,6 +28,7 @@ const routes: Routes = {
"/unbindmacs": UnbindMacs,
"/speedtest": SpeedTest,
"/monthly_user_log": MonthlyUserLog,
"/other_tools": OtherTools,
};
// Ref for current path
Expand Down
21 changes: 19 additions & 2 deletions src/components/Menu.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
<template>
<n-menu :options="menuOptions" />
<n-menu :options="menuOptions" class="my-menu"/>
</template>

<style scoped></style>
<style scoped>
.my-menu {
overflow: auto;
}
</style>

<script setup lang="ts">
Expand All @@ -18,6 +22,7 @@ import {
BrowsersOutline,
SpeedometerOutline,
CalendarOutline,
BuildOutline
} from "@vicons/ionicons5";
function renderIcon(icon: Component) {
Expand Down Expand Up @@ -109,6 +114,18 @@ const menuOptions: MenuOption[] = [
key: "speedtest",
icon: renderIcon(SpeedometerOutline),
},
{
label: () =>
h(
"a",
{
href: "#/other_tools",
},
"其他小工具"
),
key: "other_tools",
icon: renderIcon(BuildOutline),
},
{
label: () =>
h(
Expand Down
100 changes: 100 additions & 0 deletions src/pages/OtherTools.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<script setup lang="ts">
import { invoke } from "@tauri-apps/api/core";
import { onMounted, ref } from "vue";
import { Flow } from "./UserInfo.vue";
import { useMessage } from "naive-ui";
import { useLoadingBar } from "naive-ui";
const loadingBar = useLoadingBar();
const user_name = ref("");
const pop_message = useMessage();
const account_flow = ref<Flow | null>(null);
const ammeter_number = ref("");
const ammeter_data = ref(0);
onMounted(() => {
load_ammeter_number();
});
const load_ammeter_number = async () => {
let res = (await invoke("load_setting").catch((err) =>
pop_message.error(err)
)) as string;
if (res.length > 0) {
let settings = JSON.parse(res);
ammeter_number.value = settings.ammeter_number;
}
};
const load_user_flow = async () => {
if (user_name.value.length == 0) return;
loadingBar.start();
let res = await invoke("load_user_flow", { account: user_name.value }).catch(
(err) => pop_message.error(err)
);
// console.log(res as string);
account_flow.value = JSON.parse(res as string);
loadingBar.finish();
};
const load_ammeter = async () => {
let number = parseInt(ammeter_number.value);
if (!isNaN(number)) {
loadingBar.start();
let res = await invoke("load_ammeter", {
ammeterNumber: number,
}).catch((err) => pop_message.error(err));
loadingBar.finish();
ammeter_data.value = res as number;
} else {
pop_message.error("电表号应该是纯数字!");
}
};
</script>

<template>
<div class="container">
<n-h2 prefix="bar" type="success" style="margin-top: 15px">
<n-text type="success"> 其他小工具 </n-text>
</n-h2>
<n-card title="查一下别人当月流量" hoverable class="my-card">
<p>如果你不在校园网,应先登录为“我不在校园网”模式。</p>
<n-input
v-model:value="user_name"
type="text"
placeholder="学号/工号"
@blur="load_user_flow"
round
/>
<template #footer v-if="account_flow">
这个人 ipv4 用了 {{ (account_flow.data.v4 / 1024).toFixed(2) }} GB,ipv6
用了 {{ (account_flow.data.v6 / 1024).toFixed(2) }} GB
</template>
</n-card>
<n-card title="查一下电费" hoverable class="my-card">
<n-input
v-model:value="ammeter_number"
type="text"
placeholder="电表号"
@blur="load_ammeter"
round
/>
<template #footer v-if="ammeter_data">
还剩 {{ ammeter_data }} kW·h
</template>
</n-card>
</div>
</template>

<style scoped>
.container {
height: 100vh;
overflow: auto;
margin: 5px;
}
.my-card {
margin: 10px 5px;
width: calc(100vw - 300px);
background: rgba(255, 255, 255, 0.05);
}
</style>
2 changes: 1 addition & 1 deletion src/pages/UserInfo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface Data {
v6: number;
}
interface Flow {
export interface Flow {
result: number;
data: Data;
}
Expand Down

0 comments on commit 9b2aff7

Please sign in to comment.