From 99f5c058c42521640d815f3d52dc722a5d5ad4c4 Mon Sep 17 00:00:00 2001 From: skyouc Date: 星期五, 23 五月 2025 18:59:43 +0800 Subject: [PATCH] Merge branch 'devlop' of http://47.97.1.152:5880/r/wms-master into devlop --- rsf-admin/src/page/work/stockTransfer/index.jsx | 18 ++ rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java | 11 + rsf-admin/src/page/work/stockTransfer/stockTransferList.jsx | 379 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java | 9 + rsf-admin/src/page/ResourceContent.js | 3 5 files changed, 419 insertions(+), 1 deletions(-) diff --git a/rsf-admin/src/page/ResourceContent.js b/rsf-admin/src/page/ResourceContent.js index 64483a6..416d4cc 100644 --- a/rsf-admin/src/page/ResourceContent.js +++ b/rsf-admin/src/page/ResourceContent.js @@ -51,6 +51,7 @@ import basContainer from './basicInfo/basContainer'; import outBound from "./work/outBound"; import checkOutBound from "./work/checkOutBound"; +import stockTransfer from "./work/stockTransfer"; const ResourceContent = (node) => { switch (node.component) { @@ -148,6 +149,8 @@ return outBound; case 'checkOutBound': return checkOutBound; + case 'stockTransfer': + return stockTransfer; default: return { list: ListGuesser, diff --git a/rsf-admin/src/page/work/stockTransfer/index.jsx b/rsf-admin/src/page/work/stockTransfer/index.jsx new file mode 100644 index 0000000..caa0bd1 --- /dev/null +++ b/rsf-admin/src/page/work/stockTransfer/index.jsx @@ -0,0 +1,18 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { + ListGuesser, + EditGuesser, + ShowGuesser, +} from "react-admin"; + + +import StockTransferList from "./stockTransferList"; + +export default { + list: StockTransferList, + edit: EditGuesser, + show: ShowGuesser, + recordRepresentation: (record) => { + return `${record.id}` + } +}; diff --git a/rsf-admin/src/page/work/stockTransfer/stockTransferList.jsx b/rsf-admin/src/page/work/stockTransfer/stockTransferList.jsx new file mode 100644 index 0000000..a0355b8 --- /dev/null +++ b/rsf-admin/src/page/work/stockTransfer/stockTransferList.jsx @@ -0,0 +1,379 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { useWatch, useFormContext } from "react-hook-form"; +import { + CreateBase, + useTranslate, + TextInput, + NumberInput, + BooleanInput, + DateInput, + SaveButton, + SelectInput, + ReferenceInput, + ReferenceArrayInput, + AutocompleteInput, + Toolbar, + required, + useDataProvider, + useNotify, + Form, + useCreateController, + useListContext, + useRefresh, + Edit, + useRedirect, +} from 'react-admin'; +import { + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Stack, + Grid, + TextField, + Box, + Button, + Paper, + TableContainer, + Table, + TableHead, + TableBody, + TableRow, + TableCell, + Tooltip, + IconButton, + styled, + Select, + MenuItem, + Typography, + Card, + Autocomplete, +} from '@mui/material'; +import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting'; +import ConfirmButton from "../../components/ConfirmButton"; +import TreeSelectInput from "@/page/components/TreeSelectInput"; +import { DataGrid, useGridApiRef } from '@mui/x-data-grid'; +import DictSelect from "../../components/DictSelect"; +import AddIcon from '@mui/icons-material/Add'; +import DeleteIcon from '@mui/icons-material/Delete'; +import request from '@/utils/request'; +import LocItemInfoModal from "../components/locItemInfoModal"; +import { Delete } from '@mui/icons-material'; +import _, { set } from 'lodash'; +import StaSelect from "../components/StaSelect"; +import { redirect } from "react-router"; +import { number } from "prop-types"; + +const StockTransferList = () => { + + const [createDialog, setCreateDialog] = useState(false); + const [tabelData, setTableData] = useState([]); + const [selectedRows, setSelectedRows] = useState([]); + const [sta, setSta] = useState(""); + const notify = useNotify(); + const tableRef = useRef(); + tableRef.current = useGridApiRef(); + const translate = useTranslate(); + + const [orgLoc, setOrgLoc] = useState([]); + const [tarLoc, setTarLoc] = useState([]); + const [tarLocList, setTarLocList] = useState([]); + + useEffect(() => { + selectAreaNoUse(); + },[orgLoc]) + + const selectAreaNoUse = async() =>{ + const { + data: { code, data, msg }, + } = await request.post("/loc/areaNoUse/list",{ + + }); + if (code === 200) { + const newData = data.map((item) => { + return { + label: item, + id: item + } + + }) + console.log(newData); + setTarLocList(newData); + } + + } + + + const handleDeleteItem = () => { + const newTableData = _.filter(tabelData, (item) => !selectedRows.includes(item.matnrId)); + setTableData(newTableData); + } + + // 娣诲姞涓�涓鐞嗘柊鏁版嵁鐨勫嚱鏁帮紝璁剧疆outQty榛樿鍊� + const handleSetData = (newData) => { + // 涓烘柊娣诲姞鐨勬暟鎹缃畂utQty榛樿鍊间负anfme鐨勫�� + const dataWithDefaultQty = newData.map(item => ({ + ...item, + outQty: item.outQty || item.anfme // 濡傛灉outQty宸插瓨鍦ㄥ垯淇濈暀锛屽惁鍒欎娇鐢╝nfme鐨勫�� + })); + setTableData([...tabelData, ...dataWithDefaultQty]); + }; + + + + return ( + <> + <Card sx={{ p: 2, mb: 2, mt: 2 }}> + <Form> + <Grid container spacing={2}> + <Grid item xs={12}> + <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: 1 }}> + <Typography variant="h6" > + {translate('table.field.stockTransfer.inputLoc')} + </Typography> + <Box sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 1 }}> + <Stack direction='row' spacing={2} minWidth={200}> + <TextField + label={translate("table.field.stockTransfer.orgLoc")} + onChange={(event) => setOrgLoc(event.target.value)} + /> + </Stack> + <>{"鈥斺��"}</> + <Stack direction='row' spacing={2} minWidth={200}> + <Autocomplete + disablePortal + options={tarLocList} + renderInput={(params) => ( + <TextField {...params} label={translate("table.field.stockTransfer.tarLoc")} /> + )} + onChange={(event, value) => setTarLoc(value)} + /> + </Stack> + </Box> + + <Stack direction='row' spacing={2} minWidth={200}> + <SubmitButton + orgLoc={orgLoc} + tarLoc={tarLoc} + /> + </Stack> + </Box> + </Grid> + </Grid> + </Form> + </Card> + <Card sx={{ mb: 2 }}> + <Box sx={{}}> + <ModalTable tabelData={tabelData} setTableData={setTableData} selectedRows={selectedRows} setSelectedRows={setSelectedRows} tableRef={tableRef}></ModalTable> + </Box> + </Card> + <LocItemInfoModal + open={createDialog} + setOpen={setCreateDialog} + data={tabelData} + setData={handleSetData} + /> + + </> + ) +} + +export default StockTransferList; + +const SubmitButton = (props) => { + const translate = useTranslate(); + const notify = useNotify(); + const redirect = useRedirect(); + const refresh = useRefresh(); + const { orgLoc, tarLoc } = props; + const check = () => { + console.log(orgLoc, tarLoc); + if (orgLoc === "" || orgLoc === undefined || orgLoc === null) { + notify("璇烽�夋嫨绔欑偣"); + return; + } + if (tarLoc === "" || tarLoc === undefined || tarLoc === null) { + notify("璇烽�夋嫨绔欑偣"); + return; + } + + } + const http = async (sta, items) => { + console.log(items); + + const filter = items.filter(item => (item.outQty + item.workQty) > item.anfme); + if (filter.length > 0) { + notify(translate('toolbar.request.error.out_stock_qty')) + return + } + const { data: { code, data, msg } } = await request.post(`/locItem/generate/task`, { siteNo: sta, items: items }); + if (code === 200) { + notify(msg); + refresh() + setTableData([]) + redirect("/task") + } else { + notify(msg); + } + } + return ( + <ConfirmButton + variant="contained" + color="primary" + onConfirm={check} + label={"table.field.outBound.createTask"} + > + </ConfirmButton> + ) + +} + +const ModalTable = ({ tabelData, setTableData, selectedRows, setSelectedRows, tableRef }) => { + const translate = useTranslate(); + const notify = useNotify(); + + const [columns, setColumns] = useState([ + { + field: 'locCode', + headerName: translate('table.field.locItem.locCode'), + width: 100, + editable: false, + }, + { + field: 'anfme', + headerName: translate('table.field.locItem.anfme'), + type: 'number', + width: 100, + editable: false, + }, + { + field: 'workQty', + headerName: translate('table.field.locItem.workQty'), + width: 100, + type: 'number', + editable: false, + }, + { + field: 'locCode', + headerName: translate('table.field.locItem.locCode'), + width: 100, + editable: false, + }, + { + field: 'matnrCode', + headerName: translate('table.field.locItem.matnrCode'), + width: 130, + editable: false, + }, + { + field: 'maktx', + headerName: translate('table.field.locItem.maktx'), + width: 250, + editable: false, + }, + { + field: 'batch', + headerName: translate('table.field.locItem.batch'), + width: 250, + editable: false, + }, + ]) + + const action = { + field: 'action', + headerName: '鎿嶄綔', + width: 70, + lockPosition: 'left', + renderCell: (params) => ( + <Tooltip title="Delete"> + <IconButton onClick={() => handleDelete(params.row)}> + <Delete /> + </IconButton> + </Tooltip> + ), + + } + + let cdata = useRef([]); + + useEffect(() => { + getDynamicFields(); + }, []); + + useEffect(() => { + cdata.current = tabelData + }, [tabelData]); + + const getDynamicFields = async () => { + const { + data: { code, data, msg }, + } = await request.get("/fields/enable/list"); + if (code === 200) { + const cols = data.map(el => ({ + field: el.fields, + headerName: el.fieldsAlise, + minWidth: 100, + flex: 1, + editable: false + })) + setColumns([...columns, ...cols, action]) + } else { + notify(msg); + } + } + + + const handleDelete = (row) => { + const newData = _.filter(cdata.current, (item) => item.id !== row.id); + setTableData(newData); + }; + + + const processRowUpdate = (newRow, oldRow) => { + const rows = tabelData.map((r) => + r.id === newRow.id ? { ...newRow } : r + ) + setTableData(rows) + return newRow; + }; + + const handleSelectionChange = (ids) => { + setSelectedRows(ids) + }; + + tableRef.current = useGridApiRef(); + + return ( + <div style={{ height: 500, width: '100%' }}> + <DataGrid + apiRef={tableRef} + rows={tabelData} + columns={columns} + disableRowSelectionOnClick + getRowId={(row) => row.matnrId ? row.matnrId : row.id} + disableColumnFilter + disableColumnSelector + disableColumnSorting + disableMultipleColumnsSorting + processRowUpdate={processRowUpdate} + initialState={{ + pagination: { + paginationModel: { + pageSize: 25, + }, + }, + }} + pageSizeOptions={[10, 25, 50, 100]} + editMode="row" + checkboxSelection + onRowSelectionModelChange={handleSelectionChange} + selectionModel={selectedRows} + sx={{ + '& .MuiDataGrid-cell input': { + border: '1px solid #ccc' + }, + }} + /> + </div> + ); +}; diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java index d5022a8..7b981c9 100644 --- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java @@ -30,6 +30,7 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; import java.util.*; +import java.util.stream.Collectors; @Api(tags = "搴撲綅淇℃伅") @@ -58,6 +59,14 @@ } @PreAuthorize("hasAuthority('manager:loc:list')") + @PostMapping("/loc/areaNoUse/list") + public R areaNoUselist(@RequestBody Map<String, Object> map) { + List<Loc> list = locService.list(); + List<String> list1 = list.stream().map(obj -> obj.getCode()).collect(Collectors.toList()); + return R.ok(list1); + } + + @PreAuthorize("hasAuthority('manager:loc:list')") @PostMapping({"/loc/many/{ids}", "/locs/many/{ids}"}) public R many(@PathVariable Long[] ids) { return R.ok().add(locService.listByIds(Arrays.asList(ids))); diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java index 259612b..c2fdab5 100644 --- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java @@ -93,12 +93,21 @@ } String join = StringUtils.join(param.getTypeIds(), ","); + String[] split = warehouseAreas.getCode().split("\\."); + if (split.length == 0){ + throw new CoolException("搴撳尯缂栫爜閿欒锛侊紒"); + } + StringBuilder locStar = new StringBuilder(); + for (int i = 0; i < split.length; i++) { + locStar.append(split[i]).append("-"); + } + List<Loc> list = new ArrayList<>(); for (int r = param.getStartRow(); r <= param.getEndRow(); r++) { for (int b = param.getStartBay(); b <= param.getEndBay(); b++) { for (int l = param.getStartLev(); l <= param.getEndLev(); l++) { // 鑾峰彇搴撲綅鍙� - String locNo = String.format("%02d", r) + String.format("%03d", b) + String.format("%02d", l); + String locNo = locStar + String.format("%d", r) + String.format("-%d", b) + String.format("-%d", l); Loc loc = new Loc(); loc.setCode(locNo) .setUseStatus("O") -- Gitblit v1.9.1