feat:新增起点,终点,库位 ,机器人动作 下拉选择功能。

This commit is contained in:
xudan 2025-07-21 15:59:44 +08:00
parent 5ecb12a679
commit a4372a12fc
4 changed files with 122 additions and 190 deletions

View File

@ -21,12 +21,15 @@ const TaskCard: React.FC<TaskCardProps> = ({ task, onPress }) => {
return ( return (
<Card style={styles.card} onPress={() => onPress(task.id)}> <Card style={styles.card} onPress={() => onPress(task.id)}>
<Card.Content> <Card.Content>
<Text variant="titleMedium" style={styles.title}>{task.name}</Text> <Text variant="titleMedium" style={styles.title}>
<Chip {task.name}
icon="information" </Text>
<Chip
icon="information"
mode="outlined" mode="outlined"
selectedColor={statusColors[task.status]} selectedColor={statusColors[task.status]}
style={[styles.chip, {backgroundColor: theme.colors.surface}]} style={[styles.chip, { backgroundColor: theme.colors.surface }]}
textStyle={{ fontSize: 12 }}
> >
{task.status} {task.status}
</Chip> </Chip>
@ -46,7 +49,7 @@ const styles = StyleSheet.create({
}, },
chip: { chip: {
alignSelf: 'flex-start', alignSelf: 'flex-start',
} },
}); });
export default TaskCard; export default TaskCard;

View File

