11
This commit is contained in:
@@ -7,6 +7,10 @@
|
||||
"core:default",
|
||||
"core:window:default",
|
||||
"core:window:allow-start-dragging",
|
||||
"core:window:allow-minimize",
|
||||
"core:window:allow-maximize",
|
||||
"core:window:allow-unmaximize",
|
||||
"core:window:allow-is-maximized",
|
||||
"core:event:default",
|
||||
"core:event:allow-listen",
|
||||
"core:event:allow-unlisten",
|
||||
|
||||
@@ -8,3 +8,4 @@ pub mod fs_util;
|
||||
pub mod nodejs;
|
||||
pub mod publish;
|
||||
pub mod quickjs;
|
||||
pub mod software_info;
|
||||
|
||||
71
src-tauri/src/commands/software_info.rs
Normal file
71
src-tauri/src/commands/software_info.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
//! 按本地 oem 文件中的 ID 拉取公开品牌信息。
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use serde::Serialize;
|
||||
use serde_json::Value;
|
||||
use tauri::State;
|
||||
|
||||
use crate::api_client;
|
||||
use crate::oem_context::OemContext;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SoftwareInfo {
|
||||
pub oem_id: i64,
|
||||
pub software_name: String,
|
||||
pub logo_url: Option<String>,
|
||||
pub wechat: Option<String>,
|
||||
}
|
||||
|
||||
fn empty_info(oem_id: i64) -> SoftwareInfo {
|
||||
SoftwareInfo {
|
||||
oem_id,
|
||||
software_name: String::new(),
|
||||
logo_url: None,
|
||||
wechat: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_software_info(oem_id: i64, value: &Value) -> SoftwareInfo {
|
||||
let data = value.get("data").unwrap_or(value);
|
||||
SoftwareInfo {
|
||||
oem_id: data
|
||||
.get("oem_id")
|
||||
.and_then(|v| v.as_i64())
|
||||
.unwrap_or(oem_id),
|
||||
software_name: data
|
||||
.get("software_name")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("")
|
||||
.to_string(),
|
||||
logo_url: data
|
||||
.get("logo_url")
|
||||
.and_then(|v| v.as_str())
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(str::to_string),
|
||||
wechat: data
|
||||
.get("wechat")
|
||||
.and_then(|v| v.as_str())
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(str::to_string),
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_software_info(ctx: State<'_, OemContext>) -> Result<SoftwareInfo, String> {
|
||||
let oem_id = ctx.oem_id;
|
||||
let path = format!("/public/oem-branding/{oem_id}");
|
||||
let (status, value) =
|
||||
api_client::request_json("GET", &path, None, HashMap::new()).await?;
|
||||
|
||||
if status >= 400 {
|
||||
return Ok(empty_info(oem_id));
|
||||
}
|
||||
|
||||
if value.get("ok").and_then(|v| v.as_bool()) == Some(false) {
|
||||
return Ok(empty_info(oem_id));
|
||||
}
|
||||
|
||||
Ok(parse_software_info(oem_id, &value))
|
||||
}
|
||||
@@ -17,6 +17,8 @@ pub mod ffmpeg;
|
||||
pub mod http;
|
||||
pub mod js_runtime;
|
||||
pub mod nodejs;
|
||||
pub mod oem_context;
|
||||
pub mod oem_id;
|
||||
pub mod oss;
|
||||
pub mod publish_db;
|
||||
pub mod publish_store;
|
||||
@@ -36,6 +38,13 @@ pub fn run() {
|
||||
.manage(publish_store::PublishStore::new())
|
||||
.setup(|app| {
|
||||
let handle = app.handle().clone();
|
||||
let oem_id = handle
|
||||
.path()
|
||||
.app_data_dir()
|
||||
.map(|dir| oem_id::read_oem_id_file(&dir.join(oem_id::OEM_FILE_NAME)))
|
||||
.unwrap_or(oem_id::DEFAULT_OEM_ID);
|
||||
app.manage(oem_context::OemContext { oem_id });
|
||||
|
||||
tauri::async_runtime::block_on(async move {
|
||||
let app_config = handle.state::<app_config::AppConfig>();
|
||||
let avatar_store = handle.state::<avatar_store::AvatarStore>();
|
||||
@@ -68,6 +77,7 @@ pub fn run() {
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
commands::api::api_request,
|
||||
commands::software_info::get_software_info,
|
||||
commands::auth::sync_auth_session,
|
||||
commands::app_config::get_app_config,
|
||||
commands::app_config::get_app_config_last_message,
|
||||
|
||||
6
src-tauri/src/oem_context.rs
Normal file
6
src-tauri/src/oem_context.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
//! 启动时解析的 OEM 上下文。
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OemContext {
|
||||
pub oem_id: i64,
|
||||
}
|
||||
67
src-tauri/src/oem_id.rs
Normal file
67
src-tauri/src/oem_id.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
//! 从应用数据目录的 `oem` 文件读取 OEM 编号。
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
pub const DEFAULT_OEM_ID: i64 = 1;
|
||||
|
||||
/// 应用数据目录下的 OEM 配置文件名。
|
||||
pub const OEM_FILE_NAME: &str = "oem";
|
||||
|
||||
pub fn read_oem_id_file(path: &Path) -> i64 {
|
||||
let content = match std::fs::read_to_string(path) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return DEFAULT_OEM_ID,
|
||||
};
|
||||
parse_oem_id_content(&content).unwrap_or(DEFAULT_OEM_ID)
|
||||
}
|
||||
|
||||
fn parse_oem_id_content(content: &str) -> Option<i64> {
|
||||
let trimmed = content.trim();
|
||||
if trimmed.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Ok(value) = serde_json::from_str::<Value>(trimmed) {
|
||||
if let Some(id) = value.get("oem_id").and_then(|v| v.as_i64()) {
|
||||
if id >= 1 {
|
||||
return Some(id);
|
||||
}
|
||||
}
|
||||
if let Some(id) = value.as_i64() {
|
||||
if id >= 1 {
|
||||
return Some(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let first_line = trimmed.lines().next()?.trim();
|
||||
let id: i64 = first_line.parse().ok()?;
|
||||
if id >= 1 {
|
||||
Some(id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn parse_integer_line() {
|
||||
assert_eq!(parse_oem_id_content("2\n"), Some(2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_json_object() {
|
||||
assert_eq!(parse_oem_id_content(r#"{"oem_id":3}"#), Some(3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_defaults_none() {
|
||||
assert_eq!(parse_oem_id_content("abc"), None);
|
||||
assert_eq!(parse_oem_id_content(""), None);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user