Java全栈项目--校园快递代收管理系统项目实战

项目介绍

校园快递代收管理系统是一个面向高校的快递管理平台,旨在解决校园快递收发混乱、效率低下等问题。系统采用 Spring Boot + Vue.js 的前后端分离架构,实现了快递代收、分发、查询等核心功能。

技术栈

后端技术

  • Spring Boot 2.5.x
  • Spring Security
  • MyBatis Plus
  • MySQL 8.0
  • Redis
  • JWT

前端技术

  • Vue.js 2.x
  • Element UI
  • Axios
  • Vuex
  • Vue Router

核心功能

1. 用户管理模块

  • 学生注册登录
  • 管理员账号管理
  • 角色权限控制

2. 快递管理模块

  • 快递信息录入
  • 快递分发管理
  • 快递状态追踪
  • 取件码生成

3. 代收点管理

  • 代收点信息维护
  • 代收员管理
  • 工作量统计

4. 通知提醒

  • 到件通知
  • 逾期提醒
  • 系统公告

数据库设计

sql 复制代码
-- 用户表
CREATE TABLE `user` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `password` varchar(100) NOT NULL,
  `phone` varchar(20),
  `role` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
);

-- 快递信息表
CREATE TABLE `express` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `tracking_number` varchar(50) NOT NULL,
  `recipient_name` varchar(50) NOT NULL,
  `recipient_phone` varchar(20) NOT NULL,
  `pickup_code` varchar(10) NOT NULL,
  `status` int NOT NULL,
  `create_time` datetime NOT NULL,
  PRIMARY KEY (`id`)
);

核心代码展示

后端接口示例

java 复制代码
@RestController
@RequestMapping("/api/express")
public class ExpressController {
    
    @Autowired
    private ExpressService expressService;
    
    @PostMapping("/create")
    public Result createExpress(@RequestBody ExpressDTO expressDTO) {
        Express express = expressService.createExpress(expressDTO);
        return Result.success(express);
    }
    
    @GetMapping("/list")
    public Result getExpressList(ExpressQuery query) {
        Page<Express> page = expressService.getExpressList(query);
        return Result.success(page);
    }
}

前端代码示例

vue 复制代码
<template>
  <div class="express-list">
    <el-table :data="expressList" border>
      <el-table-column prop="trackingNumber" label="快递单号"/>
      <el-table-column prop="recipientName" label="收件人"/>
      <el-table-column prop="status" label="状态">
        <template slot-scope="scope">
          {{ getStatusText(scope.row.status) }}
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button type="primary" @click="handlePickup(scope.row)">
            确认取件
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

项目亮点

  1. 安全性设计

    • 采用 JWT + Redis 实现登录认证
    • 接口权限精细化控制
    • 敏感数据加密存储
  2. 性能优化

    • Redis 缓存热点数据
    • MyBatis Plus 分页查询优化
    • 前端组件按需加载
  3. 用户体验

    • 响应式布局设计
    • 取件码短信通知
    • 操作日志完整记录

项目总结

通过本项目的开发,不仅实现了校园快递管理的信息化和规范化,也积累了完整的项目开发经验。项目中运用了主流的技术栈,采用前后端分离架构,在性能优化和用户体验方面都做了细致的工作。

项目收获

  1. 掌握了完整的项目开发流程
  2. 深入理解前后端分离架构
  3. 提升了代码质量和安全意识
  4. 积累了实际项目经验

后续优化方向

  1. 引入消息队列处理异步任务
  2. 添加微信小程序端
  3. 优化系统监控和告警机制
  4. 引入容器化部署方案

结语

校园快递代收管理系统是一个实用性强、技术栈完整的项目。通过这个项目,不仅解决了实际问题,也提供了很好的学习参考。

校园快递管理系统核心模块详解

一、用户管理模块

1. 用户角色设计

java 复制代码
public enum UserRole {
    STUDENT("学生"),
    ADMIN("管理员"),
    COURIER("快递员"),
    PICKUP_STAFF("代收点工作人员");
    
    private String description;
    
    UserRole(String description) {
        this.description = description;
    }
}

2. 学生注册登录

