fix: 修复数据库查询NULL值错误和Tauri命令参数命名问题

- 修复video_classification_repository中get_classification_stats函数的NULL值处理
- 将SUM()查询结果从直接获取i32改为Option<i32>并提供默认值0
- 修复get_templates_by_project等命令的参数命名,使用camelCase以匹配前端调用
- 解决'Invalid column type Null at index: 1, name: pending'错误
- 解决'invalid args projectId for command get_templates_by_project'错误
This commit is contained in:
imeepos 2025-07-15 13:18:04 +08:00
parent 9aa2cdd49f
commit 8f1355ba16
3 changed files with 17 additions and 17 deletions

View File

@ -511,11 +511,11 @@ impl VideoClassificationRepository {
))?; ))?;
let task_stats = stmt.query_row([&pending_json, &uploading_json, &analyzing_json, &completed_json, &failed_json], |row| { let task_stats = stmt.query_row([&pending_json, &uploading_json, &analyzing_json, &completed_json, &failed_json], |row| {
let total: i32 = row.get(0)?; let total: i32 = row.get::<_, Option<i32>>(0)?.unwrap_or(0);
let pending: i32 = row.get(1)?; let pending: i32 = row.get::<_, Option<i32>>(1)?.unwrap_or(0);
let processing: i32 = row.get(2)?; let processing: i32 = row.get::<_, Option<i32>>(2)?.unwrap_or(0);
let completed: i32 = row.get(3)?; let completed: i32 = row.get::<_, Option<i32>>(3)?.unwrap_or(0);
let failed: i32 = row.get(4)?; let failed: i32 = row.get::<_, Option<i32>>(4)?.unwrap_or(0);
Ok((total, pending, processing, completed, failed)) Ok((total, pending, processing, completed, failed))
})?; })?;
@ -530,7 +530,7 @@ impl VideoClassificationRepository {
let record_stats = stmt.query_row([], |row| { let record_stats = stmt.query_row([], |row| {
Ok(( Ok((
row.get::<_, i32>(0)?, row.get::<_, Option<i32>>(0)?.unwrap_or(0),
row.get::<_, Option<f64>>(1)?.unwrap_or(0.0), row.get::<_, Option<f64>>(1)?.unwrap_or(0.0),
row.get::<_, Option<f64>>(2)?.unwrap_or(0.0), row.get::<_, Option<f64>>(2)?.unwrap_or(0.0),
)) ))

View File

@ -96,12 +96,12 @@ pub async fn list_project_template_bindings(
/// 获取项目的模板列表 /// 获取项目的模板列表
#[tauri::command] #[tauri::command]
pub async fn get_templates_by_project( pub async fn get_templates_by_project(
project_id: String, projectId: String,
state: State<'_, AppState>, state: State<'_, AppState>,
) -> Result<Vec<ProjectTemplateBindingDetail>, String> { ) -> Result<Vec<ProjectTemplateBindingDetail>, String> {
let service = create_service(&state)?; let service = create_service(&state)?;
service.get_templates_by_project(&project_id) service.get_templates_by_project(&projectId)
.await .await
.map_err(|e| e.to_string()) .map_err(|e| e.to_string())
} }
@ -109,12 +109,12 @@ pub async fn get_templates_by_project(
/// 获取模板的项目列表 /// 获取模板的项目列表
#[tauri::command] #[tauri::command]
pub async fn get_projects_by_template( pub async fn get_projects_by_template(
template_id: String, templateId: String,
state: State<'_, AppState>, state: State<'_, AppState>,
) -> Result<Vec<ProjectTemplateBindingDetail>, String> { ) -> Result<Vec<ProjectTemplateBindingDetail>, String> {
let service = create_service(&state)?; let service = create_service(&state)?;
service.get_projects_by_template(&template_id) service.get_projects_by_template(&templateId)
.await .await
.map_err(|e| e.to_string()) .map_err(|e| e.to_string())
} }
@ -174,12 +174,12 @@ pub async fn deactivate_project_template_binding(
/// 获取项目的主要模板绑定 /// 获取项目的主要模板绑定
#[tauri::command] #[tauri::command]
pub async fn get_primary_template_binding_for_project( pub async fn get_primary_template_binding_for_project(
project_id: String, projectId: String,
state: State<'_, AppState>, state: State<'_, AppState>,
) -> Result<Option<ProjectTemplateBinding>, String> { ) -> Result<Option<ProjectTemplateBinding>, String> {
let service = create_service(&state)?; let service = create_service(&state)?;
service.get_primary_binding_for_project(&project_id) service.get_primary_binding_for_project(&projectId)
.await .await
.map_err(|e| e.to_string()) .map_err(|e| e.to_string())
} }
@ -187,13 +187,13 @@ pub async fn get_primary_template_binding_for_project(
/// 设置项目的主要模板 /// 设置项目的主要模板
#[tauri::command] #[tauri::command]
pub async fn set_primary_template_for_project( pub async fn set_primary_template_for_project(
project_id: String, projectId: String,
template_id: String, templateId: String,
state: State<'_, AppState>, state: State<'_, AppState>,
) -> Result<ProjectTemplateBinding, String> { ) -> Result<ProjectTemplateBinding, String> {
let service = create_service(&state)?; let service = create_service(&state)?;
service.set_primary_template(&project_id, &template_id) service.set_primary_template(&projectId, &templateId)
.await .await
.map_err(|e| e.to_string()) .map_err(|e| e.to_string())
} }

View File

@ -95,7 +95,7 @@ export class ProjectTemplateBindingService {
*/ */
static async getTemplatesByProject(projectId: string): Promise<ProjectTemplateBindingDetail[]> { static async getTemplatesByProject(projectId: string): Promise<ProjectTemplateBindingDetail[]> {
try { try {
return await invoke('get_templates_by_project', { project_id: projectId }); return await invoke('get_templates_by_project', { projectId });
} catch (error) { } catch (error) {
console.error('获取项目模板列表失败:', error); console.error('获取项目模板列表失败:', error);
throw new Error(`获取项目模板列表失败: ${error}`); throw new Error(`获取项目模板列表失败: ${error}`);
@ -107,7 +107,7 @@ export class ProjectTemplateBindingService {
*/ */
static async getProjectsByTemplate(templateId: string): Promise<ProjectTemplateBindingDetail[]> { static async getProjectsByTemplate(templateId: string): Promise<ProjectTemplateBindingDetail[]> {
try { try {
return await invoke('get_projects_by_template', { template_id: templateId }); return await invoke('get_projects_by_template', { templateId });
} catch (error) { } catch (error) {
console.error('获取模板项目列表失败:', error); console.error('获取模板项目列表失败:', error);
throw new Error(`获取模板项目列表失败: ${error}`); throw new Error(`获取模板项目列表失败: ${error}`);