@ -1,9 +1,8 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { View, StyleSheet, ScrollView } from 'react-native'; import { View, StyleSheet, ScrollView } from 'react-native';
import { TextInput } from 'react-native-paper'; import { TextInput, Menu, Button, Divider, Text } from 'react-native-paper';
import DropDown from "react-native-paper-dropdown";
import { Task, RobotAction } from '../types/task'; import { Task, RobotAction } from '../types/task';
import { LOCATIONS, ROBOT_ACTIONS, PAYLOADS } from '../data/mockData'; import { LOCATIONS, ROBOT_ACTIONS, PAYLOADS, LOCATIONS_BAYS } from '../data/mockData';
interface TaskFormProps { interface TaskFormProps {
task: Task; task: Task;
@ -11,138 +10,91 @@ interface TaskFormProps {
} }
const TaskForm: React.FC<TaskFormProps> = ({ task, onTaskChange }) => { const TaskForm: React.FC<TaskFormProps> = ({ task, onTaskChange }) => {
const [showStartLocation, setShowStartLocation] = useState(false); const [menuVisible, setMenuVisible] = useState<{ [key: string]: boolean }>({});
const [showEndLocation, setShowEndLocation] = useState(false);
const [showRobotAction, setShowRobotAction] = useState(false);
const [showPayload, setShowPayload] = useState(false);
const handleParamChange = (field: string, value: string | RobotAction) => { const openMenu = (name: string) => setMenuVisible(prev => ({ ...prev, [name]: true }));
const updatedTask = { const closeMenu = (name: string) => setMenuVisible(prev => ({ ...prev, [name]: false }));
...task,
parameters: { const handleParamChange = (field: string, value: string | RobotAction) => {
...task.parameters, const updatedTask = {
[field]: value, ...task,
}, parameters: {
...task.parameters,
[field]: value,
},
};
onTaskChange(updatedTask);
}; };
onTaskChange(updatedTask);
};
return ( const renderDropdown = (
<ScrollView contentContainerStyle={styles.container}> name: string,
<TextInput label: string,
label="任务名称" value: string,
value={task.name} items: { label: string, value: string }[]
onChangeText={text => onTaskChange({ ...task, name: text })} ) => (
style={styles.input} <View style={styles.input}>
mode="outlined" <Text>{label}</Text>
/> <Menu
visible={menuVisible[name]}
onDismiss={() => closeMenu(name)}
anchor={
<Button onPress={() => openMenu(name)} mode="outlined">
{value || `选择${label}`}
</Button>
}
>
<ScrollView style={{ maxHeight: 200 }}>
{items.map(item => (
<Menu.Item
key={item.value}
onPress={() => {
handleParamChange(name, item.value);
closeMenu(name);
}}
title={item.label}
/>
))}
</ScrollView>
</Menu>
</View>
);
{/* <DropDown return (
label={"起点"} <ScrollView contentContainerStyle={styles.container}>
mode={"outlined"} <TextInput
visible={showStartLocation} label="任务名称"
showDropDown={() => setShowStartLocation(true)} value={task.name}
onDismiss={() => setShowStartLocation(false)} onChangeText={text => onTaskChange({ ...task, name: text })}
value={task.parameters.startLocation} style={styles.input}
setValue={(value) => handleParamChange('startLocation', value)} mode="outlined"
list={LOCATIONS.map((location) => ({ />
label: location.label,
value: location.value,
}))}
dropDownStyle={styles.input}
/> */}
<TextInput
label="起点"
value={task.parameters.startLocation}
onChangeText={text => handleParamChange('startLocation', text)}
style={styles.input}
mode="outlined"
/>
{/* <DropDown {renderDropdown('startLocation', '起点', task.parameters.startLocation, LOCATIONS)}
label={"终点"} {renderDropdown('endLocation', '终点', task.parameters.endLocation, LOCATIONS)}
mode={"outlined"}
visible={showEndLocation} <TextInput
showDropDown={() => setShowEndLocation(true)} label="途经点 (可选)"
onDismiss={() => setShowEndLocation(false)} value={task.parameters.waypoint || ''}
value={task.parameters.endLocation} onChangeText={text => handleParamChange('waypoint', text)}
setValue={(value) => handleParamChange('endLocation', value)} style={styles.input}
list={LOCATIONS.map((location) => ({ mode="outlined"
label: location.label, />
value: location.value,
}))} {renderDropdown('robotAction', '机器人动作', task.parameters.robotAction, ROBOT_ACTIONS)}
dropDownStyle={styles.input} {renderDropdown('payload', '载荷', task.parameters.payload, PAYLOADS)}
/> */} {renderDropdown('locationBay', '库位', task.parameters.locationBay, LOCATIONS_BAYS)}
<TextInput
label="终点"
value={task.parameters.endLocation}
onChangeText={text => handleParamChange('endLocation', text)}
style={styles.input}
mode="outlined"
/>
<TextInput
label="途经点 (可选)"
value={task.parameters.waypoint || ''}
onChangeText={text => handleParamChange('waypoint', text)}
style={styles.input}
mode="outlined"
/>
{/* <DropDown
label={"机器人动作"}
mode={"outlined"}
visible={showRobotAction}
showDropDown={() => setShowRobotAction(true)}
onDismiss={() => setShowRobotAction(false)}
value={task.parameters.robotAction}
setValue={(value) => handleParamChange('robotAction', value)}
list={ROBOT_ACTIONS.map((action) => ({
label: action.label,
value: action.value,
}))}
dropDownStyle={styles.input}
/> */}
<TextInput
label="机器人动作"
value={task.parameters.robotAction}
onChangeText={text => handleParamChange('robotAction', text)}
style={styles.input}
mode="outlined"
/>
{/* <DropDown </ScrollView>
label={"载荷"} );
mode={"outlined"}
visible={showPayload}
showDropDown={() => setShowPayload(true)}
onDismiss={() => setShowPayload(false)}
value={task.parameters.payload}
setValue={(value) => handleParamChange('payload', value)}
list={PAYLOADS.map((payload) => ({
label: payload.label,
value: payload.value,
}))}
dropDownStyle={styles.input}
/> */}
<TextInput
label="载荷"
value={task.parameters.payload}
onChangeText={text => handleParamChange('payload', text)}
style={styles.input}
mode="outlined"
/>
</ScrollView>
);
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
padding: 16, padding: 16,
}, },
input: { input: {
marginBottom: 16, marginBottom: 16,
}, },
}); });
export default TaskForm; export default TaskForm;

View File

