当前位置: 首页 > news >正文

基于“SpringBoot+uniapp的考研书库微信小程序设计与实现7000字论文

摘要
本文设计并实现了一个基于 SpringBoot 后端和 uniapp 前端的考研书库微信小程序,旨在为考研学生提供便捷的电子资料查询、在线学习和社交交流平台。系统采用前后端分离架构,通过 RESTful API 实现数据交互,支持用户注册登录、资料分类检索、笔记共享、学习计划管理等功能。论文详细阐述了系统需求分析、架构设计、数据库设计、功能模块实现及测试评估过程,最终验证了系统的可行性和实用性。

关键词
SpringBoot;uniapp;微信小程序;考研书库;在线学习平台

1 引言

1.1 研究背景与意义

随着考研人数的逐年增长,考生对优质学习资源的需求日益迫切。传统的考研资料获取方式存在信息分散、更新不及时、检索困难等问题,无法满足考生高效备考的需求。开发一个集资料整合、学习管理和社交交流于一体的考研书库平台,具有重要的现实意义:

  • 整合优质考研资源,解决信息碎片化问题
  • 提供个性化学习支持,提高备考效率
  • 构建学习社区,促进考生间的交流与互助
  • 降低学习成本,实现资源共享与优化配置
1.2 国内外研究现状

国内外针对在线学习平台的研究已经取得了一定进展:

  • 国外:Coursera、edX 等平台提供了丰富的课程资源,但针对考研的专业化平台较少
  • 国内:考研帮、新东方在线等平台主要以课程服务为主,资料共享功能相对薄弱
  • 技术层面:SpringBoot 框架在后端开发中广泛应用,uniapp 在跨平台小程序开发中展现出显著优势

然而,现有的考研学习平台在资料整合深度、个性化服务和社交互动方面仍存在不足。

1.3 研究内容与目标

本文研究内容包括:

  1. 考研书库微信小程序的需求分析与功能设计
  2. 基于 SpringBoot 的后端架构设计与实现
  3. 基于 uniapp 的前端界面开发与交互实现
  4. 数据库设计与优化
  5. 系统测试与性能评估

研究目标是开发一个功能完善、性能稳定、界面友好的考研书库微信小程序,满足考研学生的学习需求。

2 相关技术与理论基础

2.1 SpringBoot 框架

SpringBoot 是基于 Spring 的快速应用开发框架,具有以下特点:

  • 自动配置,减少 XML 配置文件
  • 内嵌 Tomcat 等服务器,简化部署
  • 提供 Actuator 组件,便于监控系统运行状态
  • 支持各种数据库和缓存技术
2.2 uniapp 框架

uniapp 是一个使用 Vue.js 开发所有前端应用的框架,具有以下优势:

  • 一套代码可同时发布到微信小程序、H5、APP 等多个平台
  • 兼容微信小程序原生组件和 API
  • 性能接近原生应用
  • 丰富的 UI 组件库和插件市场
2.3 微信小程序开发

微信小程序是一种轻量级应用,具有以下特点:

  • 无需下载安装,触手可及
  • 基于微信生态,用户基数大
  • 提供丰富的 API 接口,如支付、分享、位置等
  • 开发成本低,维护方便
2.4 数据库技术

本系统采用 MySQL 作为关系型数据库,Redis 作为缓存数据库:

  • MySQL:支持事务处理,适合存储结构化数据
  • Redis:高性能内存数据库,适合缓存热点数据,提高系统响应速度

3 系统需求分析

3.1 功能需求
3.1.1 用户管理模块
  • 用户注册与登录
  • 个人信息管理
  • 学习偏好设置
  • 账号安全管理
3.1.2 资料管理模块
  • 资料分类与标签
  • 资料上传与审核
  • 资料检索与预览
  • 资料下载与收藏
3.1.3 学习管理模块
  • 学习计划制定与跟踪
  • 学习进度记录
  • 学习笔记管理
  • 学习数据分析
3.1.4 社交互动模块
  • 评论与回复
  • 点赞与分享
  • 关注与粉丝管理
  • 私信交流
