回顾前文
seaorm迁移初体验——从tauri-plugin-sql重构到seaorm #1 数据库迁移脚本
构建数据库repository层——从tauri-plugin-sql重构到seaorm #2
使用tauri::command构建后端service层
写好了repository层,显然前端没法直接调用这些curd操作,传统的前后端架构往往都需要通过写一些HTTP接口来实现前后端通信,而在Tauri应用中,可以利用tauri::command宏来简化这个过程。tauri::command允许我们通过进程间通信的方式,将Rust函数暴露给前端调用,从而实现前后端的数据交互。
一个tauri command的示例:
/// 插入游戏数据(包含关联数据)
#[tauri::command]
pub async fn insert_game_with_related(
db: State<'_, DatabaseConnection>,
game: InsertGameData,
bgm: Option<BgmDataInput>,
vndb: Option<VndbDataInput>,
other: Option<OtherDataInput>,
) -> Result<i32, String> {
GamesRepository::insert_with_related(&db, game, bgm, vndb, other)
.await
.map_err(|e| format!("插入游戏数据失败: {}", e))
};lib.rs中注册command
写好了一个tauri command之后,还需要在lib.rs中注册这个command,才能让Tauri应用识别它:
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![
insert_game_with_related,
// 其他command...
])在前端使用invoke构建前端service层(调用command)
在前端,我们可以通过Tauri提供的invoke方法来调用后端暴露的command,从而实现前后端的数据交互。我们可以将这些调用封装成一个service层,方便在应用中使用。
由于command较多,如果一个command就写一个函数,那前端service层会显得非常臃肿,因此我们可以将相关的command进行分类,以及使用OOP的编程思想,将相关的command封装到一个类中。
基础Service类:
// 统一处理错误
export class BaseService {
protected async invoke<T>(
command: string,
args?: Record<string, unknown>,
): Promise<T> {
try {
const result = await invoke<T>(command, args);
return result;
} catch (error) {
console.error(`[Service Error] ${command}:`, error);
throw error;
}
}
}GameService类:
class GameService extends BaseService {
/**
* 插入游戏数据(包含关联数据)
*/
async insertGame(
game: RawGameData,
bgm?: BgmData | null,
vndb?: VndbData | null,
other?: OtherData | null,
): Promise<number> {
return this.invoke<number>("insert_game_with_related", {
game,
bgm: bgm || null,
vndb: vndb || null,
other: other || null,
});
}
//...更多的方法
}insertGame方法调用示例:
import { gameService } from "@/services";
addGame: async (fullgame: FullGameData) => {
try {
if (isTauri()) {
await gameService.insertGame(
fullgame.game,
fullgame.bgm_data,
fullgame.vndb_data,
fullgame.other_data,
);
} else {
insertGameLocal(fullgame);
}
// 使用通用刷新函数
await get().refreshGameData();
} catch (error) {
console.error("Error adding game:", error);
}
},结语
至此,完成了从tauri-plugin-sql重构到seaorm的重构工作。前端的职责变回了纯粹的UI展示和交互逻辑,后端则专注于数据库curd和部分底层功能逻辑。通过这种清晰的分层架构,代码的可维护性和扩展性都得到了显著提升。
评论 (0)