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:
parent
ba34481052
commit
a1ccde6b89
|
|
@ -71,7 +71,9 @@ impl ModelService {
|
||||||
repository: &ModelRepository,
|
repository: &ModelRepository,
|
||||||
id: &str,
|
id: &str,
|
||||||
) -> Result<Option<Model>> {
|
) -> Result<Option<Model>> {
|
||||||
repository.get_by_id(id)
|
// 使用 get_basic_by_id 避免死锁问题
|
||||||
|
// 在MaterialCard等组件中只需要基本信息,不需要照片
|
||||||
|
repository.get_basic_by_id(id)
|
||||||
.map_err(|e| anyhow!("获取模特详情失败: {}", e))
|
.map_err(|e| anyhow!("获取模特详情失败: {}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,14 +29,29 @@ pub async fn get_model_by_id(
|
||||||
state: State<'_, AppState>,
|
state: State<'_, AppState>,
|
||||||
id: String,
|
id: String,
|
||||||
) -> Result<Option<Model>, String> {
|
) -> Result<Option<Model>, String> {
|
||||||
let repository_guard = state.get_model_repository()
|
println!("get_model_by_id 命令开始执行,ID: {}", id);
|
||||||
.map_err(|e| format!("获取模特仓库失败: {}", e))?;
|
|
||||||
|
|
||||||
let repository = repository_guard.as_ref()
|
|
||||||
.ok_or("模特仓库未初始化")?;
|
|
||||||
|
|
||||||
ModelService::get_model_by_id(repository, &id)
|
let repository_guard = state.get_model_repository()
|
||||||
.map_err(|e| e.to_string())
|
.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
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 获取所有模特命令
|
/// 获取所有模特命令
|
||||||
|
|
|
||||||
|
|
@ -108,25 +108,44 @@ export const MaterialCard: React.FC<MaterialCardProps> = ({ material, onEdit, on
|
||||||
|
|
||||||
// 获取关联的模特信息
|
// 获取关联的模特信息
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let isMounted = true; // 用于防止组件卸载后设置状态
|
||||||
|
|
||||||
const fetchAssociatedModel = async () => {
|
const fetchAssociatedModel = async () => {
|
||||||
if (!material.model_id) {
|
if (!material.model_id) {
|
||||||
setAssociatedModel(null);
|
if (isMounted) {
|
||||||
|
setAssociatedModel(null);
|
||||||
|
setLoadingModel(false);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoadingModel(true);
|
if (isMounted) {
|
||||||
|
setLoadingModel(true);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const model = await invoke<Model>('get_model_by_id', { id: material.model_id });
|
const model = await invoke<Model>('get_model_by_id', { id: material.model_id });
|
||||||
setAssociatedModel(model);
|
if (isMounted) {
|
||||||
|
setAssociatedModel(model);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取关联模特失败:', error);
|
console.error('获取关联模特失败:', error);
|
||||||
setAssociatedModel(null);
|
if (isMounted) {
|
||||||
|
setAssociatedModel(null);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
setLoadingModel(false);
|
if (isMounted) {
|
||||||
|
setLoadingModel(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchAssociatedModel();
|
fetchAssociatedModel();
|
||||||
|
|
||||||
|
// 清理函数
|
||||||
|
return () => {
|
||||||
|
isMounted = false;
|
||||||
|
};
|
||||||
}, [material.model_id]);
|
}, [material.model_id]);
|
||||||
|
|
||||||
// 加载切分片段
|
// 加载切分片段
|
||||||
|
|
|
||||||
|
|
@ -116,16 +116,17 @@ export const ProjectTemplateBindingList: React.FC<ProjectTemplateBindingListProp
|
||||||
};
|
};
|
||||||
|
|
||||||
// 执行删除
|
// 执行删除
|
||||||
const executeDelete = () => {
|
const executeDelete = async () => {
|
||||||
try {
|
try {
|
||||||
if (deleteConfirm.isBatch && onBatchDelete) {
|
if (deleteConfirm.isBatch && onBatchDelete) {
|
||||||
onBatchDelete(selectedIds);
|
await onBatchDelete(selectedIds);
|
||||||
success('批量删除成功', `已删除 ${selectedIds.length} 个绑定`);
|
success('批量删除成功', `已删除 ${selectedIds.length} 个绑定`);
|
||||||
} else if (deleteConfirm.id && onDelete) {
|
} else if (deleteConfirm.id && onDelete) {
|
||||||
onDelete(deleteConfirm.id);
|
await onDelete(deleteConfirm.id);
|
||||||
success('删除成功', `绑定"${deleteConfirm.name}"已删除`);
|
success('删除成功', `绑定"${deleteConfirm.name}"已删除`);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.error('删除操作失败:', err);
|
||||||
error('删除失败', err instanceof Error ? err.message : '未知错误');
|
error('删除失败', err instanceof Error ? err.message : '未知错误');
|
||||||
} finally {
|
} finally {
|
||||||
setDeleteConfirm({ isOpen: false });
|
setDeleteConfirm({ isOpen: false });
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,10 @@ export class ProjectTemplateBindingService {
|
||||||
*/
|
*/
|
||||||
static async batchDeleteBindings(request: BatchDeleteProjectTemplateBindingRequest): Promise<number> {
|
static async batchDeleteBindings(request: BatchDeleteProjectTemplateBindingRequest): Promise<number> {
|
||||||
try {
|
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) {
|
} catch (error) {
|
||||||
console.error('批量删除项目-模板绑定失败:', error);
|
console.error('批量删除项目-模板绑定失败:', error);
|
||||||
throw new Error(`批量删除绑定失败: ${error}`);
|
throw new Error(`批量删除绑定失败: ${error}`);
|
||||||
|
|
|
||||||
|
|
@ -235,20 +235,24 @@ export const useProjectTemplateBindingStore = create<ProjectTemplateBindingState
|
||||||
|
|
||||||
// 批量删除绑定
|
// 批量删除绑定
|
||||||
batchDeleteBindings: async (ids: string[]) => {
|
batchDeleteBindings: async (ids: string[]) => {
|
||||||
|
console.log('Store: 开始批量删除绑定, IDs:', ids);
|
||||||
set({ loading: true, error: null });
|
set({ loading: true, error: null });
|
||||||
try {
|
try {
|
||||||
await ProjectTemplateBindingService.batchDeleteBindings({ binding_ids: ids });
|
const deletedCount = await ProjectTemplateBindingService.batchDeleteBindings({ binding_ids: ids });
|
||||||
|
console.log('Store: 批量删除成功, 删除数量:', deletedCount);
|
||||||
const currentBindings = get().bindings;
|
const currentBindings = get().bindings;
|
||||||
set({
|
set({
|
||||||
bindings: currentBindings.filter(binding => !ids.includes(binding.id)),
|
bindings: currentBindings.filter(binding => !ids.includes(binding.id)),
|
||||||
selectedBindingIds: [],
|
selectedBindingIds: [],
|
||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
set({
|
console.error('Store: 批量删除失败:', error);
|
||||||
|
set({
|
||||||
error: error instanceof Error ? error.message : '批量删除绑定失败',
|
error: error instanceof Error ? error.message : '批量删除绑定失败',
|
||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
|
throw error; // 重新抛出错误以便上层处理
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue