| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import React, { useState, useEffect } from "react"; |
| | | import { |
| | | CreateBase, |
| | | useTranslate, |
| | | TextInput, |
| | | NumberInput, |
| | | BooleanInput, |
| | | DateInput, |
| | | SaveButton, |
| | | SelectInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | Toolbar, |
| | | required, |
| | | useDataProvider, |
| | | useNotify, |
| | | Form, |
| | | useCreateController, |
| | | useListContext, |
| | | useNotify, |
| | | useRefresh, |
| | | SelectArrayInput |
| | | TextInput, |
| | | SelectInput, |
| | | } from 'react-admin'; |
| | | import { |
| | | Dialog, |
| | |
| | | DialogContent, |
| | | DialogTitle, |
| | | Grid, |
| | | TextField, |
| | | Box, |
| | | Button, |
| | | Paper, |
| | |
| | | TableBody, |
| | | TableRow, |
| | | TableCell, |
| | | Tooltip, |
| | | IconButton, |
| | | styled |
| | | |
| | | |
| | | MenuItem, |
| | | Select, |
| | | FormControl, |
| | | TextField, |
| | | } from '@mui/material'; |
| | | import DialogCloseButton from "../../components/DialogCloseButton"; |
| | | import DictionarySelect from "../../components/DictionarySelect"; |
| | | import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form"; |
| | | import SaveIcon from '@mui/icons-material/Save'; |
| | | import request from '@/utils/request'; |
| | | import { Add, Edit, Delete } from '@mui/icons-material'; |
| | | import _ from 'lodash'; |
| | | import { DataGrid } from '@mui/x-data-grid'; |
| | | import { Add, Delete } from '@mui/icons-material'; |
| | | import { ReferenceInput, AutocompleteInput } from 'react-admin'; |
| | | |
| | | const defaultRow = () => ({ deviceSite: '', site: '', target: '' }); |
| | | |
| | | |
| | | |
| | | const InitModal = ({ open, setOpen }) => { |
| | | const InitModal = ({ open, setOpen, initialData = null, onClose }) => { |
| | | const refresh = useRefresh(); |
| | | const translate = useTranslate(); |
| | | |
| | | |
| | | const notify = useNotify(); |
| | | const [disabled, setDisabled] = useState(false) |
| | | const [disabled, setDisabled] = useState(false); |
| | | const [rows, setRows] = useState([defaultRow()]); |
| | | const [stationOptions, setStationOptions] = useState([]); |
| | | |
| | | useEffect(() => { |
| | | if (!open) return; |
| | | request.post('/basStation/list', {}) |
| | | .then((res) => { |
| | | if (res?.data?.code === 200 && res?.data?.data) { |
| | | const list = Array.isArray(res.data.data) ? res.data.data : (res.data.data?.records || []); |
| | | const opts = list.map((item) => ({ id: item.id, stationName: item.stationName ?? item.name ?? item.id })); |
| | | setStationOptions(opts); |
| | | if (initialData?.rows?.length && opts.length) { |
| | | const resolved = initialData.rows.map((r) => { |
| | | const deviceSiteId = r.deviceSite || (r.deviceSiteName && opts.find((o) => o.stationName === r.deviceSiteName)?.id); |
| | | const siteId = r.site || (r.siteName && opts.find((o) => o.stationName === r.siteName)?.id); |
| | | return { |
| | | deviceSite: deviceSiteId != null ? String(deviceSiteId) : '', |
| | | site: siteId != null ? String(siteId) : '', |
| | | target: r.target ?? '', |
| | | }; |
| | | }); |
| | | setRows(resolved.length ? resolved : [defaultRow()]); |
| | | } |
| | | } |
| | | }) |
| | | .catch(() => {}); |
| | | }, [open, initialData]); |
| | | |
| | | useEffect(() => { |
| | | if (open && !initialData?.rows?.length) { |
| | | setRows([defaultRow()]); |
| | | } |
| | | }, [open, initialData]); |
| | | |
| | | const handleClose = (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | setOpen(false); |
| | | if (typeof onClose === 'function') onClose(); |
| | | } |
| | | }; |
| | | |
| | | const handleReset = (e) => { |
| | | e.preventDefault(); |
| | | const addRow = () => setRows((prev) => [...prev, defaultRow()]); |
| | | const removeRow = (index) => { |
| | | if (rows.length <= 1) return; |
| | | setRows((prev) => prev.filter((_, i) => i !== index)); |
| | | }; |
| | | |
| | | const handleChange = (value, name) => { |
| | | setFormData((prevData) => ({ |
| | | ...prevData, |
| | | [name]: value |
| | | })); |
| | | const changeRow = (index, field, value) => { |
| | | setRows((prev) => prev.map((r, i) => (i === index ? { ...r, [field]: value } : r))); |
| | | }; |
| | | |
| | | const handleSubmit = async (value) => { |
| | | setDisabled(true) |
| | | const res = await request.post(`/deviceSite/init`, value); |
| | | const validRows = rows.filter( |
| | | (r) => (r.deviceSite !== '' && r.deviceSite != null) && (r.site !== '' && r.site != null) && (r.target !== '' && (r.target || '').trim() !== '') |
| | | ); |
| | | if (validRows.length === 0) { |
| | | notify('请至少填写一行完整的设备站点、作业站点、目标站点', { type: 'error' }); |
| | | return; |
| | | } |
| | | if (!(value.channel != null && String(value.channel).trim() !== '')) { |
| | | notify('巷道不能为空,多个请用英文逗号分隔,如 1,2,3', { type: 'error' }); |
| | | return; |
| | | } |
| | | setDisabled(true); |
| | | const payload = { |
| | | ...value, |
| | | // 名称、wcs编号、站点标签 已从界面注释,不再提交 |
| | | name: null, |
| | | wcsCode: null, |
| | | label: null, |
| | | rows: validRows.map((r) => ({ |
| | | deviceSite: String(r.deviceSite), |
| | | site: String(r.site), |
| | | target: String(r.target || '').trim(), |
| | | })), |
| | | }; |
| | | const res = await request.post('/deviceSite/init', payload); |
| | | if (res?.data?.code === 200) { |
| | | setOpen(false); |
| | | refresh(); |
| | | } else { |
| | | notify(res.data.msg); |
| | | notify(res?.data?.msg || '初始化失败'); |
| | | } |
| | | setDisabled(false) |
| | | } |
| | | setDisabled(false); |
| | | }; |
| | | |
| | | const formDefaultValues = initialData ? { |
| | | channel: initialData.channel != null ? String(initialData.channel) : '', |
| | | deviceType: initialData.deviceType ?? '', |
| | | // deviceCode 接驳位已注释,不默认填入 |
| | | // deviceCode: initialData.deviceCode ?? '', |
| | | areaIdStart: initialData.areaIdStart ?? undefined, |
| | | areaIdEnd: initialData.areaIdEnd ?? undefined, |
| | | flagInit: 0, |
| | | // name、wcsCode、label 已注释,不默认填入 |
| | | // name: initialData.name ?? '', |
| | | // wcsCode: initialData.wcsCode ?? '', |
| | | // label: initialData.label ?? '', |
| | | typeIds: Array.isArray(initialData.typeIds) ? initialData.typeIds : (initialData.type != null ? [initialData.type] : undefined), |
| | | } : undefined; |
| | | |
| | | return ( |
| | | <Dialog open={open} maxWidth="lg" fullWidth> |
| | | <Form onSubmit={handleSubmit}> |
| | | <Dialog open={open} maxWidth="lg" fullWidth onClose={handleClose}> |
| | | <Form onSubmit={handleSubmit} defaultValues={formDefaultValues} key={open ? (initialData ? 'copy' : 'new') : 'closed'}> |
| | | <DialogCloseButton onClose={handleClose} /> |
| | | <DialogTitle>{translate('toolbar.siteInit')}</DialogTitle> |
| | | <DialogTitle>{translate('toolbar.pathInit')}</DialogTitle> |
| | | <DialogContent sx={{ mt: 2 }}> |
| | | <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={12}> |
| | | <TableContainer component={Paper} variant="outlined"> |
| | | <Table size="small"> |
| | | <TableHead> |
| | | <TableRow> |
| | | <TableCell>{translate('table.field.deviceSite.deviceSite')}</TableCell> |
| | | <TableCell>{translate('table.field.deviceSite.site')}</TableCell> |
| | | <TableCell>{translate('table.field.deviceSite.target')}</TableCell> |
| | | <TableCell width={80}>操作</TableCell> |
| | | </TableRow> |
| | | </TableHead> |
| | | <TableBody> |
| | | {rows.map((r, index) => ( |
| | | <TableRow key={index}> |
| | | <TableCell> |
| | | <FormControl fullWidth size="small"> |
| | | <Select |
| | | displayEmpty |
| | | value={r.deviceSite ?? ''} |
| | | onChange={(e) => changeRow(index, 'deviceSite', e.target.value)} |
| | | renderValue={(v) => { |
| | | const o = stationOptions.find((s) => String(s.id) === String(v)); |
| | | return o ? o.stationName : (v ? String(v) : ''); |
| | | }} |
| | | > |
| | | <MenuItem value="">请选择</MenuItem> |
| | | {stationOptions.map((opt) => ( |
| | | <MenuItem key={opt.id} value={opt.id}> |
| | | {opt.stationName} |
| | | </MenuItem> |
| | | ))} |
| | | </Select> |
| | | </FormControl> |
| | | </TableCell> |
| | | <TableCell> |
| | | <FormControl fullWidth size="small"> |
| | | <Select |
| | | displayEmpty |
| | | value={r.site ?? ''} |
| | | onChange={(e) => changeRow(index, 'site', e.target.value)} |
| | | renderValue={(v) => { |
| | | const o = stationOptions.find((s) => String(s.id) === String(v)); |
| | | return o ? o.stationName : (v ? String(v) : ''); |
| | | }} |
| | | > |
| | | <MenuItem value="">请选择</MenuItem> |
| | | {stationOptions.map((opt) => ( |
| | | <MenuItem key={opt.id} value={opt.id}> |
| | | {opt.stationName} |
| | | </MenuItem> |
| | | ))} |
| | | </Select> |
| | | </FormControl> |
| | | </TableCell> |
| | | <TableCell> |
| | | <TextField |
| | | size="small" |
| | | fullWidth |
| | | placeholder={translate('table.field.deviceSite.target')} |
| | | value={r.target ?? ''} |
| | | onChange={(e) => changeRow(index, 'target', e.target.value)} |
| | | /> |
| | | </TableCell> |
| | | <TableCell> |
| | | <IconButton |
| | | size="small" |
| | | onClick={() => removeRow(index)} |
| | | disabled={rows.length <= 1} |
| | | > |
| | | <Delete fontSize="small" /> |
| | | </IconButton> |
| | | </TableCell> |
| | | </TableRow> |
| | | ))} |
| | | </TableBody> |
| | | </Table> |
| | | </TableContainer> |
| | | <Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 1 }}> |
| | | <Button size="small" startIcon={<Add />} onClick={addRow}> |
| | | 新增一行 |
| | | </Button> |
| | | </Box> |
| | | </Grid> |
| | | |
| | | {/* 名称、wcs编号、站点标签 已注释,不显示也不默认填入 */} |
| | | {/* <Grid item xs={4}> |
| | | <TextInput |
| | | source="name" |
| | | label="table.field.deviceSite.name" |
| | | size="small" |
| | | fullWidth |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={4}> |
| | | <TextInput |
| | | source="wcsCode" |
| | | label="table.field.deviceSite.wcsCode" |
| | | size="small" |
| | | fullWidth |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={4}> |
| | | <TextInput |
| | | source="label" |
| | | label="table.field.deviceSite.label" |
| | | size="small" |
| | | fullWidth |
| | | /> |
| | | </Grid> */} |
| | | |
| | | <Grid item xs={4}> |
| | | <DictionarySelect |
| | | label={translate("table.field.deviceSite.type")} |
| | |
| | | dictTypeCode="sys_task_type" |
| | | multiple |
| | | /> |
| | | |
| | | </Grid> |
| | | |
| | | <Grid item xs={4}> |
| | | <DictionarySelect |
| | | label={translate("table.field.deviceSite.device")} |
| | |
| | | dictTypeCode="sys_device_type" |
| | | /> |
| | | </Grid> |
| | | {/* 接驳位 deviceCode 已注释 */} |
| | | {/* <Grid item xs={4}> |
| | | <TextInput |
| | | source="deviceCode" |
| | | label="table.field.deviceSite.deviceCode" |
| | | size="small" |
| | | fullWidth |
| | | /> |
| | | </Grid> */} |
| | | <Grid item xs={4}> |
| | | <TextInput |
| | | label={translate("table.field.deviceSite.channel")} |
| | | name="channel" |
| | | source="channel" |
| | | label="table.field.deviceSite.channel" |
| | | size="small" |
| | | type="number" |
| | | fullWidth |
| | | placeholder="英文逗号分隔多个,如 1,2,3" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={4}> |
| | | <ReferenceInput |
| | | source="deviceSites" |
| | | reference="basStation" |
| | | > |
| | | <SelectInput |
| | | label="table.field.deviceSite.deviceSite" |
| | | optionText="stationName" |
| | | /> |
| | | </ReferenceInput> |
| | | </Grid> |
| | | <Grid item xs={4}> |
| | | <ReferenceInput |
| | | source="site" |
| | | reference="basStation" |
| | | > |
| | | <SelectInput |
| | | label="table.field.deviceSite.site" |
| | | optionText="stationName" |
| | | /> |
| | | </ReferenceInput> |
| | | |
| | | </Grid> |
| | | <Grid item xs={4}> |
| | | <TextInput |
| | | label={translate("table.field.deviceSite.target")} |
| | | name="target" |
| | | placeholder={translate('common.action.inputPlaceholder')} |
| | | size="small" |
| | | // type="number" |
| | | source="flagInit" |
| | | label="table.field.deviceSite.flagInit" |
| | | choices={[ |
| | | { id: 0, name: '否' }, |
| | | { id: 1, name: '是' }, |
| | | ]} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | |
| | | <AutocompleteInput optionValue="id" optionText="name" label={translate('table.field.deviceSite.areaIdEnd')} /> |
| | | </ReferenceInput> |
| | | </Grid> |
| | | <Grid item xs={4}> |
| | | <SelectInput |
| | | label="table.field.deviceSite.flagInit" |
| | | source="flagInit" |
| | | choices={[ |
| | | { id: 0, name: '否' }, |
| | | { id: 1, name: '是' }, |
| | | ]} |
| | | /> |
| | | </Grid> |
| | | |
| | | |
| | | </Grid> |
| | | |
| | | </Box> |
| | | </DialogContent> |
| | | <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> |
| | |
| | | {translate('toolbar.confirm')} |
| | | </Button> |
| | | </Box> |
| | | |
| | | </DialogActions> |
| | | </Form> |
| | | </Dialog> |
| | | ); |
| | | } |
| | | }; |
| | | |
| | | export default InitModal; |