diff --git a/src/components/TaskCard.tsx b/src/components/TaskCard.tsx index ab15b66..6aac156 100644 --- a/src/components/TaskCard.tsx +++ b/src/components/TaskCard.tsx @@ -21,12 +21,15 @@ const TaskCard: React.FC = ({ task, onPress }) => { return ( onPress(task.id)}> - {task.name} - + {task.name} + + {task.status} @@ -46,7 +49,7 @@ const styles = StyleSheet.create({ }, chip: { alignSelf: 'flex-start', - } + }, }); export default TaskCard; diff --git a/src/components/TaskForm.tsx b/src/components/TaskForm.tsx index fe87ba0..b4c12c9 100644 --- a/src/components/TaskForm.tsx +++ b/src/components/TaskForm.tsx @@ -1,9 +1,8 @@ import React, { useState } from 'react'; import { View, StyleSheet, ScrollView } from 'react-native'; -import { TextInput } from 'react-native-paper'; -import DropDown from "react-native-paper-dropdown"; +import { TextInput, Menu, Button, Divider, Text } from 'react-native-paper'; 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 { task: Task; @@ -11,138 +10,91 @@ interface TaskFormProps { } const TaskForm: React.FC = ({ task, onTaskChange }) => { - const [showStartLocation, setShowStartLocation] = useState(false); - const [showEndLocation, setShowEndLocation] = useState(false); - const [showRobotAction, setShowRobotAction] = useState(false); - const [showPayload, setShowPayload] = useState(false); + const [menuVisible, setMenuVisible] = useState<{ [key: string]: boolean }>({}); - const handleParamChange = (field: string, value: string | RobotAction) => { - const updatedTask = { - ...task, - parameters: { - ...task.parameters, - [field]: value, - }, + const openMenu = (name: string) => setMenuVisible(prev => ({ ...prev, [name]: true })); + const closeMenu = (name: string) => setMenuVisible(prev => ({ ...prev, [name]: false })); + + const handleParamChange = (field: string, value: string | RobotAction) => { + const updatedTask = { + ...task, + parameters: { + ...task.parameters, + [field]: value, + }, + }; + onTaskChange(updatedTask); }; - onTaskChange(updatedTask); - }; - return ( - - onTaskChange({ ...task, name: text })} - style={styles.input} - mode="outlined" - /> + const renderDropdown = ( + name: string, + label: string, + value: string, + items: { label: string, value: string }[] + ) => ( + + {label} + closeMenu(name)} + anchor={ + + } + > + + {items.map(item => ( + { + handleParamChange(name, item.value); + closeMenu(name); + }} + title={item.label} + /> + ))} + + + + ); - {/* setShowStartLocation(true)} - onDismiss={() => setShowStartLocation(false)} - value={task.parameters.startLocation} - setValue={(value) => handleParamChange('startLocation', value)} - list={LOCATIONS.map((location) => ({ - label: location.label, - value: location.value, - }))} - dropDownStyle={styles.input} - /> */} - handleParamChange('startLocation', text)} - style={styles.input} - mode="outlined" - /> + return ( + + onTaskChange({ ...task, name: text })} + style={styles.input} + mode="outlined" + /> - {/* setShowEndLocation(true)} - onDismiss={() => setShowEndLocation(false)} - value={task.parameters.endLocation} - setValue={(value) => handleParamChange('endLocation', value)} - list={LOCATIONS.map((location) => ({ - label: location.label, - value: location.value, - }))} - dropDownStyle={styles.input} - /> */} - handleParamChange('endLocation', text)} - style={styles.input} - mode="outlined" - /> - - handleParamChange('waypoint', text)} - style={styles.input} - mode="outlined" - /> - - {/* 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} - /> */} - handleParamChange('robotAction', text)} - style={styles.input} - mode="outlined" - /> + {renderDropdown('startLocation', '起点', task.parameters.startLocation, LOCATIONS)} + {renderDropdown('endLocation', '终点', task.parameters.endLocation, LOCATIONS)} + + handleParamChange('waypoint', text)} + style={styles.input} + mode="outlined" + /> + + {renderDropdown('robotAction', '机器人动作', task.parameters.robotAction, ROBOT_ACTIONS)} + {renderDropdown('payload', '载荷', task.parameters.payload, PAYLOADS)} + {renderDropdown('locationBay', '库位', task.parameters.locationBay, LOCATIONS_BAYS)} - {/* 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} - /> */} - handleParamChange('payload', text)} - style={styles.input} - mode="outlined" - /> - - ); + + ); }; const styles = StyleSheet.create({ - container: { - padding: 16, - }, - input: { - marginBottom: 16, - }, + container: { + padding: 16, + }, + input: { + marginBottom: 16, + }, }); export default TaskForm; diff --git a/src/data/mockData.ts b/src/data/mockData.ts index 44838aa..f4f4e35 100644 --- a/src/data/mockData.ts +++ b/src/data/mockData.ts @@ -1,23 +1,25 @@ import { Task, RobotAction } from '../types/task'; import { v4 as uuidv4 } from 'uuid'; -export const LOCATIONS = [ - { label: '炉前缓存区', value: '炉前缓存区' }, - { label: '热处理上料交接区', value: '热处理上料交接区' }, - { label: '空料架缓存区', value: '空料架缓存区' }, - { label: '焊接空料架交接区', value: '焊接空料架交接区' }, - { label: '热后区', value: '热后区' }, - { label: 'ALD上料区', value: 'ALD上料区' }, - { label: '空车区', value: '空车区' }, -]; +export const LOCATIONS = Array.from({ length: 100 }, (_, i) => ({ + label: `AP-${i + 1}`, + value: `AP-${i + 1}`, +})); export const ROBOT_ACTIONS: { label: string; value: RobotAction }[] = [ { label: '运输', value: 'TRANSPORT' }, { label: '取货', value: 'PICKUP' }, { label: '卸货', value: 'DROPOFF' }, { 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 = [ { label: '满料架-A1', value: '满料架-A1' }, { label: '空料架-B2', value: '空料架-B2' }, @@ -25,53 +27,27 @@ export const PAYLOADS = [ { label: '空车', value: '空车' }, ]; -export const MOCK_TASKS: Task[] = [ - { - id: uuidv4(), - name: '炉前缓存区到热处理上料交接区运输', - status: 'IDLE', - createdAt: new Date().toISOString(), - parameters: { - startLocation: '炉前缓存区', - endLocation: '热处理上料交接区', - robotAction: 'TRANSPORT', - payload: '满料架-A1', - }, - }, - { - id: uuidv4(), - name: '空料架到焊接空料架交接区运输', - status: 'RUNNING', - createdAt: new Date().toISOString(), - parameters: { - startLocation: '空料架缓存区', - endLocation: '焊接空料架交接区', - 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: '空车', - }, - }, -]; +const getRandomElement = (arr: T[]): T => arr[Math.floor(Math.random() * arr.length)]; + +export const MOCK_TASKS: Task[] = Array.from({ length: 15 }, (_, i) => { + const startLocation = getRandomElement(LOCATIONS); + const endLocation = getRandomElement(LOCATIONS.filter(l => l.value !== startLocation.value)); + const robotAction = getRandomElement(ROBOT_ACTIONS); + const payload = getRandomElement(PAYLOADS); + const statusOptions: Task['status'][] = ['IDLE', 'RUNNING', 'COMPLETED', 'ERROR']; + const status = getRandomElement(statusOptions); + + return { + id: uuidv4(), + name: `任务 ${i + 1}: 从 ${startLocation.label} 到 ${endLocation.label}`, + status: status, + createdAt: new Date(new Date().getTime() - Math.random() * 1000 * 60 * 60 * 24).toISOString(), + parameters: { + startLocation: startLocation.value, + endLocation: endLocation.value, + robotAction: robotAction.value, + payload: payload.value, + locationBay: getRandomElement(LOCATIONS_BAYS).value, + }, + }; +}); diff --git a/src/types/task.ts b/src/types/task.ts index 27e568c..f71b06f 100644 --- a/src/types/task.ts +++ b/src/types/task.ts @@ -11,6 +11,7 @@ export interface TaskParameters { waypoint?: string; // 途经点 (可选) robotAction: RobotAction; // 机器人动作 payload: string; // 载荷,比如 '空料架' 或具体的物料ID + locationBay?: string; // 库位 (可选) } // 核心任务对象