2.1 注册流程
java 复制代码
@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired 
    private PasswordEncoder passwordEncoder;
    
    public void register(RegisterDTO dto) {
        // 1. 验证学号是否已注册
        if(userMapper.existsByStudentId(dto.getStudentId())) {
            throw new BusinessException("该学号已注册");
        }
        
        // 2. 验证手机号
        if(!PhoneUtil.isValid(dto.getPhone())) {
            throw new BusinessException("手机号格式不正确");
        }
        
        // 3. 密码加密
        String encodedPassword = passwordEncoder.encode(dto.getPassword());
        
        // 4. 保存用户信息
        User user = User.builder()
                .studentId(dto.getStudentId())
                .username(dto.getUsername())
                .password(encodedPassword)
                .phone(dto.getPhone())
                .role(UserRole.STUDENT)
                .build();
                
        userMapper.insert(user);
    }
}
2.2 登录认证
java 复制代码
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private UserService userService;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private RedisTemplate redisTemplate;

    public LoginVO login(LoginDTO dto) {
        // 1. 验证用户名密码
        User user = userService.validatePassword(dto);
        
        // 2. 生成token
        String token = jwtUtil.generateToken(user);
        
        // 3. 存入Redis
        redisTemplate.opsForValue().set(
            "TOKEN:" + user.getId(), 
            token,
            30,
            TimeUnit.DAYS
        );
        
        return LoginVO.builder()
                .token(token)
                .userInfo(UserConverter.toVO(user))
                .build();
    }
}

3. 管理员账号管理

java 复制代码
@RestController
@RequestMapping("/api/admin/user")
@PreAuthorize("hasRole('ADMIN')")
public class AdminUserController {

    @Autowired
    private UserService userService;

    // 创建账号
    @PostMapping("/create")
    public Result createUser(@RequestBody AdminUserDTO dto) {
        userService.createAdminUser(dto);
        return Result.success();
    }
    
    // 禁用账号
    @PostMapping("/disable/{userId}")
    public Result disableUser(@PathVariable Long userId) {
        userService.disableUser(userId);
        return Result.success();
    }
    
    // 重置密码
    @PostMapping("/reset-password/{userId}")
    public Result resetPassword(@PathVariable Long userId) {
        String newPassword = userService.resetPassword(userId);
        return Result.success(newPassword);
    }
}

4. 权限控制

java 复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            // 公开接口
            .antMatchers("/api/auth/**").permitAll()
            // 学生接口
            .antMatchers("/api/student/**").hasRole("STUDENT")
            // 快递员接口
            .antMatchers("/api/courier/**").hasRole("COURIER")
            // 管理员接口
            .antMatchers("/api/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .addFilter(new JwtAuthenticationFilter(authenticationManager()));
    }
}

二、快递管理模块

1. 快递信息录入

1.1 数据模型
java 复制代码
@Data
@TableName("express")
public class Express {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    private String trackingNumber; // 快递单号
    private String recipientName;  // 收件人姓名
    private String recipientPhone; // 收件人电话
    private String address;        // 收件地址
    private String pickupCode;     // 取件码
    private ExpressStatus status;  // 快递状态
    private ExpressType type;      // 快递类型
    private Double weight;         // 重量
    private String remark;         // 备注
    
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}
1.2 快递录入接口
java 复制代码
@RestController
@RequestMapping("/api/express")
public class ExpressController {

    @Autowired
    private ExpressService expressService;
    
    @PostMapping("/create")
    public Result createExpress(@RequestBody ExpressDTO dto) {
        // 1. 生成取件码
        String pickupCode = PickupCodeGenerator.generate();
        
        // 2. 保存快递信息
        Express express = Express.builder()
                .trackingNumber(dto.getTrackingNumber())
                .recipientName(dto.getRecipientName())
                .recipientPhone(dto.getRecipientPhone())
                .pickupCode(pickupCode)
                .status(ExpressStatus.RECEIVED)
                .build();
                
        expressService.save(express);
        
        // 3. 发送短信通知
        smsService.sendPickupNotification(express);
        
        return Result.success(express);
    }
}

2. 快递分发管理

java 复制代码
@Service
public class ExpressDistributionService {

    @Autowired
    private ExpressMapper expressMapper;
    
    @Autowired
    private PickupPointMapper pickupPointMapper;

    // 分配快递到代收点
    public void distributeExpress(Long expressId, Long pickupPointId) {
        // 1. 验证快递和代收点
        Express express = expressMapper.selectById(expressId);
        PickupPoint point = pickupPointMapper.selectById(pickupPointId);
        
        // 2. 更新快递状态和位置
        express.setStatus(ExpressStatus.DISTRIBUTED);
        express.setPickupPointId(pickupPointId);
        express.setDistributionTime(LocalDateTime.now());
        
        expressMapper.updateById(express);
        
        // 3. 记录分发日志
        saveDistributionLog(express, point);
    }
}

3. 快递状态追踪

