7de56ab8061601614a9c29af42acadfcddcafdce..eeb96ed3c9830f996dc85cc9d4a8113aba91692b
2025-06-30 zjj
Merge remote-tracking branch 'origin/devlop' into devlop
eeb96e 对比 | 目录
2025-06-30 zjj
#
54cc43 对比 | 目录
2025-06-30 skyouc
代码优化
7e9aba 对比 | 目录
13个文件已修改
1个文件已添加
211 ■■■■ 已修改文件
rsf-admin/.env 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/InitModal.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderList.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderModal.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderPreview.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutStockPublic.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/controller/mcp/McpController.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/controller/pda/PdaOutStockController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/LocMastInitParam.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/Shelves.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/.env
@@ -1,3 +1,3 @@
VITE_BASE_IP=192.168.4.12
VITE_BASE_IP=127.0.0.1
# VITE_BASE_IP=47.76.147.249
VITE_BASE_PORT=8080
rsf-admin/src/i18n/en.js
@@ -437,6 +437,7 @@
                col: "Col",
                lev: "Lev",
                channel: "Channel",
                startChannel: "startChannel",
                maxParts: "MaxParts",
                maxPack: "MaxPack",
                flagLabelMange: "FlagLabelMange",
rsf-admin/src/i18n/zh.js
@@ -445,6 +445,7 @@
                flagLogic: "虚拟库位",
                fucAtrrs: "功能属性",
                barcode: "容器码",
                startChannel: "起始巷道",
                unit: "单位",
                size: "长/宽/高",
                length: "长",
rsf-admin/src/page/basicInfo/loc/InitModal.jsx
@@ -235,6 +235,17 @@
                                    validate={[required()]}
                                />
                            </Grid>
                            <Grid item xs={4}>
                                <TextInput
                                    label={"table.field.loc.startChannel"}
                                    name="startChannel"
                                    value={formData.startChannel}
                                    onChange={(e) => handleChange(+e.target.value, 'startChannel')}
                                    size="small"
                                    type="number"
                                    validate={[required()]}
                                />
                            </Grid>
                        </Grid>
                    </Box>
                </DialogContent>
rsf-admin/src/page/orders/outStock/OutOrderList.jsx
@@ -222,7 +222,7 @@
        drawerVal={drawerVal}
        setDrawerVal={setDrawerVal}
      >
        <OutStockPublic record={select} open={drawerVal} setOpen={setDrawerVal} />
        <OutStockPublic record={select} open={drawerVal} setOpen={setDrawerVal}  setManualDialog={setManualDialog}/>
      </PageEditDrawer>
    </Box >
  )
rsf-admin/src/page/orders/outStock/OutOrderModal.jsx
@@ -96,10 +96,8 @@
    const translate = useTranslate();
    const [params, setParams] = useState({});
    const [select, setSelect] = useState([]);
    const [drawerVal, setDrawerVal] = useState(false);
    const refresh = useRefresh();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
@@ -253,7 +251,7 @@
                </DialogContent>
            </Grid>
            <Grid>
                <OutOrderPreview open={preview} setOpen={setPreview} selectedIds={select} />
                <OutOrderPreview open={preview} setOpen={setPreview} selectedIds={select} setCloseParent={setOpen} />
            </Grid>
        </Dialog >
    )
rsf-admin/src/page/orders/outStock/OutOrderPreview.jsx
@@ -16,7 +16,7 @@
const OutOrderPreview = (props) => {
    const { open, setOpen, record, selectedIds } = props;
    const { open, setOpen, record, selectedIds, setCloseParent } = props;
    const translate = useTranslate();
    const gridRef = useGridApiRef();
    const [rows, setRows] = useState([]);
@@ -26,6 +26,7 @@
        if (reason !== "backdropClick") {
            // const res = await request.get(`/outStock/items/cancel/` + selectedIds);
            setOpen(false);
            setCloseParent(false)
        }
    };
@@ -66,7 +67,7 @@
                    </Grid>
                </Grid>
                <Toolbar sx={{ justifyContent: 'end' }}>
                    <ConfirmButton label="toolbar.confirm" variant="contained" size="large" gridRef={gridRef} setOpen={setOpen} />
                    <ConfirmButton label="toolbar.confirm" variant="contained" size="large" gridRef={gridRef} setOpen={setOpen} setCloseParent={setCloseParent}/>
                </Toolbar>
            </DialogContent>
        </Dialog>
