| | |
| | | "@tweenjs/tween.js": "^21.0.0", |
| | | "axios": "^1.7.4", |
| | | "date-fns": "^3.6.0", |
| | | "lodash": "^4.17.21", |
| | | "papaparse": "^5.4.1", |
| | | "pixi.js": "^7.4.0", |
| | | "react": "^18.3.0", |
| | |
| | | "@mui/icons-material": "^5.16.7", |
| | | "@mui/material": "^5.16.7", |
| | | "@mui/x-tree-view": "^7.16.0", |
| | | "@tweenjs/tween.js": "^21.0.0", |
| | | "axios": "^1.7.4", |
| | | "date-fns": "^3.6.0", |
| | | "lodash": "^4.17.21", |
| | | "papaparse": "^5.4.1", |
| | | "pixi.js": "^7.4.0", |
| | | "react": "^18.3.0", |
| | |
| | | "react-router-dom": "^6.26.1", |
| | | "react-syntax-highlighter": "^15.5.0", |
| | | "three": "^0.155.0", |
| | | "@tweenjs/tween.js": "^21.0.0", |
| | | "tweedle.js": "^2.1.0" |
| | | }, |
| | | "devDependencies": { |
| | |
| | | import React from 'react'; |
| | | import { useTranslate } from "react-admin"; |
| | | import { useForm, Controller } from 'react-hook-form'; |
| | | import { |
| | | Button, |
| | |
| | | ToggleButton, |
| | | ToggleButtonGroup, |
| | | Typography, |
| | | Divider, |
| | | Toolbar, |
| | | useTheme, |
| | | Autocomplete, |
| | | CircularProgress, |
| | | } from '@mui/material'; |
| | | import CheckOutlinedIcon from '@mui/icons-material/CheckOutlined'; |
| | | import RestartAltIcon from '@mui/icons-material/RestartAlt'; |
| | | import useCoolHook from './useCoolHook'; |
| | | |
| | | function AgvControl({ open, onClose }) { |
| | | const theme = useTheme(); |
| | | const translate = useTranslate(); |
| | | |
| | | const { control, handleSubmit, reset, watch } = useForm({ |
| | | defaultValues: { |
| | | taskMode: 'MOVE', |
| | | startCode: '', |
| | | endCode: '', |
| | | startLocNo: '', |
| | | endLocNo: '', |
| | | startStaNo: '', |
| | | endStaNo: '', |
| | | }, |
| | | }); |
| | | |
| | |
| | | } |
| | | }; |
| | | |
| | | const { |
| | | options: codeOptions, |
| | | setInputValue: setCodeInputValue, |
| | | } = useCoolHook('/code/page', 'data'); |
| | | |
| | | return ( |
| | | <Box display="flex" height="100%" p={2}> |
| | | <> |
| | | <form onSubmit={handleSubmit(onSubmit)}> |
| | | <Grid container spacing={2}> |
| | | <Box display="flex" flexDirection="row" height="100%" justifyContent="space-around" p={2}> |
| | | {/* left */} |
| | | <Grid item xs={4}> |
| | | <Box |
| | | position="relative" |
| | | width="35%" |
| | | height="100%" |
| | | > |
| | | <Controller |
| | | name="taskMode" |
| | | control={control} |
| | |
| | | </ToggleButtonGroup> |
| | | )} |
| | | /> |
| | | </Grid> |
| | | </Box> |
| | | |
| | | {/* right */} |
| | | <Grid item xs={8}> |
| | | <Box |
| | | position="relative" |
| | | width="55%" |
| | | height="100%" |
| | | > |
| | | <Grid container spacing={2}> |
| | | {showField('startCode') && ( |
| | | <Grid item xs={12}> |
| | |
| | | <Controller |
| | | name="endCode" |
| | | control={control} |
| | | rules={{ required: '目标地面码不能为空' }} |
| | | render={({ field, fieldState }) => ( |
| | | render={({ field, fieldState }) => { |
| | | return ( |
| | | <Autocomplete |
| | | options={codeOptions} |
| | | onInputChange={(event, value) => { |
| | | setCodeInputValue(value); |
| | | }} |
| | | onChange={(event, value) => { |
| | | field.onChange(value?.id); |
| | | }} |
| | | renderInput={(params) => ( |
| | | <TextField |
| | | {...field} |
| | | fullWidth |
| | | {...params} |
| | | label="目标地面码" |
| | | error={!!fieldState.error} |
| | | helperText={fieldState.error?.message} |
| | | /> |
| | | )} |
| | | /> |
| | | ); |
| | | }} |
| | | /> |
| | | </Grid> |
| | | )} |
| | |
| | | </Grid> |
| | | )} |
| | | |
| | | {/* button group */} |
| | | <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'flex-end', mt: 2 }}> |
| | | <Button variant="contained" color="primary" type="submit" sx={{ mr: 2 }}> |
| | | 确认 |
| | | </Button> |
| | | <Button variant="outlined" color="secondary" onClick={() => reset()}> |
| | | 重置 |
| | | </Button> |
| | | </Grid> |
| | | </Grid> |
| | | </Grid> |
| | | </Grid> |
| | | </form> |
| | | </Box> |
| | | </Box> |
| | | <Box pl={5} pr={5}> |
| | | <Divider sx={{ |
| | | marginBottom: '16px' |
| | | }} /> |
| | | <Toolbar sx={{ |
| | | display: 'flex', |
| | | justifyContent: 'space-between', |
| | | minHeight: { sm: 0 }, |
| | | }}> |
| | | <Button |
| | | variant="outlined" |
| | | color="primary" |
| | | type="submit" |
| | | onClick={() => { |
| | | |
| | | }} |
| | | sx={{ |
| | | borderColor: theme => theme.palette.primary.main, |
| | | color: theme => theme.palette.primary.main, |
| | | }} |
| | | startIcon={ |
| | | <CheckOutlinedIcon sx={{ color: theme => theme.palette.primary.main }} /> |
| | | } |
| | | > |
| | | {translate('ra.action.confirm')} |
| | | </Button> |
| | | |
| | | <Button |
| | | variant="outlined" |
| | | color="primary" |
| | | onClick={() => { |
| | | reset(); |
| | | }} |
| | | sx={{ |
| | | borderColor: theme => theme.palette.warning.main, |
| | | color: theme => theme.palette.warning.main, |
| | | }} |
| | | startIcon={ |
| | | <RestartAltIcon sx={{ color: theme => theme.palette.warning.main }} /> |
| | | } |
| | | > |
| | | {translate('common.action.reset')} |
| | | </Button> |
| | | </Toolbar> |
| | | </Box> |
| | | </form> |
| | | </> |
| | | ); |
| | | } |
| | | |
New file |
| | |
| | | import { useState, useEffect, useCallback } from 'react'; |
| | | import { debounce } from 'lodash'; |
| | | import request from '@/utils/request'; |
| | | |
| | | const useCoolHook = (url, label) => { |
| | | const [options, setOptions] = useState([]); |
| | | const [inputValue, setInputValue] = useState(''); |
| | | |
| | | const fetchData = async (condition) => { |
| | | try { |
| | | const res = await request.post(url, { |
| | | condition: condition, |
| | | pageSize: 20 |
| | | }).catch(error => { |
| | | console.error(error.message); |
| | | }); |
| | | const { code, msg, data: { records } } = res.data; |
| | | if (code === 200) { |
| | | setOptions(records.map(item => ({ |
| | | label: item[label], |
| | | id: item.id |
| | | }))) |
| | | } else { |
| | | console.error(msg); |
| | | } |
| | | } catch (error) { |
| | | console.error(error.message); |
| | | setOptions([]); |
| | | } |
| | | } |
| | | |
| | | const debouncedFetch = useCallback(debounce(fetchData, 300), [url]); |
| | | |
| | | useEffect(() => { |
| | | if (inputValue) { |
| | | debouncedFetch(inputValue); |
| | | } else { |
| | | setOptions([]); |
| | | } |
| | | }, [inputValue, debouncedFetch]); |
| | | |
| | | return { |
| | | options, |
| | | setInputValue, |
| | | }; |
| | | } |
| | | |
| | | export default useCoolHook; |