java 复制代码
public enum ExpressStatus {
    RECEIVED("已接收"),
    DISTRIBUTED("已分发"),
    READY_FOR_PICKUP("待取件"),
    PICKED_UP("已取件"),
    EXPIRED("已过期"),
    RETURNED("已退回");
    
    private String description;
}

@Service
public class ExpressTrackingService {

    public List<ExpressTrackingVO> getTrackingInfo(String trackingNumber) {
        List<ExpressTracking> trackingList = trackingMapper.selectByTrackingNumber(trackingNumber);
        
        return trackingList.stream()
                .map(tracking -> ExpressTrackingVO.builder()
                        .status(tracking.getStatus())
                        .operation(tracking.getOperation())
                        .operator(tracking.getOperator())
                        .operateTime(tracking.getOperateTime())
                        .remark(tracking.getRemark())
                        .build())
                .collect(Collectors.toList());
    }
}

4. 取件码生成与验证

java 复制代码
@Component
public class PickupCodeGenerator {
    
    private static final int CODE_LENGTH = 6;
    
    // 生成取件码
    public static String generate() {
        // 生成6位随机数字
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for(int i = 0; i < CODE_LENGTH; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }
    
    // 验证取件码
    public boolean verifyPickupCode(String trackingNumber, String inputCode) {
        Express express = expressMapper.selectByTrackingNumber(trackingNumber);
        if(express == null) {
            throw new BusinessException("快递不存在");
        }
        
        if(!express.getPickupCode().equals(inputCode)) {
            throw new BusinessException("取件码错误");
        }
        
        if(express.getStatus() == ExpressStatus.PICKED_UP) {
            throw new BusinessException("该快递已被取走");
        }
        
        return true;
    }
}

以上是用户管理模块和快递管理模块的核心代码实现。每个功能点都包含了:

  1. 数据模型设计
  2. 业务逻辑实现
  3. 接口封装
  4. 安全控制
  5. 异常处理

这样的设计确保了系统的:

  • 功能完整性
  • 安全性
  • 可维护性
  • 可扩展性

校园快递管理系统功能模块详解(续)

三、代收点管理模块

1. 代收点信息维护

1.1 数据模型设计
java 复制代码
@Data
@TableName("pickup_point")
public class PickupPoint {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    private String name;        // 代收点名称
    private String location;    // 具体位置
    private String contact;     // 联系方式
    private Integer capacity;   // 最大容量
    private Integer currentLoad;// 当前存放数量
    private String openTime;    // 营业时间
    private Boolean isActive;   // 是否营业
    
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}
1.2 代收点管理接口
java 复制代码
@RestController
@RequestMapping("/api/admin/pickup-point")
@PreAuthorize("hasRole('ADMIN')")
public class PickupPointController {

    @Autowired
    private PickupPointService pickupPointService;

    // 新增代收点
    @PostMapping("/create")
    public Result createPickupPoint(@RequestBody PickupPointDTO dto) {
        PickupPoint point = pickupPointService.createPickupPoint(dto);
        return Result.success(point);
    }
    
    // 更新代收点信息
    @PutMapping("/update/{id}")
    public Result updatePickupPoint(@PathVariable Long id, @RequestBody PickupPointDTO dto) {
        pickupPointService.updatePickupPoint(id, dto);
        return Result.success();
    }
    
    // 获取代收点容量统计
    @GetMapping("/capacity-stats")
    public Result getCapacityStats() {
        List<PickupPointCapacityVO> stats = pickupPointService.getCapacityStats();
        return Result.success(stats);
    }
}

2. 代收员管理

2.1 代收员信息模型
java 复制代码
@Data
@TableName("pickup_staff")
public class PickupStaff {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    private String name;
    private String phone;
    private Long pickupPointId;  // 所属代收点
    private String workSchedule; // 工作时间安排
    private StaffStatus status;  // 在职状态
    private String idCard;       // 身份证号
    
    @TableField(exist = false)
    private PickupPoint pickupPoint;
}
2.2 代收员管理服务
java 复制代码
@Service
public class PickupStaffService {

    @Autowired
    private PickupStaffMapper staffMapper;
    
    // 分配工作时间
    public void assignWorkSchedule(Long staffId, List<WorkScheduleDTO> schedules) {
        PickupStaff staff = staffMapper.selectById(staffId);
        if(staff == null) {
            throw new BusinessException("员工不存在");
        }
        
        // 验证时间安排是否合理
        validateWorkSchedule(schedules);
        
        // 更新工作时间
        staff.setWorkSchedule(JSON.toJSONString(schedules));
        staffMapper.updateById(staff);
    }
    
