webapp/src/context/TasksContext.tsx

185 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, {
createContext,
useState,
useContext,
ReactNode,
useEffect,
} from 'react';
import { Task } from '../types/task';
import {
AppConfig,
LocationOption,
PayloadOption,
RobotActionOption,
} from '../types/config';
import {
getConfig,
getSettings,
executeTask,
clearCachedConfig,
} from '../services/configService';
interface TasksContextData {
tasks: Task[];
locations: LocationOption[];
locationsBays: LocationOption[];
payloads: PayloadOption[];
robotActions: RobotActionOption[];
getTaskById: (id: string) => Task | undefined;
updateTask: (updatedTask: Task) => void;
runTask: (id: string) => void;
refreshConfig: () => Promise<void>;
isConfigLoaded: boolean;
}
const TasksContext = createContext<TasksContextData>({} as TasksContextData);
export const TasksProvider: React.FC<{ children: ReactNode }> = ({
children,
}) => {
const [tasks, setTasks] = useState<Task[]>([]);
const [locations, setLocations] = useState<LocationOption[]>([]);
const [locationsBays, setLocationsBays] = useState<LocationOption[]>([]);
const [payloads, setPayloads] = useState<PayloadOption[]>([]);
const [robotActions, setRobotActions] = useState<RobotActionOption[]>([]);
const [isConfigLoaded, setIsConfigLoaded] = useState(false);
// 组件初始化时加载配置
useEffect(() => {
const loadConfig = async () => {
try {
// 清除缓存以确保加载最新的配置
await clearCachedConfig();
const config = await getConfig();
if (config) {
applyConfig(config);
setIsConfigLoaded(true);
console.log('成功加载配置,任务数量:', config.tasks?.length || 0);
} else {
console.log('没有找到配置文件,使用空数据');
// 使用空数据而不是mock数据
applyConfig({
version: '0.0.0',
locations: [],
locationsBays: [],
payloads: [],
robotActions: [],
tasks: [],
});
setIsConfigLoaded(false);
}
} catch (error) {
console.error('加载配置失败:', error);
// 发生错误时也使用空数据
applyConfig({
version: '0.0.0',
locations: [],
locationsBays: [],
payloads: [],
robotActions: [],
tasks: [],
});
setIsConfigLoaded(false);
}
};
loadConfig();
}, []);
const applyConfig = (config: AppConfig) => {
setTasks(config.tasks || []);
setLocations(config.locations || []);
setLocationsBays(config.locationsBays || []);
setPayloads(config.payloads || []);
setRobotActions(config.robotActions || []);
};
const refreshConfig = async () => {
try {
// 刷新时也清除缓存
await clearCachedConfig();
const config = await getConfig();
if (config) {
applyConfig(config);
setIsConfigLoaded(true);
console.log('成功刷新配置,任务数量:', config.tasks?.length || 0);
} else {
console.log('刷新配置时没有找到配置文件');
setIsConfigLoaded(false);
}
} catch (error) {
console.error('刷新配置失败:', error);
setIsConfigLoaded(false);
}
};
const getTaskById = (id: string) => {
return tasks.find(task => task.id === id);
};
const updateTask = (updatedTask: Task) => {
setTasks(prevTasks =>
prevTasks.map(task => (task.id === updatedTask.id ? updatedTask : task)),
);
};
const runTask = async (id: string) => {
const task = getTaskById(id);
if (!task) return;
// 更新任务状态为运行中
setTasks(prevTasks =>
prevTasks.map(t => (t.id === id ? { ...t, status: 'RUNNING' } : t)),
);
try {
// 获取服务器设置并发送任务执行请求
const settings = await getSettings();
if (settings.serverUrl) {
await executeTask(settings.serverUrl, task.id, {
name: task.name,
parameters: task.parameters,
});
}
// 模拟任务完成实际项目中应该通过WebSocket或轮询获取任务状态
setTimeout(() => {
setTasks(prevTasks =>
prevTasks.map(t => (t.id === id ? { ...t, status: 'COMPLETED' } : t)),
);
}, 5000);
} catch (error) {
console.error('任务执行失败:', error);
// 任务执行失败,更新状态为错误
setTasks(prevTasks =>
prevTasks.map(t => (t.id === id ? { ...t, status: 'ERROR' } : t)),
);
}
};
return (
<TasksContext.Provider
value={{
tasks,
locations,
locationsBays,
payloads,
robotActions,
getTaskById,
updateTask,
runTask,
refreshConfig,
isConfigLoaded,
}}
>
{children}
</TasksContext.Provider>
);
};
export function useTasks() {
return useContext(TasksContext);
}