webapp/src/context/TasksContext.tsx

185 lines
4.9 KiB
TypeScript
Raw Normal View History

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);
}