    // 统计代收员工作情况
    public StaffWorkStatsVO getWorkStats(Long staffId, LocalDate startDate, LocalDate endDate) {
        return StaffWorkStatsVO.builder()
                .expressCount(getHandledExpressCount(staffId, startDate, endDate))
                .customerRating(getCustomerRating(staffId))
                .workHours(calculateWorkHours(staffId, startDate, endDate))
                .build();
    }
}

3. 工作量统计

java 复制代码
@Service
public class WorkloadStatisticsService {

    @Autowired
    private ExpressMapper expressMapper;
    
    @Autowired
    private PickupStaffMapper staffMapper;

    // 统计代收点工作量
    public PickupPointStatsVO getPickupPointStats(Long pointId, LocalDate date) {
        // 1. 统计快递处理量
        Integer expressCount = expressMapper.countByPointAndDate(pointId, date);
        
        // 2. 统计高峰期
        List<PeakHourVO> peakHours = calculatePeakHours(pointId, date);
        
        // 3. 统计员工效率
        List<StaffEfficiencyVO> staffEfficiency = calculateStaffEfficiency(pointId, date);
        
        return PickupPointStatsVO.builder()
                .expressCount(expressCount)
                .peakHours(peakHours)
                .staffEfficiency(staffEfficiency)
                .build();
    }
    
    // 生成工作量报表
    public WorkloadReportVO generateWorkloadReport(LocalDate startDate, LocalDate endDate) {
        // 1. 收集基础数据
        List<DailyStatsVO> dailyStats = getDailyStats(startDate, endDate);
        
        // 2. 计算关键指标
        WorkloadMetrics metrics = calculateMetrics(dailyStats);
        
        // 3. 生成图表数据
        List<ChartDataVO> chartData = generateChartData(dailyStats);
        
        return WorkloadReportVO.builder()
                .dailyStats(dailyStats)
                .metrics(metrics)
                .chartData(chartData)
                .build();
    }
}

四、通知提醒模块

1. 到件通知

1.1 通知服务实现
java 复制代码
@Service
public class NotificationService {

    @Autowired
    private SmsService smsService;
    
    @Autowired
    private WechatService wechatService;
    
    @Autowired
    private EmailService emailService;

    // 发送到件通知
    public void sendArrivalNotification(Express express) {
        // 1. 构建通知内容
        NotificationMessage message = NotificationMessage.builder()
                .recipientName(express.getRecipientName())
                .trackingNumber(express.getTrackingNumber())
                .pickupCode(express.getPickupCode())
                .pickupPoint(express.getPickupPoint().getName())
                .build();
        
        // 2. 多渠道发送通知
        CompletableFuture.allOf(
            CompletableFuture.runAsync(() -> smsService.sendNotification(message)),
            CompletableFuture.runAsync(() -> wechatService.sendNotification(message)),
            CompletableFuture.runAsync(() -> emailService.sendNotification(message))
        ).join();
        
        // 3. 记录通知日志
        saveNotificationLog(express.getId(), message);
    }
}

2. 逾期提醒

java 复制代码
@Service
@Slf4j
public class ExpressExpirationService {

    @Autowired
    private ExpressMapper expressMapper;
    
    @Autowired
    private NotificationService notificationService;

    // 定时检查逾期快递
    @Scheduled(cron = "0 0 8 * * ?") // 每天早上8点执行
    public void checkExpiredExpress() {
        log.info("开始检查逾期快递...");
        
        // 1. 获取即将逾期的快递(3天内未取)
        List<Express> expiringExpress = expressMapper.findExpiringExpress();
        
        // 2. 发送提醒通知
        for (Express express : expiringExpress) {
            notificationService.sendExpirationWarning(express);
        }
        
        // 3. 处理已逾期快递(7天未取)
        List<Express> expiredExpress = expressMapper.findExpiredExpress();
        handleExpiredExpress(expiredExpress);
        
        log.info("逾期快递检查完成");
    }
    
    // 处理逾期快递
    private void handleExpiredExpress(List<Express> expiredExpress) {
        for (Express express : expiredExpress) {
            // 1. 更新状态为已逾期
            express.setStatus(ExpressStatus.EXPIRED);
            expressMapper.updateById(express);
            
            // 2. 通知快递公司处理
            notificationService.notifyCourierCompany(express);
            
            // 3. 记录处理日志
            saveExpirationLog(express);
        }
    }
}

3. 系统公告

3.1 公告模型
java 复制代码
@Data
@TableName("system_announcement")
public class Announcement {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    private String title;
    private String content;
    private AnnouncementType type;
    private AnnouncementStatus status;
    private LocalDateTime publishTime;
    private LocalDateTime expireTime;
    private Integer priority;  // 优先级
    private Boolean isSticky; // 是否置顶
}
3.2 公告管理服务
java 复制代码
@Service
public class AnnouncementService {

