fix: 修复get_model_by_id死锁问题和批量删除模板功能

- 修复ModelService中get_model_by_id使用get_basic_by_id避免数据库死锁
- 解决MaterialCard组件中关联模特一直加载中的问题
- 修复ProjectTemplateBindingList中executeDelete函数的异步处理
- 在get_model_by_id命令中添加详细的调试日志
- 在MaterialCard中添加组件卸载时的状态清理机制
- 在批量删除服务中添加调试日志追踪问题
- 解决页面切换时loading状态不清除的问题
This commit is contained in:
imeepos 2025-07-15 13:49:43 +08:00
parent ba34481052
commit a1ccde6b89
6 changed files with 66 additions and 22 deletions

View File

@ -71,7 +71,9 @@ impl ModelService {
repository: &ModelRepository,
id: &str,
) -> Result<Option<Model>> {
repository.get_by_id(id)
// 使用 get_basic_by_id 避免死锁问题
// 在MaterialCard等组件中只需要基本信息不需要照片
repository.get_basic_by_id(id)
.map_err(|e| anyhow!("获取模特详情失败: {}", e))
}

View File

@ -29,14 +29,29 @@ pub async fn get_model_by_id(
state: State<'_, AppState>,
id: String,
) -> Result<Option<Model>, String> {
let repository_guard = state.get_model_repository()
.map_err(|e| format!("获取模特仓库失败: {}", e))?;
let repository = repository_guard.as_ref()
.ok_or("模特仓库未初始化")?;
println!("get_model_by_id 命令开始执行ID: {}", id);
ModelService::get_model_by_id(repository, &id)
.map_err(|e| e.to_string())
let repository_guard = state.get_model_repository()
.map_err(|e| {
println!("获取模特仓库失败: {}", e);
format!("获取模特仓库失败: {}", e)
})?;
let repository = repository_guard.as_ref()
.ok_or_else(|| {
println!("模特仓库未初始化");
"模特仓库未初始化".to_string()
})?;
println!("调用 ModelService::get_model_by_id");
let result = ModelService::get_model_by_id(repository, &id)
.map_err(|e| {
println!("ModelService::get_model_by_id 失败: {}", e);
e.to_string()
});
println!("get_model_by_id 命令执行完成,结果: {:?}", result.is_ok());
result
}
/// 获取所有模特命令

View File

@ -108,25 +108,44 @@ export const MaterialCard: React.FC<MaterialCardProps> = ({ material, onEdit, on
// 获取关联的模特信息
useEffect(() => {
let isMounted = true; // 用于防止组件卸载后设置状态
const fetchAssociatedModel = async () => {
if (!material.model_id) {
setAssociatedModel(null);
if (isMounted) {
setAssociatedModel(null);
setLoadingModel(false);
}
return;
}
setLoadingModel(true);
if (isMounted) {
setLoadingModel(true);
}
try {
const model = await invoke<Model>('get_model_by_id', { id: material.model_id });
setAssociatedModel(model);
if (isMounted) {
setAssociatedModel(model);
}
} catch (error) {
console.error('获取关联模特失败:', error);
setAssociatedModel(null);
if (isMounted) {
setAssociatedModel(null);
}
} finally {
setLoadingModel(false);
if (isMounted) {
setLoadingModel(false);
}
}
};
fetchAssociatedModel();
// 清理函数
return () => {
isMounted = false;
};
}, [material.model_id]);
// 加载切分片段

View File

@ -116,16 +116,17 @@ export const ProjectTemplateBindingList: React.FC<ProjectTemplateBindingListProp
};
// 执行删除
const executeDelete = () => {
const executeDelete = async () => {
try {
if (deleteConfirm.isBatch && onBatchDelete) {
onBatchDelete(selectedIds);
await onBatchDelete(selectedIds);
success('批量删除成功', `已删除 ${selectedIds.length} 个绑定`);
} else if (deleteConfirm.id && onDelete) {
onDelete(deleteConfirm.id);
await onDelete(deleteConfirm.id);
success('删除成功', `绑定"${deleteConfirm.name}"已删除`);
}
} catch (err) {
console.error('删除操作失败:', err);
error('删除失败', err instanceof Error ? err.message : '未知错误');
} finally {
setDeleteConfirm({ isOpen: false });

View File

@ -131,7 +131,10 @@ export class ProjectTemplateBindingService {
*/
static async batchDeleteBindings(request: BatchDeleteProjectTemplateBindingRequest): Promise<number> {
try {
return await invoke('batch_delete_project_template_bindings', { request });
console.log('Service: 发送批量删除请求:', request);
const result = await invoke<number>('batch_delete_project_template_bindings', { request });
console.log('Service: 批量删除响应:', result);
return result;
} catch (error) {
console.error('批量删除项目-模板绑定失败:', error);
throw new Error(`批量删除绑定失败: ${error}`);

View File

@ -235,20 +235,24 @@ export const useProjectTemplateBindingStore = create<ProjectTemplateBindingState
// 批量删除绑定
batchDeleteBindings: async (ids: string[]) => {
console.log('Store: 开始批量删除绑定, IDs:', ids);
set({ loading: true, error: null });
try {
await ProjectTemplateBindingService.batchDeleteBindings({ binding_ids: ids });
const deletedCount = await ProjectTemplateBindingService.batchDeleteBindings({ binding_ids: ids });
console.log('Store: 批量删除成功, 删除数量:', deletedCount);
const currentBindings = get().bindings;
set({
set({
bindings: currentBindings.filter(binding => !ids.includes(binding.id)),
selectedBindingIds: [],
loading: false
loading: false
});
} catch (error) {
set({
console.error('Store: 批量删除失败:', error);
set({
error: error instanceof Error ? error.message : '批量删除绑定失败',
loading: false
loading: false
});
throw error; // 重新抛出错误以便上层处理
}
},