skyouc
8 天以前 f2b48ce0cfdf9b68ecc7c9d84937d69500590f81
Merge branch 'devlop' of http://47.97.1.152:5880/r/wms-master into devlop
1个文件已添加
9个文件已修改
286 ■■■■ 已修改文件
rsf-admin/src/config/setting.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/basStation/BasStationList.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/basStation/CrossZoneAreaField.jsx 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/warehouseAreasItem/WarehouseAreasItemList.jsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/controller/pda/AgvController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/AgvService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/AgvServiceImpl.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WarehouseAreasItemController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/config/setting.js
@@ -25,7 +25,7 @@
export const ABORT_SIGNAL = false;
export const DEFAULT_PAGE_SIZE = 20;
export const DEFAULT_PAGE_SIZE = 10;
export const DEFAULT_ITEM_PAGE_SIZE = 10;
rsf-admin/src/i18n/zh.js
@@ -206,9 +206,9 @@
                outAble: '能出',
                useStatus: '状态',
                status: '状态',
                area: '所属库区类型',
                area: '所属库区',
                isCrossZone: '是否跨区',
                crossZoneArea: '可跨区类型',
                crossZoneArea: '可跨库区',
                isWcs: '是否WCS站站点',
                wcsData: 'wcs数据',
                containerType: '容器类型',