3.1.5 系统管理模块
  • 管理员账号管理
  • 资料审核管理
  • 用户权限管理
  • 系统日志管理
3.2 非功能需求
3.2.1 性能需求
  • 系统响应时间不超过 3 秒
  • 支持至少 1000 个并发用户
  • 资料下载速度不低于 1MB/s
3.2.2 安全需求
  • 用户信息加密存储
  • 资料访问权限控制
  • 防止 SQL 注入和 XSS 攻击
  • 数据定期备份
3.2.3 可用性需求
  • 系统 7×24 小时可用
  • 故障恢复时间不超过 1 小时
  • 操作界面简洁直观,易于使用
3.2.4 兼容性需求
  • 兼容主流微信版本
  • 适配不同屏幕尺寸的移动设备

4 系统设计

4.1 总体架构设计

系统采用前后端分离的三层架构:

plaintext

┌─────────────────────────────────────────────┐
│                  表示层                     │
│       (uniapp前端、微信小程序界面)           │
└─────────────────────┬───────────────────────┘│ RESTful API
┌─────────────────────┼───────────────────────┐
│                  业务逻辑层                   │
│ (SpringBoot、Service、Repository、Controller) │
└─────────────────────┬───────────────────────┘│ JDBC/MyBatis
┌─────────────────────┼───────────────────────┐
│                  数据访问层                   │
│             (MySQL数据库、Redis缓存)           │
└─────────────────────────────────────────────┘
4.2 数据库设计
4.2.1 数据库表结构

用户表 (users)

sql

CREATE TABLE `users` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',`username` varchar(50) NOT NULL COMMENT '用户名',`password` varchar(100) NOT NULL COMMENT '密码(加密存储)',`nickname` varchar(50) DEFAULT NULL COMMENT '昵称',`avatar` varchar(255) DEFAULT NULL COMMENT '头像URL',`email` varchar(100) DEFAULT NULL COMMENT '邮箱',`phone` varchar(20) DEFAULT NULL COMMENT '手机号',`gender` tinyint(1) DEFAULT NULL COMMENT '性别(0:未知,1:男,2:女)',`school` varchar(100) DEFAULT NULL COMMENT '学校',`major` varchar(100) DEFAULT NULL COMMENT '专业',`target_school` varchar(100) DEFAULT NULL COMMENT '目标院校',`target_major` varchar(100) DEFAULT NULL COMMENT '目标专业',`role` varchar(20) NOT NULL DEFAULT 'user' COMMENT '角色(user/admin)',`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL COMMENT '更新时间',PRIMARY KEY (`id`),UNIQUE KEY `idx_username` (`username`),UNIQUE KEY `idx_email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

资料表 (resources)

sql

CREATE TABLE `resources` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '资料ID',`title` varchar(100) NOT NULL COMMENT '资料标题',`description` text COMMENT '资料描述',`category_id` bigint(20) NOT NULL COMMENT '分类ID',`uploader_id` bigint(20) NOT NULL COMMENT '上传者ID',`file_path` varchar(255) NOT NULL COMMENT '文件路径',`file_size` bigint(20) NOT NULL COMMENT '文件大小(字节)',`file_type` varchar(20) NOT NULL COMMENT '文件类型(pdf/doc/xls等)',`download_count` int(11) NOT NULL DEFAULT '0' COMMENT '下载次数',`view_count` int(11) NOT NULL DEFAULT '0' COMMENT '浏览次数',`score` decimal(3,1) DEFAULT '0.0' COMMENT '评分',`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态(0:待审核,1:已通过,2:已拒绝)',`is_free` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否免费(0:付费,1:免费)',`price` decimal(10,2) DEFAULT '0.00' COMMENT '价格',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL COMMENT '更新时间',PRIMARY KEY (`id`),KEY `idx_category_id` (`category_id`),KEY `idx_uploader_id` (`uploader_id`),KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资料表';

资料分类表 (resource_categories)

sql

CREATE TABLE `resource_categories` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类ID',`name` varchar(50) NOT NULL COMMENT '分类名称',`parent_id` bigint(20) DEFAULT NULL COMMENT '父分类ID',`level` int(11) NOT NULL DEFAULT '1' COMMENT '分类级别',`sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序',`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL COMMENT '更新时间',PRIMARY KEY (`id`),KEY `idx_parent_id` (`parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资料分类表';

