Kiến trúc hệ thống
Hệ thống được xây dựng theo mô hình phân lớp 3-tier: frontend, backend và database. Kiến trúc này giúp hệ thống dễ bảo trì và mở rộng. Backend sử dụng SpringBoot framework để xử lý logic nghiệp vụ, RESTful API cho frontend tương tác.
Hiện thực cơ bản
Dưới đây là một số đoạn mã mẫu trong hệ thống:
Controller quản lý người dùng
@RestController
@RequestMapping("/api/auth")
public class AuthenticationController {
@Autowired
private AccountService accountService;
@Autowired
private JwtTokenProvider jwtProvider;
@PostMapping("/authenticate")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
AccountEntity account = accountService.findByUsername(loginRequest.getUsername());
if (account == null || !passwordEncoder.matches(loginRequest.getPassword(), account.getPassword())) {
return ResponseEntity.badRequest().body(new ApiResponse(false, "Thông tin đăng nhập không hợp lệ"));
}
if (!account.getRole().equals(loginRequest.getRole())) {
return ResponseEntity.badRequest().body(new ApiResponse(false, "Quyền truy cập không phù hợp"));
}
String jwt = jwtProvider.generateToken(account.getId(), account.getUsername(), account.getRole());
return ResponseEntity.ok(new JwtResponse(jwt));
}
@PostMapping("/signup")
public ResponseEntity<?> registerUser(@RequestBody SignUpRequest signUpRequest) {
if (accountService.existsByUsername(signUpRequest.getUsername())) {
return ResponseEntity.badRequest().body(new ApiResponse(false, "Tên người dùng đã tồn tại"));
}
AccountEntity account = new AccountEntity();
account.setUsername(signUpRequest.getUsername());
account.setPassword(passwordEncoder.encode(signUpRequest.getPassword()));
account.setRole(signUpRequest.getRole());
accountService.save(account);
return ResponseEntity.ok(new ApiResponse(true, "Đăng ký thành công"));
}
}
Service xử lý nghiệp vụ
@Service
@Transactional
public class LogisticsServiceImpl implements LogisticsService {
@Autowired
private ShipmentRepository shipmentRepository;
@Autowired
private TrackingRepository trackingRepository;
@Override
public Page<ShipmentEntity> getAllShipments(Pageable pageable, ShipmentFilter filter) {
Specification<ShipmentEntity> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (filter.getStatus() != null) {
predicates.add(cb.equal(root.get("status"), filter.getStatus()));
}
if (filter.getStartDate() != null && filter.getEndDate() != null) {
predicates.add(cb.between(root.get("createdAt"), filter.getStartDate(), filter.getEndDate()));
}
return cb.and(predicates.toArray(new Predicate[0]));
};
return shipmentRepository.findAll(spec, pageable);
}
@Override
@Transactional
public ShipmentEntity updateShipmentStatus(Long shipmentId, String newStatus, String updatedBy) {
ShipmentEntity shipment = shipmentRepository.findById(shipmentId)
.orElseThrow(() -> new ResourceNotFoundException("Không tìm thấy lô hàng"));
shipment.setStatus(newStatus);
shipment.setUpdatedBy(updatedBy);
shipment.setUpdatedAt(LocalDateTime.now());
TrackingEntity tracking = new TrackingEntity();
tracking.setShipmentId(shipmentId);
tracking.setStatus(newStatus);
tracking.setTimestamp(LocalDateTime.now());
tracking.setCreatedBy(updatedBy);
trackingRepository.save(tracking);
return shipmentRepository.save(shipment);
}
}
Cấu trúc database
-- Bảng tài khoản người dùng
CREATE TABLE IF NOT EXISTS user_accounts (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
email VARCHAR(100),
full_name VARCHAR(100),
role ENUM('ADMIN', 'MANAGER', 'STAFF', 'CUSTOMER') DEFAULT 'STAFF',
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Bảng thông tin lô hàng
CREATE TABLE IF NOT EXISTS shipments (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
tracking_code VARCHAR(50) NOT NULL UNIQUE,
sender_name VARCHAR(100) NOT NULL,
sender_phone VARCHAR(20),
sender_address TEXT,
recipient_name VARCHAR(100) NOT NULL,
recipient_phone VARCHAR(20),
recipient_address TEXT,
weight DECIMAL(10,2),
dimensions VARCHAR(50),
status ENUM('PENDING', 'PICKED_UP', 'IN_TRANSIT', 'DELIVERED', 'CANCELLED') DEFAULT 'PENDING',
created_by BIGINT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (created_by) REFERENCES user_accounts(id)
);
-- Bảng theo dõi hành trình
CREATE TABLE IF NOT EXISTS shipment_tracking (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
shipment_id BIGINT NOT NULL,
status VARCHAR(50) NOT NULL,
location VARCHAR(200),
description TEXT,
created_by BIGINT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (shipment_id) REFERENCES shipments(id),
FOREIGN KEY (created_by) REFERENCES user_accounts(id)
);
Công nghệ sử dụng
SpringBoot Framework: Là framework phát triển ứng dụng Java dựa trên Spring, giúp đơn giản hóa cấu hình và triển khai. SpringBoot cung cấp các auto-configuration để giảm thiểu cấu hình thủ công, tích hợp sẵn các server nhúng như Tomcat, Jetty.
MySQL Database: Hệ quản trị cơ sở dữ liệu quan hệ mã nguồn mở, hỗ trợ các tiêu chuẩn SQL, cung cấp độ tin cậy cao và hiệu suất tốt cho ứng dụng enterprise. MySQL hỗ trợ các engine lưu trữ khác nhau như InnoDB với tính năng ACID.
Spring Security & JWT: Spring Security cung cấp cơ chế bảo mật toàn diện, tích hợp với JWT (JSON Web Token) để thực hiện xác thực và phân quyền stateless, phù hợp cho các ứng dụng microservices và API.