rsf-admin/src/page/basicInfo/basStation/BasStationList.jsx
@@ -45,6 +45,7 @@
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
import WarehouseAreaField from "./WarehouseAreaField";
import CrossZoneAreaField from "./CrossZoneAreaField";
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
@@ -95,7 +96,7 @@
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    const [areaFieldDialog, setAreaFieldDialog] = useState(false);
    return (
        <Box display="flex">
            <List
@@ -147,8 +148,12 @@
                        label="table.field.basStation.isCrossZone"
                        render={record => record.inAble === 1 ? '是' : '否'}
                    />
                    <TextField source="crossZoneArea" label="table.field.basStation.crossZoneArea" />
                    <WrapperField cellClassName="crossZoneArea" label="table.field.basStation.crossZoneArea">
                        <CrossZoneAreaField
                            open={areaFieldDialog}
                            setOpen={setAreaFieldDialog}
                        />
                    </WrapperField>
                    <FunctionField
                        source="isWcs"
                        label="table.field.basStation.isWcs"
@@ -170,16 +175,18 @@
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />                    
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <BasStationCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='BasStation Detail'
                drawerVal={drawerVal}
rsf-admin/src/page/basicInfo/basStation/CrossZoneAreaField.jsx
New file
@@ -0,0 +1,118 @@
import * as React from 'react';
import { Stack, Chip, Dialog, DialogTitle, DialogContent, IconButton, CircularProgress } from '@mui/material';
import { useTranslate, useRecordContext } from 'react-admin';
import CloseIcon from '@mui/icons-material/Close';
import request from '@/utils/request';
const CrossZoneAreaField = () => {
    const translate = useTranslate();
    const record = useRecordContext();
    const [open, setOpen] = React.useState(false);
    const [areaNames, setAreaNames] = React.useState([]);
    const [loading, setLoading] = React.useState(false);
    const handleOpen = () => {
        setOpen(true);
    };
    const handleClose = () => {
        setOpen(false);
    };
    const fetchAreaNames = async () => {
        if (!record?.areaIds || record.areaIds.length === 0) return;
        setLoading(true);
        try {
            const res = await request.post(`/warehouseAreas/many/${record.areaIds.join(',')}`);
            if (res?.data?.code === 200) {
                setAreaNames(res.data.data || []);
            }
        } catch (error) {
            console.error('获取区域名称失败:', error);
        } finally {
            setLoading(false);
        }
    };
    React.useEffect(() => {
        if (record?.areaIds && record.areaIds.length > 0) {
            fetchAreaNames();
        }
    }, [record]);
    if (loading) {
        return <CircularProgress size={20} />;
    }
    return (
        <>
            <Stack
                direction="row"
                gap={1}
                flexWrap="wrap"
                onClick={handleOpen}
                sx={{ cursor: 'pointer' }}
            >
                {areaNames.slice(0, 1).map((item, idx) => (
                    <Chip
                        size="small"
                        key={item.id}
                        label={item.name || item.id}
                    />
                ))}
                {areaNames.length > 1 && (
                    <Chip
                        size="small"
                        label={`+${areaNames.length - 1}`}
                    />
                )}
                {areaNames.length === 0 && record.areaIds && record.areaIds.length > 0 && (
                    <Chip
                        size="small"
                        label={`${record.areaIds.length} 个区域`}
                    />
                )}
            </Stack>
            <Dialog
                open={open}
                onClose={handleClose}
                maxWidth="md"
                fullWidth
            >
                <DialogTitle>
                    {translate('table.field.basStation.crossZoneArea')}
                    <IconButton
                        aria-label="close"
                        onClick={handleClose}
                        sx={{
                            position: 'absolute',
                            right: 8,
                            top: 8,
                        }}
                    >
                        <CloseIcon />
                    </IconButton>
                </DialogTitle>
                <DialogContent>
                    {loading ? (
                        <CircularProgress />
                    ) : (
                        <Stack direction="row" gap={1} flexWrap="wrap" sx={{ mt: 1 }}>
                            {areaNames.map((item) => (
                                <Chip
                                    size="small"
                                    key={item.id}
                                    label={item.name || item.id}
                                />
                            ))}
                        </Stack>
                    )}
                </DialogContent>
            </Dialog>
        </>
    );
};
export default CrossZoneAreaField;
rsf-admin/src/page/warehouseAreasItem/WarehouseAreasItemList.jsx
@@ -170,17 +170,17 @@
        const { data: { code, data, msg }, } = await request.get("/fields/enable/list");
        if (code == 200) {
            const arr = [
                <NumberField source="id" />,
                <TextField source="asnCode" label="table.field.warehouseAreasItem.asnCode" />,
                <NumberField source="areaId" label="table.field.warehouseAreasItem.areaId" />,
                <TextField source="areaName" label="table.field.warehouseAreasItem.areaName" />,
                <NumberField source="matnrId" label="table.field.warehouseAreasItem.matnrId" />,
                <TextField source="maktx" label="table.field.warehouseAreasItem.matnrName" />,
                <TextField source="matnrCode" label="table.field.warehouseAreasItem.matnrCode" />,
                <TextField source="trackCode" label="table.field.warehouseAreasItem.barcode" />,
                <NumberField source="anfme" label="table.field.warehouseAreasItem.anfme" />,
                <NumberField source="workQty" label="table.field.warehouseAreasItem.workQty" />,
                <NumberField source="qty" label="table.field.warehouseAreasItem.qty" />,
                <NumberField key="id" source="id" />,
                <TextField key="asnCode" source="asnCode" label="table.field.warehouseAreasItem.asnCode" />,
                <NumberField key="areaId" source="areaId" label="table.field.warehouseAreasItem.areaId" />,
                <TextField key="areaName" source="areaName" label="table.field.warehouseAreasItem.areaName" />,
                <NumberField key="matnrId" source="matnrId" label="table.field.warehouseAreasItem.matnrId" />,
                <TextField key="maktx" source="maktx" label="table.field.warehouseAreasItem.matnrName" />,
                <TextField key="matnrCode" source="matnrCode" label="table.field.warehouseAreasItem.matnrCode" />,
                <TextField key="trackCode" source="trackCode" label="table.field.warehouseAreasItem.barcode" />,
                <NumberField key="anfme" source="anfme" label="table.field.warehouseAreasItem.anfme" />,
                <NumberField key="workQty" source="workQty" label="table.field.warehouseAreasItem.workQty" />,
                <NumberField key="qty" source="qty" label="table.field.warehouseAreasItem.qty" />,
                // <MyField source="isptQty" label="table.field.qlyIsptItem.anfme"
                //     onClick={(event, record, val) => {
                //         event.stopPropagation();
@@ -188,27 +188,37 @@
                //         setDrawerVal(!!drawerVal && drawerVal === val ? null : val);
                //     }}
                // />,
                <TextField source="splrBatch" label="table.field.warehouseAreasItem.splrBtch" />,
                <TextField source="batch" label="table.field.warehouseAreasItem.batch" />,
                <TextField source="unit" label="table.field.warehouseAreasItem.unit" />,
                <TextField source="stockUnit" label="table.field.warehouseAreasItem.stockUnit" />,
                <TextField source="brand" label="table.field.warehouseAreasItem.brand" />,
                <TextField source="shipperId" label="table.field.warehouseAreasItem.shipperId" />,
                <TextField source="splrId" label="table.field.warehouseAreasItem.splrId" />,
                <TextField source="isptResult$" label="table.field.warehouseAreasItem.isptResult" sortable={false} />,
                <NumberField source="weight" label="table.field.warehouseAreasItem.weight" />,
                <TextField source="prodTime" label="table.field.warehouseAreasItem.prodTime" />,
                <TextField key="splrBatch" source="splrBatch" label="table.field.warehouseAreasItem.splrBtch" />,
                <TextField key="batch" source="batch" label="table.field.warehouseAreasItem.batch" />,
                <TextField key="unit" source="unit" label="table.field.warehouseAreasItem.unit" />,
                <TextField key="stockUnit" source="stockUnit" label="table.field.warehouseAreasItem.stockUnit" />,
                <TextField key="brand" source="brand" label="table.field.warehouseAreasItem.brand" />,
                <TextField key="shipperId" source="shipperId" label="table.field.warehouseAreasItem.shipperId" />,
                <TextField key="splrId" source="splrId" label="table.field.warehouseAreasItem.splrId" />,
                <TextField key="isptResult" source="isptResult$" label="table.field.warehouseAreasItem.isptResult" sortable={false} />,
                <NumberField key="weight" source="weight" label="table.field.warehouseAreasItem.weight" />,
                <TextField key="prodTime" source="prodTime" label="table.field.warehouseAreasItem.prodTime" />,
            ]
            const fields = data.map(el => <TextField key={el.fields} source={`extendFields.[${el.fields}]`} label={el.fieldsAlise} />)
            const lastArr = [
                <TextField source="updateBy$" label="common.field.updateBy" />,
                <DateField source="updateTime" label="common.field.updateTime" showTime />,
                <TextField source="createBy$" label="common.field.createBy" />,
                <DateField source="createTime" label="common.field.createTime" showTime />,
                <BooleanField source="statusBool" label="common.field.status" sortable={false} />,
                <TextField source="memo" label="common.field.memo" sortable={false} />,
                <TextField key="updateBy" source="updateBy$" label="common.field.updateBy" />,
                <DateField key="updateTime" source="updateTime" label="common.field.updateTime" showTime />,
                <TextField key="createBy" source="createBy$" label="common.field.createBy" />,
                <DateField key="createTime" source="createTime" label="common.field.createTime" showTime />,
                <BooleanField key="statusBool" source="statusBool" label="common.field.status" sortable={false} />,
                <TextField key="memo" source="memo" label="common.field.memo" sortable={false} />,
            ]
            setColumns([...arr, ...fields, ...lastArr]);
            //filters添加过滤字段
            data.map(el => {
                var i =0;
                filters.map((item) =>{
                    if(item.key === el.fields){
                      i = 1;
                    }
                })
                i===0 && filters.push(<TextInput key={el.fields} source={el.fields} label={el.fieldsAlise} />)
            })
        } else {
            notify(msg);
        }
rsf-server/src/main/java/com/vincent/rsf/server/api/controller/pda/AgvController.java
@@ -34,6 +34,16 @@
        return agvService.getStaBindList(params);
    }
    @ApiOperation("站点查询")
    @PreAuthorize("hasAuthority('manager:basStation:list')")
    @PostMapping("/staMsg/select")
    public R getStaMsgSelect(@RequestBody Map<String, Object> params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        return agvService.getStaMsgSelect(params);
    }
    @PreAuthorize("hasAuthority('manager:basStation:list')")
    @ApiOperation("站点绑定")
    @PostMapping("/AGV/staBind")
