Hệ thống quản lý tồn kho nguyên liệu cho nhà máy thực phẩm với Spring Boot và Vue.js

Thiết kế kiến trúc công nghệ

Dự án áp dụng kiến trúc phân tầng rõ ràng, tách biệt giữa giao diện người dùng và logic nghiệp vụ, đảm bảo khả năng mở rộng và bảo trì cao.

Backend dựa trên Spring Boot

Sử dụng Spring Boot 3.x làm nền tảng chính để xây dựng API RESTful. Cơ chế xác thực được triển khai qua Spring Security kết hợp JWT, hỗ trợ phân quyền theo vai trò (admin, nhân viên kho, kiểm nghiệm). Lớp truy vấn dữ liệu sử dụng JPA với các tùy chỉnh thông qua @Query hoặc tích hợp MyBatis-Plus cho các thao tác phức tạp. Tài liệu API được tự động sinh bởi Springdoc OpenAPI (thế hệ mới của Swagger).

Frontend với Vue 3 và Composition API

Giao diện được phát triển bằng Vue 3, tận dụng tính năng setup script và phản ứng hóa trạng thái thông qua refcomputed. Thư viện UI là Element Plus, kết hợp với Vue Router cho điều hướng và Pinia để quản lý trạng thái toàn cục. Các yêu cầu HTTP được xử lý đồng bộ và bất đồng bộ thông qua Axios, kèm cơ chế retry và xử lý lỗi tập trung.

Cơ sở dữ liệu quan hệ

Sử dụng MySQL 8.0 với cấu trúc bảng tối ưu hóa cho truy vấn nhanh và ràng buộc toàn vẹn:

  • Bảng nguyên liệu: raw_material_id, material_name, category_code, shelf_life_days, supplier_ref
  • Bảng tồn kho chi tiết: stock_id, material_id, batch_identifier, current_quantity, warehouse_zone
  • Bảng kiểm kê định kỳ: audit_id, auditor_id, audit_timestamp, discrepancy_status

Các chức năng trọng tâm

Theo dõi tồn kho thời gian thực

Hệ thống cập nhật số lượng tồn sau mỗi giao dịch nhập/xuất. Khi tồn kho giảm dưới ngưỡng cảnh báo (cấu hình linh hoạt), hệ thống gửi thông báo tức thì qua WebSocket tới người phụ trách kho. Dữ liệu lịch sử được biểu diễn trực quan bằng biểu đồ đường và cột tương tác sử dụng thư viện Apache ECharts.

Quản lý lô sản xuất và truy xuất nguồn gốc

Mỗi lô nguyên liệu được gắn mã duy nhất, liên kết với đơn hàng mua, kết quả kiểm nghiệm vi sinh và hạn sử dụng. Hệ thống tự động đề xuất lô nào nên xuất trước (FIFO) dựa trên ngày sản xuất và thời hạn bảo quản — yêu cầu bắt buộc trong ngành thực phẩm.

Tự động hóa quy trình kiểm kê

Hỗ trợ quét mã QR/RFID tại hiện trường để thu thập dữ liệu nhanh chóng. Sau khi nhập xong, hệ thống so sánh tự động giữa số liệu thực tế và số liệu hệ thống, liệt kê chênh lệch theo từng mã lô và kích hoạt luồng phê duyệt điện tử nếu chênh lệch vượt ngưỡng cho phép.

Cấu hình môi trường phát triển

Tích hợp trong PyCharm

Cấu hình dự án đa mô-đun: module backend (Maven, JDK 17), module frontend (npm 18+, Node.js 20). Cài đặt plugin Vue.js và ESLint để hỗ trợ linting và autocomplete. Thiết lập proxy trong vite.config.ts để chuyển tiếp yêu cầu từ cổng 5173 sang backend chạy trên 8080, tránh lỗi CORS trong giai đoạn phát triển.

Sử dụng Django như công cụ hỗ trợ

Django không đóng vai trò backend chính, mà được dùng như một lớp tiện ích: Django Admin giúp tạo giao diện quản trị mẫu trong vài phút; Django REST Framework mô phỏng dữ liệu mẫu phục vụ testing frontend; Celery + Redis đảm nhận việc sinh báo cáo kiểm kê dạng PDF/XLSX bất đồng bộ, không chặn luồng xử lý chính.

Mẫu mã nguồn tiêu biểu

Repository JPA kiểm tra nguyên liệu hết hạn

@Repository
public interface RawMaterialRepo extends JpaRepository<RawMaterial, Long> {
    @Query("SELECT r FROM RawMaterial r WHERE r.expiryDate < :cutoffDate")
    List<RawMaterial> findNearExpiry(@Param("cutoffDate") LocalDate cutoffDate);
}

Component Vue kiểm kê với xử lý chọn hàng loạt

<template>
  <el-table :data="stockItems" row-key="batchIdentifier">
    <el-table-column type="selection" width="60"/>
    <el-table-column prop="batchIdentifier" label="Mã lô"/>
    <el-table-column prop="currentQuantity" label="Tồn kho hiện tại"/>
  </el-table>
  <el-button @click="executeAudit" type="primary">Xác nhận kiểm kê</el-button>
</template>

<script setup>
import { ref } from 'vue';
import axios from '@/utils/request';

const stockItems = ref([]);
const selectedBatchIds = ref([]);

const handleSelectionChange = (selection) => {
  selectedBatchIds.value = selection.map(item => item.batchIdentifier);
};

const executeAudit = async () => {
  try {
    await axios.post('/api/v1/audit/batch', { batchList: selectedBatchIds.value });
    ElMessage.success('Kiểm kê thành công');
  } catch (err) {
    ElMessage.error('Lỗi khi thực hiện kiểm kê');
  }
};
</script>

An toàn và bảo mật hệ thống

Trao đổi dữ liệu giữa client và server luôn được mã hóa qua HTTPS (TLS 1.3). Các trường nhạy cảm như thông tin nhà cung cấp hoặc hạn sử dụng được mã hóa hai chiều bằng thuật toán AES-256-GCM trước khi lưu vào cơ sở dữ liệu. Chính sách phân quyền dựa trên RBAC, với ba nhóm vai trò rõ ràng và có thể mở rộng. Toàn bộ dữ liệu được sao lưu định kỳ lên đối tượng lưu trữ đám mây (AWS S3 hoặc MinIO), kèm cơ chế retention tự động.

Thẻ: spring-boot Vue3 element-plus jpa mysql

Đăng vào ngày 22 tháng 5 lúc 13:31