@@ -75,7 +76,7 @@
export default OutOrderPreview;
const ConfirmButton = ({ gridRef, setOpen }) => {
const ConfirmButton = ({ gridRef, setOpen, setCloseParent }) => {
    const refresh = useRefresh();
    const notify = useNotify();
    const confirm = async () => {
@@ -85,6 +86,7 @@
            notify(msg);
            refresh()
            setOpen(false)
            setCloseParent(false)
        } else {
            notify(msg);
        }
rsf-admin/src/page/orders/outStock/OutStockPublic.jsx
@@ -67,7 +67,7 @@
}));
const OutStockPublic = (props) => {
    const { record, open, setOpen } = props;
    const { record, open, setOpen, setManualDialog } = props;
    const notify = useNotify();
    const gridRef = useGridApiRef();
    const [rows, setRows] = useState([]);
@@ -103,7 +103,6 @@
        return (
            <Button label="toolbar.confirm" size="medium" onClick={handleRowClick} />
        )
    };
    const handleClickOpen = () => {
@@ -133,10 +132,8 @@
    };
    useEffect(() => {
        if (open) {
            getWaveRule()
        }
    }, [open, formData])
        getWaveRule()
    }, [open])
    const getWaveRule = async () => {
        if (formData.waveId == null && formData.waveId == undefined) {
@@ -144,7 +141,7 @@
        }
        const { data: { code, data, msg } } = await request.post('/outStock/order/getOutTaskItems', { ...formData });
        if (code === 200) {
            setRows(data)
            // setRows(data)
            setFetchRows(data)
        } else {
            notify(msg);
rsf-server/src/main/java/com/vincent/rsf/server/api/controller/mcp/McpController.java
@@ -5,6 +5,7 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.common.constant.Constants;
import com.vincent.rsf.server.common.utils.FieldsUtils;
import com.vincent.rsf.server.manager.controller.params.LocToTaskParams;
@@ -86,13 +87,13 @@
        }
        param.setType(Constants.TASK_TYPE_OUT_STOCK);
//        try {
//            locItemService.generateTask(TaskResouceType.TASK_RESOUCE_STOCK_TYPE.val, param, getLoginUserId());
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
        try {
            locItemService.generateTask(TaskResouceType.TASK_RESOUCE_STOCK_TYPE.val, param, getLoginUserId());
        } catch (Exception e) {
            throw new CoolException(e);
        }
        return R.ok(param);
        return R.ok();
    }
