skyouc
2 天以前 7737c1a11778a236592ff3677d54a44776fd440f
容器管理初始化功能
10个文件已修改
4个文件已添加
665 ■■■■■ 已修改文件
rsf-admin/src/i18n/en.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/basContainer/BasContainerInit.jsx 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/basContainer/BasContainerList.jsx 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/basContainer/PrintModal.jsx 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/container/ContainerList.jsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/BasContainerController.java 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/InitContainerParams.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/BasContainer.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/QRCodeType.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/BasContainerService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/BasContainerServiceImpl.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/application-dev.yml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js
@@ -126,6 +126,7 @@
    },
    create: {
        title: 'Create',
        init: 'Init',
        empty: {
            title: 'Data Empty',
            desc: 'Please Create Data First',
@@ -227,6 +228,9 @@
            basContainer: {
                containerType: 'containerType',
                codeType: 'codeType',
                startNo: 'Start No',
                code: 'Barcode',
                endNo: 'End No',
                areas: 'areas',
            },
            basStation: {
@@ -1310,6 +1314,7 @@
        detail: "Detail",
        unenable: 'unenable',
        locInit: 'loc init',
        init: "Init",
        siteInit: 'site init',
        batch: 'batch',
        pick: 'Pick',
rsf-admin/src/i18n/zh.js
@@ -127,6 +127,7 @@
    },
    create: {
        title: '添加',
        init: '初始化',
        empty: {
            title: '暂无数据',
            desc: '请先添加数据',
@@ -249,6 +250,9 @@
            },
            basContainer: {
                containerType: '容器类型',
                startNo: '起始数值',
                endNo: '结束数值',
                code: '条码',
                codeType: '条码类型',
                areas: '可入库区',
            },
@@ -1332,6 +1336,7 @@
        confirm: '确认',
        start: '自动下发',
        autoStartLocs: '自动跑库',
        init: "初始化",
        stopPub: '终止下发',
        pause: '暂停',
        pick: '拣料',
rsf-admin/src/page/basicInfo/basContainer/BasContainerInit.jsx
New file
@@ -0,0 +1,134 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
    SelectArrayInput,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../../components/DialogCloseButton";
import StatusSelectInput from "../../components/StatusSelectInput";
import DictionarySelect from "../../components/DictionarySelect";
import MemoInput from "../../components/MemoInput";
const BasContainerCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                resource="/basContainer/init"
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.init')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <BooleanInput
                                        label="table.field.deviceSite.flagInit"
                                        source="flagInit"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DictionarySelect
                                        label={translate("table.field.basStation.containerType")}
                                        name="containerType"
                                        size="small"
                                        validate={[required()]}
                                        dictTypeCode="sys_container_type"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.basContainer.startNo"
                                        source="startNo"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.basContainer.endNo"
                                        source="endNo"
                                        parse={v => v}
                                    />
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default BasContainerCreate;
rsf-admin/src/page/basicInfo/basContainer/BasContainerList.jsx
@@ -31,6 +31,7 @@
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
    Button,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
@@ -42,8 +43,11 @@
import PageDrawer from "../../components/PageDrawer";
import MyField from "../../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
import CrossZoneAreaField from "../basStation/CrossZoneAreaField";
import AllInclusiveIcon from '@mui/icons-material/AllInclusive';
import BasContainerInit from "./BasContainerInit";
import PrintModal from './PrintModal'
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
@@ -85,6 +89,9 @@
    const [areaFieldDialog, setAreaFieldDialog] = useState(false);
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    const [open, setOpen] = useState(false);
    const [print, setPrint] = useState(false);
    const [selectPrints, setSelectPrints] = useState([]);
    return (
        <Box display="flex">
@@ -98,11 +105,12 @@
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.basContainer"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                empty={false}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <InitButton setOpen={setOpen} />
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='basContainer' />
@@ -113,21 +121,18 @@
            >
                <StyledDatagrid
                    preferenceKey='basContainer'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    bulkActionButtons={<>
                        <BulkPrintBarcode setPrint={setPrint} setSelectPrints={setSelectPrints} />
                        <BulkDeleteButton mutationMode={OPERATE_MODE} />
                    </>}
                    rowClick={(id, resource, record) => false}                    
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo','statusBool']}
                    omit={['id', 'statusBool']}
                >
                    <NumberField source="id" />
                    <NumberField source="containerType$" label="table.field.basContainer.containerType" />
                    <TextField source="code" label="table.field.basContainer.code" />
                    <TextField source="codeType" label="table.field.basContainer.codeType" />
                    <WrapperField cellClassName="areas" label="table.field.basContainer.areas">
                        <CrossZoneAreaField
                            open={areaFieldDialog}
                            setOpen={setAreaFieldDialog}
                        />
                    </WrapperField>
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
@@ -148,6 +153,15 @@
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <BasContainerInit
                open={open}
                setOpen={setOpen}
            />
            <PrintModal
                open={print}
                setOpen={setPrint}
                rows={selectPrints}
            />
            <PageDrawer
                title='BasContainer Detail'
                drawerVal={drawerVal}
@@ -158,4 +172,38 @@
    )
}
//初始化按钮
const InitButton = ({ setOpen }) => {
    const init = () => {
        setOpen(true)
    }
    return (
        <Button
            label="toolbar.init"
            variant="text"
            size="small"
            onClick={init}
            startIcon={<AllInclusiveIcon />} />
    )
}
const BulkPrintBarcode = ({ setPrint, setSelectPrints }) => {
    const { selectedIds } = useListContext();
    //打印
    const print = () => {
        setPrint(true);
        setSelectPrints(selectedIds);
    }
    return (
        <Button
            label="toolbar.print"
            variant="text"
            size="small"
            onClick={print}
            startIcon={<AllInclusiveIcon />} />
    )
}
export default BasContainerList;
rsf-admin/src/page/basicInfo/basContainer/PrintModal.jsx
New file
@@ -0,0 +1,249 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
    useListContext,
    useRefresh,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Grid,
    TextField,
    Box,
    Button,
    Radio,
    RadioGroup,
    FormControlLabel,
    FormControl,
    FormLabel,
    TableRow,
    TableCell,
    Tooltip,
    IconButton,
    styled
} 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 StatusSelectInput from "../../components/StatusSelectInput";
import { useReactToPrint } from "react-to-print";
import jsbarcode from 'jsbarcode'
import { el } from "date-fns/locale";
import { padding } from "@mui/system";
const PrintModal = ({ open, setOpen, rows }) => {
    const refresh = useRefresh();
    const translate = useTranslate();
    const notify = useNotify();
    const contentRef = useRef();
    const reactToPrintFn = useReactToPrint({
        content: () => {
            return contentRef.current
        },
        documentTitle: `物料信息`,
        pageStyle: `
        @page {
            margin: 10mm;
        }
        @media print {
             html, body {
                width: 70mm;     // A4横向宽度
                height: 40mm;    // A4横向高度
            }
        }`
    });
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const [value, setValue] = useState('temp1');
    const handleChange = (event) => {
        setValue(event.target.value);
    };
    const handlePrint = () => {
        // handleClose()
        reactToPrintFn()
    };
    return (
        <Dialog open={open} maxWidth="sm" fullWidth>
            <DialogCloseButton onClose={handleClose} />
            <DialogTitle>{translate('toolbar.print')}</DialogTitle>
            <DialogContent >
                <FormControl >
                    <RadioGroup
                        row
                        aria-labelledby="demo-controlled-radio-buttons-group"
                        name="controlled-radio-buttons-group"
                        value={value}
                        onChange={handleChange}
                        size="small"
                        sx={{ justifyContent: 'center' }}
                    >
                        <FormControlLabel value="temp1" control={<Radio />} label="模板1" size="small" />
                    </RadioGroup>
                </FormControl>
                <Box>
                    <div style={{ textAlign: 'center', display: 'flex', justifyContent: 'center' }}>
                        <table
                            className="contain"
                            style={{
                                overflow: 'hidden',
                                fontSize: 'small',
                                tableLayout: 'fixed',
                                width: '280px',
                                borderCollapse: 'collapse', // 合并边框
                                border: '1px solid black' // 设置表格整体边框
                            }}
                        >
                            <tbody>
                                <tr style={{ height: '94px' ,padding: '5px', }}>
                                    <td
                                        align="center"
                                        className="barcode"
                                        colSpan={12}
                                        style={{ border: '1px solid black' }}
                                    >
                                        <img className="template-code" src={'/img/barcode.jpeg'} style={{ width: '90%' }} alt="Barcode" />
                                        <div style={{ letterSpacing: '2px', marginTop: '1px', textAlign: 'center' }}>
                                            <span>{'xxxxxx'}</span>
                                        </div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                    <style>{`
                    @media print {
                    .print-content {
                            display: block!important;
                        }
                    }`} </style>
                    <div ref={contentRef} className="print-content" style={{ textAlign: 'center', display: 'none' }}>
                        <PrintTemp key={'bb'} rows={rows} />
                    </div>
                </Box>
            </DialogContent>
            <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
                    <Button onClick={handlePrint} variant="contained" startIcon={<SaveIcon />}>
                        {translate('toolbar.confirm')}
                    </Button>
                </Box>
            </DialogActions>
        </Dialog >
    );
}
export default PrintModal;
const PrintTemp = ({ rows }) => {
    const notify = useNotify();
    const [data, setData] = useState([]);
    const http = async () => {
        const res = await request.post(`/basContainer/many/${rows?.join()}`);
        if (res?.data?.code === 200) {
            let val = res.data.data.map((el => {
                return {
                    barcode: '/img/barcode.jpeg',
                    code: el.code,
                    name: el.name,
                    memo: el.memo
                }
            }))
            setData(val)
            setTimeout(() => {
                val.forEach((el) => {
                    jsbarcode(`#barcode${el.code}`, el.code, { height: 30 });
                });
            }, 10);
        } else {
            notify(res.data.msg);
        }
    }
    useEffect(() => {
        if (rows?.length > 0) {
            http();
        }
    }, [rows]);
    return (
        <>
            {data.map((item, index) => (
                <table
                    key={index}
                    className="contain"
                    style={{
                        overflow: 'hidden',
                        fontSize: 'small',
                        tableLayout: 'fixed',
                        width: '520px',
                        borderCollapse: 'collapse',
                        borderSpacing: 0,
                        margin: '0 auto',
                        marginTop: '10px',
                    }}
                >
                    <tbody>
                        <tr style={{ height: '74px' }}>
                            <td
                                align="center"
                                className="barcode"
                                colSpan={9}
                                style={{ border: '1px solid black' }}
                            >
                                {/* <img id={"barcode" + item.code} style={{ width: '70%', verticalAlign: 'middle' }} /> */}
                                <img className="template-code" src={item.barcode} style={{ width: '90%', verticalAlign: 'middle' }} alt="Barcode" />
                                <div style={{ letterSpacing: '2px', marginTop: '1px', textAlign: 'center' }}>
                                    <span>{item.code}</span>
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            ))}
        </>
    )
}
rsf-admin/src/page/container/ContainerList.jsx
@@ -31,6 +31,7 @@
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
    Button,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
@@ -43,6 +44,7 @@
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
import AllInclusiveIcon from '@mui/icons-material/AllInclusive';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
@@ -122,6 +124,7 @@
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <InitButton />
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='container' />
@@ -183,4 +186,22 @@
    )
}
//初始化按钮
const InitButton = ({ setOpen }) => {
    const close = () => {
        setOpen(false)
    }
    return (
        <Button
            label="toolbar.init"
            variant="outlined"
            size="medium"
            onClick={close}
            startIcon={<AllInclusiveIcon />}
            sx={{ margin: '3.5em' }} />
    )
}
export default ContainerList;
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/BasContainerController.java
@@ -9,6 +9,7 @@
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.manager.controller.params.InitContainerParams;
import com.vincent.rsf.server.manager.entity.BasContainer;
import com.vincent.rsf.server.manager.entity.BasStation;
import com.vincent.rsf.server.manager.service.BasContainerService;
@@ -32,18 +33,18 @@
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<BasContainer, BaseParam> pageParam = new PageParam<>(baseParam, BasContainer.class);
        PageParam<BasContainer, BaseParam> page = basContainerService.page(pageParam, pageParam.buildWrapper(true));
        for (BasContainer container : page.getRecords()) {
            if (!Cools.isEmpty(container.getAreas())) {
                String content = container.getAreas().substring(1, container.getAreas().length() - 1);
                String[] parts = content.split(",");
                Long[] longArray = new Long[parts.length];
                for (int i = 0; i < parts.length; i++) {
                    longArray[i] = Long.parseLong(parts[i].trim());
                }
                container.setAreaIds(longArray);
            }
        }
