Springboot vue仓库管理系统源码Java 前后端分离 WMS仓库管理 BS 功能见详情

最近在折腾一个前后端分离的仓库管理系统,用SpringBoot+Vue搞了套WMS方案。这玩意儿用起来比传统单体架构灵活不少,特别是库存实时更新这块,用WebSocket推数据比轮询舒服多了。先看后端怎么处理入库逻辑:

@PostMapping("/stock-in")
public ResponseDto stockIn(@RequestBody StockOperationDto dto) {
    // 这里有个细节:事务里先锁库存记录防止并发问题
    Inventory inventory = inventoryService.lockInventory(ddto.getMaterialId());
    inventoryService.addStock(inventory, dto.getQuantity(), dto.getOperator());
    // 推送到前端看板
    webSocketHandler.sendStockChange(inventory);
    return ResponseDto.success(inventory.getCurrentStock());
}

这里用了双重保障:数据库行锁+操作日志。之前试过不加锁直接更新,结果测试时两个同时入库的请求直接把库存数搞乱了。日志表设计也花了点心思:

@Entity
public class OperationLog {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Long id;
    private String operationType; // IN/OUT/ADJUST
    @Column(precision = 10, scale = 2)
    private BigDecimal quantity;
    @ManyToOne
    private Operator operator;
    private LocalDateTime timestamp = LocalDateTime.now();
}

注意这个BigDecimal类型,用double的话金额计算会出精度问题。曾经有个项目因为用了double导致库存金额差了几毛钱,排查到凌晨三点...

前端用Vue3+Pinia状态管理,仓库看板组件是关键。这是库存实时更新的处理:

<script setup>
const ws = new WebSocket('wss://yourdomain/ws-stock')

watchEffect(() => {
  ws.onmessage = (event) => {
    const data = JSON.parse(event.data)
    if (data.type === 'STOCK_UPDATE') {
      store.updateInventoryRealTime(data.payload)
    }
  }
})
</script>

这里有个坑:WebSocket重连机制。刚开始没加心跳检测,网络波动时连接断了不会自动重连。后来加了指数退避重试:

let retries = 0;
function connect() {
  ws = new WebSocket(url);
  ws.onclose = () => {
    const timeout = Math.min(1000 * Math.pow(2, retries), 30000);
    setTimeout(connect, timeout);
    retries++;
  }
}

权限控制方面,后端用Spring Security做了细粒度控制。比如质检员只能看到质检相关菜单:

@PreAuthorize("hasRole('QUALITY_CHECK') || hasRole('ADMIN')")
@GetMapping("/quality-records")
public Page<QualityRecord> getQualityRecords(Pageable pageable) {
    return qualityService.getRecords(pageable);
}

前端路由根据权限动态生成,避免硬编码。用了个骚操作:登录后把权限树缓存在IndexedDB里,下次进系统不用重新拉取。

遇到最头疼的问题是条码打印兼容性。不同型号的打印机指令集不一样,最后用了个折中方案:后端生成PDF,让浏览器调用本地打印对话框。虽然不如直接发指令给打印机快,但兼容性无敌。

整个项目搞下来最大的体会是:仓库管理系统最核心的不是技术多牛逼,而是业务逻辑的严密性。比如库存移动必须同时记录操作日志和库存变更,任何一个环节没加事务都可能造成数据不一致。源码里用了Command模式来封装操作命令,方便回滚和审计:

public class StockOutCommand implements InventoryCommand {
    @Override
    public void execute() {
        // 扣减库存
        // 生成出库单
        // 记录操作日志
    }

    @Override
    public void undo() {
        // 恢复库存
        // 标记出库单作废
    }
}

这种设计在后来加撤销功能时省了不少事。前后端分离确实让迭代变快了,但接口版本管理要特别注意。我们给每个接口都加了/v1/前缀,防止前端没更新时调用到新版接口。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