rsf-server/src/main/java/com/vincent/rsf/server/api/controller/pda/PdaOutStockController.java
@@ -32,7 +32,7 @@
    @PreAuthorize("hasAuthority('manager:task:list')")
    @GetMapping("/saveOutTaskSts/{barcode}")
    @ApiOperation("快速拣货查询")
    @ApiOperation("快速拣货")
    public R saveOutTaskSts(@PathVariable String barcode) {
        return pdaOutStockService.saveOutTaskSts(barcode);
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/LocMastInitParam.java
@@ -54,5 +54,9 @@
    @NotBlank(message = "巷道")
    private Integer channel;
    @ApiModelProperty("起始巷道")
    @NotBlank(message = "起始巷道")
    private Integer startChannel;
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.manager.controller.params.LocMastInitParam;
@@ -11,6 +12,7 @@
import com.vincent.rsf.server.manager.mapper.LocTypeRelaMapper;
import com.vincent.rsf.server.manager.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vincent.rsf.server.manager.utils.Shelves;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -106,8 +108,20 @@
        List<Loc> list = new ArrayList<>();
        Integer chanl = 0; //默认第一巷道
        for (int r = param.getStartRow(); r <= param.getEndRow(); r++) {
            if (r % param.getChannel() == 1) {
                chanl ++;
            try{
                Shelves shelves = new Shelves(param.getEndRow() - param.getStartRow() + 1, param.getChannel(),param.getStartRow());
                for (List<Integer> node : shelves.nodes){
                    if (node.contains(r)) {
                        if (!Cools.isEmpty(param.getStartChannel()) && param.getStartChannel() > 0){
                            chanl = shelves.nodes.indexOf(node) + param.getStartChannel();
                        }else {
                            chanl = shelves.nodes.indexOf(node) + 1;
                        }
                        break;
                    }
                }
            }catch (Exception e){
                throw new CoolException("解析巷道号失败");
            }
            for (int b = param.getStartBay(); b <= param.getEndBay(); b++) {
                for (int l = param.getStartLev(); l <= param.getEndLev(); l++) {
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -193,6 +193,8 @@
                    .setId(null)
                    .setUpdateBy(loginUserId)
                    .setCreateBy(loginUserId)
                    .setCreateTime(new Date())
                    .setUpdateTime(new Date())
                    .setPoCode(delivery.getCode());
            if (!this.save(order)) {
                throw new CoolException("主单保存失败!!");
rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/Shelves.java
New file
@@ -0,0 +1,132 @@
package com.vincent.rsf.server.manager.utils;
import com.alibaba.fastjson.JSON;
import com.vincent.rsf.framework.common.Arith;
import com.vincent.rsf.framework.exception.CoolException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
 * <strong>立库货架实体类</strong>
 * Created by vincent on 2020/6/11
 */
public class Shelves {
    // 货架排数量
    public final int size;
    // 货架组数量
    public final int group;
    // 偏移量[default:0]
    public final int offset;
    // 货架实例节点集合
    public List<List<Integer>> nodes;
    public Shelves(int size, int group) {
        this(size, group, 0);
    }
    /**
     * @param size 货架单排总数
     * @param group 货架组数量
     * @param offset 序列号偏移量
     */
    public Shelves(int size, int group, int offset) {
        this.size = size;
        this.group = group;
        this.offset = offset-1;
        init();
    }
    /**
     * 初始化方法【私有】
     */
    private void init(){
        if (group == 0 || size%group != 0) {
            throw new RuntimeException("shelves init fail!");
        }
        nodes = new ArrayList<>();
        for (int g = 1; g <= this.group; g++){
            int unit = size/group;
            List<Integer> node = new ArrayList<>();
            for (int i = (g-1)*unit+1+offset ; i <= g*unit+offset; i++){
                node.add(i);
            }
            nodes.add(node);
        }
    }
    /**
     * 开始计算 =======>>>
     *
     *          货架命中规则如下:
     *              安装位置:   [1]  [2]  |  [3]  [4]  --------  [5] [6]  |  [7] [8]
     *                  命中顺序:      1 -> 5 -> 4 -> 8 -> 2 -> 6 -> 3 -> 7 -> 1 ...
     *
     *          1.该规则适不限制货架数量,总数与组别在构造器中设置
     *          2.如有序列号起始问题,用偏移量规避即可
     *
     * @param curSeq 当前货架号
     * @return 规则命中货架号
     */
    public int start(int curSeq){
        Iterator<List<Integer>> iterator = nodes.iterator();
        while (iterator.hasNext()){
            List<Integer> node = iterator.next();
            if (node.contains(curSeq)) {
                int idx = node.indexOf(curSeq);
                // 是否为末尾货架
                if (iterator.hasNext()) {
                    return iterator.next().get(idx);
                } else {
                    List<Integer> first = nodes.get(0);
                    int val = first.get(idx);
                    int res = size / group + 1 + offset - val;
                    // 反向命中货架时不再是对立下标(相对于巷道)
                    if (res < val) {
                        // 轮询所有货架后重新开始定位
                        if (val - res - offset == 1) {
                            return first.get(0);
                        }
                        res = res + 1;
                    }
                    return res + offset;
                }
            }
        }
        return -1;
    }
    public Integer get(Integer curRow) {
        for (List<Integer> node : nodes){
            if (node.contains(curRow)) {
                return nodes.indexOf(node) + 1;
            }
        }
        throw new CoolException("货排检索系统报错, node:" + JSON.toJSONString(nodes) + ", curRow:" + curRow);
    }
    public static void main(String[] args) throws InterruptedException {
        double remainder = Arith.divides(1,16 - 1, 16);
        System.out.println(remainder);
        System.out.println((int) remainder);
//        Shelves shelves = new Shelves(8,2);
//        System.out.println(shelves.nodes.toString());
//        int start = 1;
//        while (true) {
//            System.out.println(start);
//            start = shelves.start(start);
//            Thread.sleep(500L);
//        }
    }
}