@ -1,23 +1,25 @@
import { Task, RobotAction } from '../types/task'; import { Task, RobotAction } from '../types/task';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
export const LOCATIONS = [ export const LOCATIONS = Array.from({ length: 100 }, (_, i) => ({
{ label: '炉前缓存区', value: '炉前缓存区' }, label: `AP-${i + 1}`,
{ label: '热处理上料交接区', value: '热处理上料交接区' }, value: `AP-${i + 1}`,
{ label: '空料架缓存区', value: '空料架缓存区' }, }));
{ label: '焊接空料架交接区', value: '焊接空料架交接区' },
{ label: '热后区', value: '热后区' },
{ label: 'ALD上料区', value: 'ALD上料区' },
{ label: '空车区', value: '空车区' },
];
export const ROBOT_ACTIONS: { label: string; value: RobotAction }[] = [ export const ROBOT_ACTIONS: { label: string; value: RobotAction }[] = [
{ label: '运输', value: 'TRANSPORT' }, { label: '运输', value: 'TRANSPORT' },
{ label: '取货', value: 'PICKUP' }, { label: '取货', value: 'PICKUP' },
{ label: '卸货', value: 'DROPOFF' }, { label: '卸货', value: 'DROPOFF' },
{ label: '等待', value: 'WAIT' }, { label: '等待', value: 'WAIT' },
{ label: '充电', value: 'CHARGE' },
{ label: '清洁', value: 'CLEAN' },
]; ];
export const LOCATIONS_BAYS = Array.from({ length: 100 }, (_, i) => ({
label: `AS2_2_${String(i + 1).padStart(3, '0')}`,
value: `AS2_2_${String(i + 1).padStart(3, '0')}`,
}));
export const PAYLOADS = [ export const PAYLOADS = [
{ label: '满料架-A1', value: '满料架-A1' }, { label: '满料架-A1', value: '满料架-A1' },
{ label: '空料架-B2', value: '空料架-B2' }, { label: '空料架-B2', value: '空料架-B2' },
@ -25,53 +27,27 @@ export const PAYLOADS = [
{ label: '空车', value: '空车' }, { label: '空车', value: '空车' },
]; ];
export const MOCK_TASKS: Task[] = [ const getRandomElement = <T>(arr: T[]): T => arr[Math.floor(Math.random() * arr.length)];
{
id: uuidv4(), export const MOCK_TASKS: Task[] = Array.from({ length: 15 }, (_, i) => {
name: '炉前缓存区到热处理上料交接区运输', const startLocation = getRandomElement(LOCATIONS);
status: 'IDLE', const endLocation = getRandomElement(LOCATIONS.filter(l => l.value !== startLocation.value));
createdAt: new Date().toISOString(), const robotAction = getRandomElement(ROBOT_ACTIONS);
parameters: { const payload = getRandomElement(PAYLOADS);
startLocation: '炉前缓存区', const statusOptions: Task['status'][] = ['IDLE', 'RUNNING', 'COMPLETED', 'ERROR'];
endLocation: '热处理上料交接区', const status = getRandomElement(statusOptions);
robotAction: 'TRANSPORT',
payload: '满料架-A1', return {
}, id: uuidv4(),
}, name: `任务 ${i + 1}: 从 ${startLocation.label}${endLocation.label}`,
{ status: status,
id: uuidv4(), createdAt: new Date(new Date().getTime() - Math.random() * 1000 * 60 * 60 * 24).toISOString(),
name: '空料架到焊接空料架交接区运输', parameters: {
status: 'RUNNING', startLocation: startLocation.value,
createdAt: new Date().toISOString(), endLocation: endLocation.value,
parameters: { robotAction: robotAction.value,
startLocation: '空料架缓存区', payload: payload.value,
endLocation: '焊接空料架交接区', locationBay: getRandomElement(LOCATIONS_BAYS).value,
robotAction: 'TRANSPORT', },
payload: '空料架-B2', };
}, });
},
{
id: uuidv4(),
name: '热后空料架返回交接区',
status: 'COMPLETED',
createdAt: new Date().toISOString(),
parameters: {
startLocation: '热后区',
endLocation: '空料架缓存区',
robotAction: 'TRANSPORT',
payload: '空料架-C3',
},
},
{
id: uuidv4(),
name: 'ALD上料空车运输到空车区',
status: 'IDLE',
createdAt: new Date().toISOString(),
parameters: {
startLocation: 'ALD上料区',
endLocation: '空车区',
robotAction: 'TRANSPORT',
payload: '空车',
},
},
];

View File

@ -11,6 +11,7 @@ export interface TaskParameters {
waypoint?: string; // 途经点 (可选) waypoint?: string; // 途经点 (可选)
robotAction: RobotAction; // 机器人动作 robotAction: RobotAction; // 机器人动作
payload: string; // 载荷,比如 '空料架' 或具体的物料ID payload: string; // 载荷,比如 '空料架' 或具体的物料ID
locationBay?: string; // 库位 (可选)
} }
// 核心任务对象 // 核心任务对象