资料标签表 (resource_tags)

sql

CREATE TABLE `resource_tags` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '标签ID',`name` varchar(50) NOT NULL COMMENT '标签名称',`count` int(11) NOT NULL DEFAULT '0' COMMENT '使用次数',`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL COMMENT '更新时间',PRIMARY KEY (`id`),UNIQUE KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资料标签表';

资料 - 标签关联表 (resource_tag_relations)

sql

CREATE TABLE `resource_tag_relations` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '关联ID',`resource_id` bigint(20) NOT NULL COMMENT '资料ID',`tag_id` bigint(20) NOT NULL COMMENT '标签ID',`create_time` datetime NOT NULL COMMENT '创建时间',PRIMARY KEY (`id`),UNIQUE KEY `idx_resource_tag` (`resource_id`,`tag_id`),KEY `idx_tag_id` (`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资料-标签关联表';

资料评论表 (resource_comments)

sql

CREATE TABLE `resource_comments` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '评论ID',`resource_id` bigint(20) NOT NULL COMMENT '资料ID',`user_id` bigint(20) NOT NULL COMMENT '评论用户ID',`parent_id` bigint(20) DEFAULT NULL COMMENT '父评论ID',`content` text NOT NULL COMMENT '评论内容',`like_count` int(11) NOT NULL DEFAULT '0' COMMENT '点赞数',`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL COMMENT '更新时间',PRIMARY KEY (`id`),KEY `idx_resource_id` (`resource_id`),KEY `idx_user_id` (`user_id`),KEY `idx_parent_id` (`parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资料评论表';

学习计划表 (study_plans)

sql

CREATE TABLE `study_plans` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '计划ID',`user_id` bigint(20) NOT NULL COMMENT '用户ID',`title` varchar(100) NOT NULL COMMENT '计划标题',`description` text COMMENT '计划描述',`start_date` date NOT NULL COMMENT '开始日期',`end_date` date NOT NULL COMMENT '结束日期',`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态(0:进行中,1:已完成,2:已取消)',`progress` int(11) NOT NULL DEFAULT '0' COMMENT '进度(0-100)',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL COMMENT '更新时间',PRIMARY KEY (`id`),KEY `idx_user_id` (`user_id`),KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学习计划表';

学习计划项表 (study_plan_items)

sql

CREATE TABLE `study_plan_items` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '计划项ID',`plan_id` bigint(20) NOT NULL COMMENT '计划ID',`title` varchar(100) NOT NULL COMMENT '计划项标题',`description` text COMMENT '计划项描述',`plan_date` date NOT NULL COMMENT '计划日期',`start_time` time DEFAULT NULL COMMENT '开始时间',`end_time` time DEFAULT NULL COMMENT '结束时间',`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态(0:未完成,1:已完成)',`priority` tinyint(1) NOT NULL DEFAULT '2' COMMENT '优先级(1:高,2:中,3:低)',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL COMMENT '更新时间',PRIMARY KEY (`id`),KEY `idx_plan_id` (`plan_id`),KEY `idx_plan_date` (`plan_date`),KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学习计划项表';

学习笔记表 (study_notes)

sql

CREATE TABLE `study_notes` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '笔记ID',`user_id` bigint(20) NOT NULL COMMENT '用户ID',`title` varchar(100) NOT NULL COMMENT '笔记标题',`content` text NOT NULL COMMENT '笔记内容',`resource_id` bigint(20) DEFAULT NULL COMMENT '关联资料ID',`category_id` bigint(20) DEFAULT NULL COMMENT '分类ID',`is_public` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否公开(0:私密,1:公开)',`like_count` int(11) NOT NULL DEFAULT '0' COMMENT '点赞数',`view_count` int(11) NOT NULL DEFAULT '0' COMMENT '浏览数',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL COMMENT '更新时间',PRIMARY KEY (`id`),KEY `idx_user_id` (`user_id`),KEY `idx_resource_id` (`resource_id`),KEY `idx_category_id` (`category_id`),KEY `idx_is_public` (`is_public`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学习笔记表';