    @Autowired
    private AnnouncementMapper announcementMapper;
    
    // 发布公告
    public void publishAnnouncement(AnnouncementDTO dto) {
        Announcement announcement = Announcement.builder()
                .title(dto.getTitle())
                .content(dto.getContent())
                .type(dto.getType())
                .status(AnnouncementStatus.PUBLISHED)
                .publishTime(LocalDateTime.now())
                .expireTime(dto.getExpireTime())
                .priority(dto.getPriority())
                .isSticky(dto.getIsSticky())
                .build();
                
        announcementMapper.insert(announcement);
        
        // 如果是重要公告,推送到用户
        if(dto.getPriority() > 5) {
            pushImportantAnnouncement(announcement);
        }
    }
    
    // 获取活动公告
    public List<AnnouncementVO> getActiveAnnouncements() {
        // 1. 获取未过期的公告
        List<Announcement> announcements = announcementMapper.findActiveAnnouncements();
        
        // 2. 按优先级和置顶状态排序
        return announcements.stream()
                .sorted(this::compareAnnouncements)
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }
    
    // 推送重要公告
    private void pushImportantAnnouncement(Announcement announcement) {
        // 1. 获取所有在线用户
        List<User> onlineUsers = userService.getOnlineUsers();
        
        // 2. 通过WebSocket推送
        WebSocketMessage message = WebSocketMessage.builder()
                .type(MessageType.ANNOUNCEMENT)
                .data(convertToVO(announcement))
                .build();
                
        webSocketService.broadcastMessage(message);
    }
}

4. 消息推送中心

java 复制代码
@Service
public class MessagePushCenter {

    @Autowired
    private WebSocketService webSocketService;
    
    @Autowired
    private NotificationService notificationService;

    // 统一消息推送
    public void pushMessage(PushMessage message) {
        // 1. 确定推送渠道
        List<PushChannel> channels = determinePushChannels(message);
        
        // 2. 执行推送
        for (PushChannel channel : channels) {
            switch (channel) {
                case WEBSOCKET:
                    webSocketService.pushToUser(message.getUserId(), message);
                    break;
                case SMS:
                    notificationService.sendSms(message);
                    break;
                case WECHAT:
                    notificationService.sendWechatMessage(message);
                    break;
                case EMAIL:
                    notificationService.sendEmail(message);
                    break;
            }
        }
        
        // 3. 记录推送日志
        savePushLog(message, channels);
    }
    
    // 消息模板管理
    private String getMessageContent(MessageTemplate template, Map<String, Object> params) {
        String content = template.getContent();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            content = content.replace("${" + entry.getKey() + "}", 
                                    String.valueOf(entry.getValue()));
        }
        return content;
    }
}

这些模块的实现特点:

  1. 代收点管理

    • 完整的CRUD功能
    • 实时容量监控
    • 灵活的工作排班
    • 详细的统计分析
  2. 通知提醒

    • 多渠道推送
    • 异步处理
    • 定时任务
    • 消息模板
    • 实时推送

关键技术点:

  1. 使用Spring Task处理定时任务
  2. 使用WebSocket实现实时推送
  3. 使用CompletableFuture处理异步通知
  4. 使用消息模板实现灵活配置
  5. 统计分析使用多维度数据聚合
相关推荐
心随雨下5 分钟前
Tomcat日志配置与优化指南
java·服务器·tomcat
Kapaseker11 分钟前
Java 25 中值得关注的新特性
java
wljt15 分钟前
Linux 常用命令速查手册(Java开发版)
java·linux·python
撩得Android一次心动18 分钟前
Android 四大组件——BroadcastReceiver(广播)
android·java·android 四大组件
canonical_entropy21 分钟前
Nop平台到底有什么独特之处,它能用在什么场景?
java·后端·领域驱动设计
chilavert31824 分钟前
技术演进中的开发沉思-174 java-EJB:分布式通信
java·分布式
不是株1 小时前
JavaWeb(后端进阶)
java·开发语言·后端
编程火箭车1 小时前
【Java SE 基础学习打卡】02 计算机硬件与软件
java·电脑选购·计算机基础·编程入门·计算机硬件·软件系统·编程学习路线
Felix_XXXXL2 小时前
IDEA + Spring Boot 的三种热加载方案
java·后端