//        for (BasContainer container : page.getRecords()) {
//            if (!Cools.isEmpty(container.getAreas())) {
//                String content = container.getAreas().substring(1, container.getAreas().length() - 1);
//                String[] parts = content.split(",");
//                Long[] longArray = new Long[parts.length];
//                for (int i = 0; i < parts.length; i++) {
//                    longArray[i] = Long.parseLong(parts[i].trim());
//                }
//                container.setAreaIds(longArray);
//            }
//
//        }
        return R.ok().add(page);
    }
@@ -133,6 +134,22 @@
        return R.ok().add(vos);
    }
    /**
     * 初始化
     * @return
     */
    @PreAuthorize("hasAuthority('manager:basContainer:list')")
    @OperationLog("容器初始化")
    @PostMapping("/basContainer/init/save")
    public R init(@RequestBody InitContainerParams params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        return basContainerService.init(params, getLoginUserId());
    }
    @PreAuthorize("hasAuthority('manager:basContainer:list')")
    @PostMapping("/basContainer/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/InitContainerParams.java
New file
@@ -0,0 +1,31 @@
package com.vincent.rsf.server.manager.controller.params;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "InitContainerParams", description = "容器初始化")
public class InitContainerParams {
    @ApiModelProperty("起始数值")
    private Integer startNo;
    @ApiModelProperty("结束数值")
    private Integer endNo;
    @ApiModelProperty("容器类型")
    private Long containerType;
    @ApiModelProperty("长度")
    private Integer length = 6;
    @ApiModelProperty("前缀")
    private String prefix = "31";
    @ApiModelProperty("是否初始化")
    private Boolean flagInit = false;
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/BasContainer.java
@@ -8,6 +8,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.vincent.rsf.server.system.entity.DictData;
import com.vincent.rsf.server.system.service.DictDataService;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -24,6 +25,7 @@
import java.util.Date;
@Data
@Accessors(chain = true)
@TableName("man_bas_container")
public class BasContainer implements Serializable {
@@ -35,6 +37,10 @@
    @ApiModelProperty(value= "id")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("唯一编码")
    private String code;
    /**
     * 容器类型
@@ -58,7 +64,6 @@
     * 是否删除 1: 是  0: 否  
     */
    @ApiModelProperty(value= "是否删除 1: 是  0: 否  ")
    @TableLogic
    private Integer deleted;
    /**
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/QRCodeType.java
New file
@@ -0,0 +1,20 @@
package com.vincent.rsf.server.manager.enums;
/**
 * 容器编码类型
 */
public enum QRCodeType {
    //容器编码类型
    QRCODE_TYPE_QRCODE(1, "二维码"),
    QRCODE_TYPE_BARCODE(0, "条型码")
    ;
    QRCodeType(Integer val, String desc) {
        this.val = val;
        this.desc = desc;
    }
    public Integer val;
    public String desc;
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/BasContainerService.java
@@ -1,8 +1,11 @@
package com.vincent.rsf.server.manager.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.manager.controller.params.InitContainerParams;
import com.vincent.rsf.server.manager.entity.BasContainer;
public interface BasContainerService extends IService<BasContainer> {
    R init(InitContainerParams params, Long loginUserId);
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/BasContainerServiceImpl.java
@@ -1,12 +1,79 @@
package com.vincent.rsf.server.manager.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.manager.controller.params.InitContainerParams;
import com.vincent.rsf.server.manager.entity.WarehouseAreas;
import com.vincent.rsf.server.manager.enums.QRCodeType;
import com.vincent.rsf.server.manager.mapper.BasContainerMapper;
import com.vincent.rsf.server.manager.entity.BasContainer;
import com.vincent.rsf.server.manager.service.BasContainerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vincent.rsf.server.manager.service.WarehouseAreasService;
import org.apache.tika.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@Service("basContainerService")
public class BasContainerServiceImpl extends ServiceImpl<BasContainerMapper, BasContainer> implements BasContainerService {
    @Autowired
    private WarehouseAreasService warehouseAreasService;
    /**
     * 容器初始化
     *
     * @param params
     * @param loginUserId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R init(InitContainerParams params, Long loginUserId) {
        if (Objects.isNull(params.getStartNo())) {
            throw new CoolException("容器起始值不能为空!!");
        }
        if (Objects.isNull(params.getEndNo())) {
            throw new CoolException("容器结束值不能为空!!");
        }
        WarehouseAreas areas = warehouseAreasService.getOne(new LambdaQueryWrapper<WarehouseAreas>().eq(WarehouseAreas::getId, 42L));
        if (Objects.isNull(areas)) {
            throw new CoolException("库区不存在,请联系管理员!!");
        }
        if (params.getFlagInit()) {
            this.remove(new LambdaQueryWrapper<>());
        }
        List<BasContainer> containerList = new ArrayList<>();
        for (int i = params.getStartNo(); i <= params.getEndNo() ; i++) {
            BasContainer container = new BasContainer();
            String code = StringUtils.leftPad(i + "", params.getLength(), "0");
            container.setAreas(areas.getName())
                    .setCodeType(QRCodeType.QRCODE_TYPE_BARCODE.desc)
                    .setCode(params.getPrefix() + code)
                    .setCreateTime(new Date())
                    .setCreateBy(loginUserId)
                    .setUpdateBy(loginUserId)
                    .setUpdateTime(new Date())
                    .setContainerType(params.getContainerType());
            containerList.add(container);
        }
        if (!this.saveBatch(containerList)) {
            throw new CoolException("容器保存失败,请检查编码是否有重复!!");
        }
        return R.ok();
    }
}
rsf-server/src/main/resources/application-dev.yml
@@ -14,10 +14,10 @@
#    url: jdbc:mysql://47.76.147.249:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
#    username: rsf
    username: root
    url: jdbc:mysql://10.10.10.200:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    password: xltys1995
#    url: jdbc:mysql://127.0.0.1:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
#    password: 34821015
#    url: jdbc:mysql://10.10.10.200:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
#    password: xltys1995
    url: jdbc:mysql://127.0.0.1:3306/rsf-xiri?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    password: 34821015
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 5
@@ -30,7 +30,7 @@
      test-on-borrow: true
      test-on-return: false
      remove-abandoned: true
      remove-abandoned-timeout: 1800
      remove-abandoned-timeout: 18
      #pool-prepared-statements: false
      #max-pool-prepared-statement-per-connection-size: 20
      filters: stat, wall
rsf-server/src/main/resources/application.yml
@@ -25,7 +25,7 @@
  #  global-config:
  #    field-strategy: 0
  configuration:
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
    cache-enabled: true
    call-setters-on-nulls: true