用户关注表 (user_follows)

sql

CREATE TABLE `user_follows` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '关注ID',`follower_id` bigint(20) NOT NULL COMMENT '关注者ID',`followed_id` bigint(20) NOT NULL COMMENT '被关注者ID',`create_time` datetime NOT NULL COMMENT '创建时间',PRIMARY KEY (`id`),UNIQUE KEY `idx_follower_followed` (`follower_id`,`followed_id`),KEY `idx_followed_id` (`followed_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户关注表';
4.3 系统架构图

 

4.4 部署架构图

 

4.5 用例图

 

4.6 界面原型
4.6.1 首页

首页展示热门资料、推荐分类、学习日历等信息,提供搜索和导航功能。

4.6.2 资料列表页

按分类或标签展示资料列表,支持筛选和排序功能。

4.6.3 资料详情页

展示资料详细信息,包括标题、描述、下载次数、评分等,提供下载和评论功能。

4.6.4 学习计划页

展示用户的学习计划和进度,支持创建、编辑和删除计划。

4.6.5 学习笔记页

展示用户的学习笔记,支持创建、编辑和分享笔记。

4.6.6 个人中心页

展示用户个人信息、收藏、关注等内容,提供账号管理功能。

5 系统实现

5.1 后端实现
5.1.1 项目结构

plaintext

kaoyan-bookstore/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── kaoyan/
│   │   │           ├── KaoyanApplication.java
│   │   │           ├── config/          # 配置类
│   │   │           ├── controller/      # 控制器
│   │   │           ├── service/         # 服务层
│   │   │           ├── repository/      # 数据访问层
│   │   │           ├── model/           # 实体类
│   │   │           ├── dto/             # 数据传输对象
│   │   │           ├── exception/       # 异常处理
│   │   │           ├── util/            # 工具类
│   │   │           └── security/        # 安全配置
│   │   └── resources/
│   │       ├── application.yml          # 配置文件
│   │       ├── mapper/                  # MyBatis映射文件
│   │       ├── static/                  # 静态资源
│   │       └── templates/               # 模板文件
│   └── test/                            # 测试代码
└── pom.xml                              # Maven配置文件
5.1.2 核心代码实现

用户认证与授权

java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate UserDetailsService userDetailsService;@Autowiredprivate JwtAuthenticationEntryPoint unauthorizedHandler;@Beanpublic JwtAuthenticationFilter jwtAuthenticationFilter() {return new JwtAuthenticationFilter();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.cors().and().csrf().disable().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests().antMatchers("/api/auth/**", "/api/resources/public/**").permitAll().antMatchers("/api/admin/**").hasRole("ADMIN").anyRequest().authenticated();http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);}
}

资料服务实现

java

@Service
@Transactional
public class ResourceServiceImpl implements ResourceService {@Autowiredprivate ResourceRepository resourceRepository;@Autowiredprivate ResourceCategoryRepository categoryRepository;@Autowiredprivate FileStorageService fileStorageService;@Overridepublic ResourceDTO uploadResource(MultipartFile file, ResourceCreateDTO resourceDTO, Long userId) {// 验证分类是否存在ResourceCategory category = categoryRepository.findById(resourceDTO.getCategoryId()).orElseThrow(() -> new ResourceNotFoundException("分类不存在"));// 保存文件String fileName = fileStorageService.storeFile(file);String fileDownloadUri = "/api/resources/download/" + fileName;// 创建资源Resource resource = new Resource();resource.setTitle(resourceDTO.getTitle());resource.setDescription(resourceDTO.getDescription());resource.setCategory(category);resource.setUploaderId(userId);resource.setFilePath(fileName);resource.setFileSize(file.getSize());resource.setFileType(file.getContentType());resource.setStatus(ResourceStatus.PENDING);resource.setIsFree(resourceDTO.getIsFree());resource.setPrice(resourceDTO.getPrice());// 保存资源Resource savedResource = resourceRepository.save(resource);// 处理标签if (resourceDTO.getTagIds() != null && !resourceDTO.getTagIds().isEmpty()) {// 标签关联逻辑}return convertToDTO(savedResource);}@Overridepublic Page<ResourceDTO> getAllResources(Pageable pageable) {Page<Resource> resources = resourceRepository.findAllByStatus(ResourceStatus.APPROVED, pageable);return resources.map(this::convertToDTO);}@Overridepublic ResourceDTO getResourceById(Long id) {Resource resource = resourceRepository.findByIdAndStatus(id, ResourceStatus.APPROVED).orElseThrow(() -> new ResourceNotFoundException("资源不存在"));// 更新浏览次数resource.setViewCount(resource.getViewCount() + 1);resourceRepository.save(resource);return convertToDTO(resource);}@Overridepublic ResourceDTO updateResource(Long id, ResourceUpdateDTO resourceDTO, Long userId) {Resource resource = resourceRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("资源不存在"));// 验证权限if (!resource.getUploaderId().equals(userId)) {throw new AccessDeniedException("无权修改此资源");}// 更新资源信息resource.setTitle(resourceDTO.getTitle());resource.setDescription(resourceDTO.getDescription());resource.setStatus(resourceDTO.getStatus());resource.setIsFree(resourceDTO.getIsFree());resource.setPrice(resourceDTO.getPrice());// 处理分类更新if (resourceDTO.getCategoryId() != null) {ResourceCategory category = categoryRepository.findById(resourceDTO.getCategoryId()).orElseThrow(() -> new ResourceNotFoundException("分类不存在"));resource.setCategory(category);}// 保存更新Resource updatedResource = resourceRepository.save(resource);// 处理标签更新if (resourceDTO.getTagIds() != null) {// 标签更新逻辑}return convertToDTO(updatedResource);}@Overridepublic void deleteResource(Long id, Long userId) {Resource resource = resourceRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("资源不存在"));// 验证权限if (!resource.getUploaderId().equals(userId)) {throw new AccessDeniedException("无权删除此资源");}// 删除文件fileStorageService.deleteFile(resource.getFilePath());// 删除资源resourceRepository.delete(resource);}private ResourceDTO convertToDTO(Resource resource) {ResourceDTO dto = new ResourceDTO();BeanUtils.copyProperties(resource, dto);dto.setCategoryId(resource.getCategory().getId());dto.setCategoryName(resource.getCategory().getName());// 设置标签List<ResourceTag> tags = resource.getTags();if (tags != null && !tags.isEmpty()) {dto.setTagNames(tags.stream().map(ResourceTag::getName).collect(Collectors.toList()));}return dto;}
}

学习计划服务实现

java

@Service
@Transactional
public class StudyPlanServiceImpl implements StudyPlanService {@Autowiredprivate StudyPlanRepository planRepository;@Autowiredprivate StudyPlanItemRepository itemRepository;@Overridepublic StudyPlanDTO createPlan(StudyPlanCreateDTO planDTO, Long userId) {// 创建学习计划StudyPlan plan = new StudyPlan();plan.setTitle(planDTO.getTitle());plan.setDescription(planDTO.getDescription());plan.setStartDate(planDTO.getStartDate());plan.setEndDate(planDTO.getEndDate());plan.setUserId(userId);plan.setStatus(PlanStatus.IN_PROGRESS);plan.setProgress(0);// 保存计划StudyPlan savedPlan = planRepository.save(plan);// 处理计划项if (planDTO.getItems() != null && !planDTO.getItems().isEmpty()) {List<StudyPlanItem> items = planDTO.getItems().stream().map(itemDTO -> {StudyPlanItem item = new StudyPlanItem();item.setPlan(savedPlan);item.setTitle(itemDTO.getTitle());item.setDescription(itemDTO.getDescription());item.setPlanDate(itemDTO.getPlanDate());item.setStartTime(itemDTO.getStartTime());item.setEndTime(itemDTO.getEndTime());item.setStatus(ItemStatus.UNFINISHED);item.setPriority(itemDTO.getPriority());return item;}).collect(Collectors.toList());itemRepository.saveAll(items);}return convertToDTO(savedPlan);}@Overridepublic Page<StudyPlanDTO> getPlansByUser(Long userId, Pageable pageable) {Page<StudyPlan> plans = planRepository.findByUserId(userId, pageable);return plans.map(this::convertToDTO);}@Overridepublic StudyPlanDTO getPlanById(Long id, Long userId) {StudyPlan plan = planRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("计划不存在"));// 验证权限if (!plan.getUserId().equals(userId)) {throw new AccessDeniedException("无权查看此计划");}return convertToDTO(plan);}@Overridepublic StudyPlanDTO updatePlan(Long id, StudyPlanUpdateDTO planDTO, Long userId) {StudyPlan plan = planRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("计划不存在"));// 验证权限if (!plan.getUserId().equals(userId)) {throw new AccessDeniedException("无权修改此计划");}// 更新计划信息plan.setTitle(planDTO.getTitle());plan.setDescription(planDTO.getDescription());plan.setStartDate(planDTO.getStartDate());plan.setEndDate(planDTO.getEndDate());plan.setStatus(planDTO.getStatus());// 保存更新StudyPlan updatedPlan = planRepository.save(plan);// 更新进度updatePlanProgress(updatedPlan.getId());return convertToDTO(updatedPlan);}@Overridepublic void deletePlan(Long id, Long userId) {StudyPlan plan = planRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("计划不存在"));// 验证权限if (!plan.getUserId().equals(userId)) {throw new AccessDeniedException("无权删除此计划");}// 删除计划项itemRepository.deleteByPlanId(id);// 删除计划planRepository.delete(plan);}@Overridepublic StudyPlanItemDTO createPlanItem(StudyPlanItemCreateDTO itemDTO, Long planId, Long userId) {StudyPlan plan = planRepository.findById(planId).orElseThrow(() -> new ResourceNotFoundException("计划不存在"));// 验证权限if (!plan.getUserId().equals(userId)) {throw new AccessDeniedException("无权添加计划项");}// 创建计划项StudyPlanItem item = new StudyPlanItem();item.setPlan(plan);item.setTitle(itemDTO.getTitle());item.setDescription(itemDTO.getDescription());item.setPlanDate(itemDTO.getPlanDate());item.setStartTime(itemDTO.getStartTime());item.setEndTime(itemDTO.getEndTime());item.setStatus(ItemStatus.UNFINISHED);item.setPriority(itemDTO.getPriority());// 保存计划项StudyPlanItem savedItem = itemRepository.save(item);// 更新计划进度updatePlanProgress(planId);return convertToDTO(savedItem);}private void updatePlanProgress(Long planId) {StudyPlan plan = planRepository.findById(planId).orElseThrow(() -> new ResourceNotFoundException("计划不存在"));List<StudyPlanItem> items = itemRepository.findByPlanId(planId);if (items.isEmpty()) {plan.setProgress(0);} else {long finishedCount = items.stream().filter(item -> item.getStatus() == ItemStatus.FINISHED).count();int progress = (int) (finishedCount * 100 / items.size());plan.setProgress(progress);}// 如果所有项都完成,将计划状态设为已完成if (plan.getProgress() == 100 && plan.getStatus() == PlanStatus.IN_PROGRESS) {plan.setStatus(PlanStatus.COMPLETED);}planRepository.save(plan);}private StudyPlanDTO convertToDTO(StudyPlan plan) {StudyPlanDTO dto = new StudyPlanDTO();BeanUtils.copyProperties(plan, dto);// 获取计划项List<StudyPlanItem> items = itemRepository.findByPlanId(plan.getId());if (items != null && !items.isEmpty()) {dto.setItems(items.stream().map(this::convertItemToDTO).collect(Collectors.toList()));}return dto;}private StudyPlanItemDTO convertItemToDTO(StudyPlanItem item) {StudyPlanItemDTO dto = new StudyPlanItemDTO();BeanUtils.copyProperties(item, dto);dto.setPlanId(item.getPlan().getId());return dto;}
}

5.2 前端实现

前端使用 uniapp 框架,采用组件化开发方式,主要实现以下功能:

5.2.1 登录注册页面
  • 微信一键登录
  • 手机号 + 验证码登录
  • 密码登录
  • 注册功能

5.2.2 资料列表与详情页面
  • 分类导航
  • 资料列表展示
  • 搜索功能
  • 资料详情展示
  • 下载功能
  • 评论功能

5.2.3 学习计划页面
  • 计划列表
  • 计划详情
  • 计划项管理
  • 进度统计
  • 日历视图

5.2.4 学习笔记页面
  • 笔记列表
  • 笔记详情
  • 新建笔记
  • 编辑笔记
  • 分享笔记

5.2.5 个人中心页面
  • 个人信息展示
  • 资料收藏
  • 关注用户
  • 学习统计
  • 设置功能

以下是 uniapp 前端的部分核心代码:

登录页面实现

javascript

<template><view class="login-container"><view class="logo">

    博主介绍:硕士研究生,专注于信息化技术领域开发与管理,会使用java、标准c/c++等开发语言,以及毕业项目实战✌

       从事基于java BS架构、CS架构、c/c++ 编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架构思想、较扎实的技术功底和资深的项目管理经验。

       先后担任过技术总监、部门经理、项目经理、开发组长、java高级工程师及c++工程师等职位,在工业互联网、国家标识解析体系、物联网、分布式集群架构、大数据通道处理、接口开发、远程教育、办公OA、财务软件(工资、记账、决策、分析、报表统计等方面)、企业内部管理软件(ERP、CRM等)、arggis地图等信息化建设领域有较丰富的实战工作经验;拥有BS分布式架构集群、数据库负载集群架构、大数据存储集群架构,以及高并发分布式集群架构的设计、开发和部署实战经验;拥有大并发访问、大数据存储、即时消息等瓶颈解决方案和实战经验。

       拥有产品研发和发明专利申请相关工作经验,完成发明专利构思、设计、编写、申请等工作,并获得发明专利1枚。

-----------------------------------------------------------------------------------

      大家在毕设选题、项目升级、论文写作,就业毕业等相关问题都可以给我留言咨询,非常乐意帮助更多的人或加w 908925859。

相关博客地址:

csdn专业技术博客:https://blog.csdn.net/mr_lili_1986?type=blog

Iteye博客:        https://www.iteye.com/blog/user/mr-lili-1986-163-com

门户:http://www.petsqi.cn

  

七、其他案例: 

 

  

 

相关文章:

  • Monorepo + PNPM 搭建高效多项目管理
  • 云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
  • 深入浅出掌握 Axios(持续更新)
  • 深入解析 Nacos MCP Router:云原生时代的 MCP 服务调度中枢
  • 云原生核心技术 (4/12): Docker 进阶:镜像优化实战与 Docker Compose 揭秘
  • uniapp+vue2+h5图片下载保存,微信浏览器、非微信浏览器
  • spark数据处理练习题番外篇【上】
  • Spring Boot集成Mina的Socket资源管理:从稳定通信到高性能优化
  • Windows上SSH连接Ubuntu失败
  • XWPFTemplate生成word
  • 置信水平、置信区间
  • 一体系数据平台的进化:基于阿里云 EMR Serverless Spark的持续演进
  • ESP32读取DHT11温湿度数据
  • 带eachers的html转word
  • 笔记 操作系统复习
  • 小程序的工具库-miniprogram-licia
  • AWS S3 SDK FOR JAVA 基本使用及如何兼容七牛云
  • 云计算——弹性云服务器(ECS)和裸金属服务器(BMS)
  • 小程序中的状态管理库-mobx-miniprogram
  • CentOS下的运维监控Grafana部署
  • 网站建设创意公司/广州网站建设技术外包
  • 哈尔滨悦创网络科技网站开发/最有效的推广方式
  • 12个优秀的平面设计素材网站/广州网站建设方案优化
  • 云服务器发布网站/网页搜索关键字
  • 去哪找网站建设公司好/安徽seo顾问服务
  • 京东联盟网站怎么做/如何让自己的网站快速被百度收录