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 分钟前
搭建一个基于Spring Boot的数码分享网站
java·spring boot·后端
m0_7482561410 分钟前
基于Leaflet和SpringBoot的全球国家综合检索WebGIS可视化
java·spring boot·后端
小馋喵知识杂货铺26 分钟前
Nginx调优
java·服务器·前端·nginx
赔罪30 分钟前
Java 数组排序
java·算法·java-ee·排序算法·数组排序
ldj20201 小时前
SpringBoot项目打war包要点
java·spring boot·spring
sin22011 小时前
springboot之YAML语法
java·spring boot·后端
luyun0202021 小时前
PDF工具箱 PDF24 ,免费下载,非常好用
java·python·pdf
结衣结衣.1 小时前
LeetCode热题100(滑动窗口篇)
java·c++·python·算法·leetcode·职场和发展
孑么2 小时前
力扣 完全平方数
java·算法·leetcode·职场和发展·动态规划
2401_897908312 小时前
2019-Android-高级面试题总结-从java语言到AIDL使用与原理
android·java·开发语言