@@ -63,4 +73,14 @@
        }
        return agvService.AGVInTaskStart(params, getLoginUserId());
    }
    @PreAuthorize("hasAuthority('manager:basStation:list')")
    @ApiOperation("AGV绑定&入库")
    @PostMapping("/AGV/bindAndIn/start")
    public R AGVBindAndInTaskStart(@RequestBody Map<String, Object> params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        return agvService.AGVBindAndInTaskStart(params, getLoginUserId());
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/api/service/AgvService.java
@@ -12,4 +12,8 @@
    R AGVStaUnBind(Map<String, Object> params);
    R AGVInTaskStart(Map<String, Object> params ,Long loginUserId);
    R getStaMsgSelect(Map<String, Object> params);
    R AGVBindAndInTaskStart(Map<String, Object> params, Long loginUserId);
}
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/AgvServiceImpl.java
@@ -35,6 +35,51 @@
    @Autowired
    private TaskService taskService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R AGVBindAndInTaskStart(Map<String, Object> params, Long loginUserId) {
        //先绑定
        getAGVStaBind(params);
        //生成任务
        AGVInTaskStart(params, loginUserId);
        return R.ok();
    }
    @Override
    public R getStaMsgSelect(Map<String, Object> params) {
        String sta = params.get("sta").toString();
        if (Cools.isEmpty(sta)){
            throw new CoolException("接驳位条码不能为空");
        }
        BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>()
                .eq(BasStation::getStationName, sta)
                .eq(BasStation::getUseStatus,StaUseStatusType.TYPE_O.type)
        );
        if (Cools.isEmpty(basStation)){
            throw new CoolException("未找到接驳站点信息,请检查站点状态");
        }
        List<Long> ids =  new ArrayList<>();
        ids.add(basStation.getArea());
        if (basStation.getIsCrossZone() == 1){
            String content = basStation.getCrossZoneArea().substring(1, basStation.getCrossZoneArea().length() - 1);
            String[] parts = content.split(",");
            for (int i = 0; i < parts.length; i++) {
                ids.add(Long.parseLong(parts[i].trim()));
            }
        }
        List<WarehouseAreas> warehouseAreasList = warehouseAreasService.list(new LambdaQueryWrapper<WarehouseAreas>()
                .in(WarehouseAreas::getId, ids)
        );
        return R.ok(Cools
                .add("barcode", basStation.getBarcode())
                .add("warehouseAreasList", warehouseAreasList)
                .add("area", basStation.getArea())
        );
    }
    @Override
    public R AGVInTaskStart(Map<String, Object> params,Long loginUserId ) {
@@ -70,6 +115,8 @@
        return R.ok();
    }
    @Override
    public R AGVStaUnBind(Map<String, Object> params) {
        String sta = params.get("sta").toString();
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java
@@ -924,14 +924,15 @@
     */
    @Override
    public R getUnItemByContainer(Map<String, Object> params) {
        if (Objects.isNull(params.get("barcode"))) {
            throw new CoolException("参数不能为空!!");
        if (Cools.isEmpty(params.get("barcode")) && Cools.isEmpty(params.get("code"))){
            throw new CoolException("容器号与组托档编码不能全为空");
        }
        //获取组拖未生成任务的组拖档
//        List<Short> asList = Arrays.asList(Short.valueOf(PakinIOStatus.PAKIN_IO_STATUS_DONE.val), Short.valueOf(PakinIOStatus.PAKIN_IO_STATUS_DONE.val));
        WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>()
                .eq(WaitPakin::getBarcode, params.get("barcode").toString())
                .eq(!Cools.isEmpty(params.get("barcode")),WaitPakin::getBarcode, params.get("barcode").toString())
                .eq(!Cools.isEmpty(params.get("code")),WaitPakin::getCode, params.get("code").toString())
                .eq(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_DONE.val));
        if (Objects.isNull(waitPakin)) {
            return R.error("未找到该容器码的组托明细,请检查组托状态");
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WarehouseAreasItemController.java
@@ -13,6 +13,7 @@
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.common.utils.FieldsUtils;
import com.vincent.rsf.server.manager.entity.AsnOrderItem;
import com.vincent.rsf.server.manager.entity.Matnr;
import com.vincent.rsf.server.manager.entity.WarehouseAreasItem;
import com.vincent.rsf.server.manager.service.WarehouseAreasItemService;
import com.vincent.rsf.server.system.controller.BaseController;
@@ -37,6 +38,8 @@
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<WarehouseAreasItem, BaseParam> pageParam = new PageParam<>(baseParam, WarehouseAreasItem.class);
        QueryWrapper<WarehouseAreasItem> queryWrapper = pageParam.buildWrapper(true);
        /**拼接扩展字段过滤*/
        FieldsUtils.setFieldsFilters(queryWrapper,pageParam, WarehouseAreasItem.class);
        /**拼接扩展字段*/
        PageParam<WarehouseAreasItem, BaseParam> page = warehouseAreasItemService.page(pageParam, queryWrapper);
        List<WarehouseAreasItem> records = page.getRecords();