我们做毕业设计,最尴尬的不是不会写代码,而是拿到一个完整项目后,根本不知道从哪儿下手去讲它。尤其是SpringBoot、Vue、MySQL这类全栈项目,源码摆在眼前,但一问到“为什么要这么设计表”“借书流程的状态是怎么流转的”,大概率会卡壳。这篇就拿“共享书角”图书借还管理系统当例子,从选题逻辑、数据库设计、后端接口、前端页面一直聊到部署和答辩准备,把这个项目掰开揉碎给你看。
这套系统面向的是计算机相关专业的学生和刚入门全栈开发的人。它会解决一个很典型的毕业设计问题:如何把真实的业务场景——共享借阅,转换成一套可运行、可演示、可答辩的系统。你不需要有生产级项目的经验,但至少要知道每一行关键代码背后在想什么,这样才能在老师和评审面前站得住脚。
1. “共享书角”干净在哪儿——这个选题为什么值得做
先从根上讲讲选题。每年毕业设计题目几百个,图书管理系统几乎是“常青树”。但“共享书角”和传统图书管一管的区别,就在“共享”这两个字上。
传统的图书管理,本质上是单向的:管理员录入图书、用户借书还书、逾期罚款。整个系统的信息流是“图书馆 -> 读者”。但共享书角的逻辑变了,它更像一个社区内部的图书流转平台。每一个用户既可以是借阅者,也可以是贡献者。我今天把闲置的书放上去,明天我也能从别人共享的书里借一本。这样一来,系统里就多了几个传统图书管理没有的东西:
- 用户自主上架图书
- 借阅关系发生在普通用户之间,管理员只做监督和仲裁
- 借阅流程中多了一个“共享者确认”的环节
- 需要有信用约束,防止书被借走不还
这看起来只是需求分析多写几行字,但对系统设计的影响是本质性的。比如在传统图书管理里,权限模型很清晰,普通用户只有借书还书权限。在共享书角里,同一个普通用户既要能借书,又要能上架书,还要能查看别人对自己书的借阅申请,这就必须在角色和状态设计上多花功夫。
再从答辩角度说,共享书角这类选题有一个天然优势,就是“业务有细节、设计有话说”。评委看到图书管理系统就听烦了,但你讲“用户共享上架 -> 借阅申请 -> 共享者确认 -> 管理员备案”这条链路时,至少听起来比单纯的增删改查高级一个台阶。而且这个模型后续可以自由扩展积分体系、信用体系、社区公告,论文里“系统扩展性”那一章不会没东西写。
这个项目实际做下来,功能边界也比较舒服。它比单表CRUD复杂,但还没复杂到SpringBoot+Vue的技术栈驾驭不住。一个典型的功能划分大概是:
- 用户端:注册登录、浏览图书、搜索筛选、发起借阅、归还、上架共享、个人借阅记录、公告查看
- 管理端:图书审核、借阅审核与登记、归还确认、逾期处理、用户管理、数据统计
注意这里我想提个醒,共享书角的核心在于“共享”,所以审核维度一定要做出来。网上很多源码把“共享”做成噱头,实际上还是管理员单方面录入图书,这种项目答辩很危险,因为题目是共享书角,系统却没有任何用户自己上架的流程,评委一问就会露馅。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 功能模块与数据库表结构:先把数据底座打好
拿到一个SpringBoot+Vue项目,第一件事应该看数据库脚本,而不是先跑代码。因为数据库表结构是一个系统的骨架,表设计合理了,后面的Service层、接口层才有依托。共享书角这个项目,最核心的表基本跑不出下面这几张,我按重要性排个序。
2.1 用户表:不要只存账号密码
用户表是权限控制的基础。一般会有:id、username、password、nickname、phone、credit_score、role、status、create_time。
这里有两个容易忽略的点。第一,password字段要存加密后的密文而不是明文。项目里通常用Spring Security的BCryptPasswordEncoder,或者简单的MD5加盐。答辩时如果被问到“密码怎么存的”,这是必考点,说“明文存的”基本就凉了。
第二,role字段建议用tinyint而不是String。0表示普通用户,1表示管理员。别小看这个设计,后端的拦截器判断角色时,一个数字判断比字符串判断干净得多。
credit_score信用分是“共享书角”这类系统的特色字段。每次借阅超期、书损坏都可以扣分,这是共享场景下维持秩序的有效手段。不建议在用户表里直接写死分数,但表结构阶段先留一个字段是完全合理的。
2.2 图书表:区分“系统录入”和“用户共享”
图书表是整个业务的核心。我和很多人聊过,最容易出问题的地方在于:大家都把图书表设计成最简单的“书名、作者、出版社、ISBN、库存”,但共享书角需要多几个字段。
我在这个项目里比较推荐的表结构是:
- id、book_name、author、publisher、isbn
- category_id(分类外键)
- cover_url(封面图地址)
- description(简介)
- status(0可借,1已借出,2下架,3待审核)
- owner_id(共享者ID,系统录入的书可以设为0)
- create_time、update_time
关键在于owner_id。这个字段把图书从“图书馆所有”变成了“某个人所有”。当用户上架一本书时,owner_id就是当前登录用户。当系统管理员自己录入藏书时,owner_id置空或者给一个固定值。
status字段也是重头戏。用户上架的图书不能直接出现在借阅列表里,必须先经过审核。所以status至少要有“待审核”这个状态。很多作品把状态简化成“在馆/借出”,这对共享书角来说是不够的。
2.3 借阅记录表:状态的流转决定业务成败
借阅表是整个系统里逻辑最复杂的一张表,因为共享书角的借阅状态至少是五态流转:
- 待确认(用户发起借阅,等待共享者或管理员确认)
- 借阅中(确认通过,书出库)
- 待归还(已经申请归还,等待接收方确认)
- 已完成(归还确认,流程终结)
- 已取消(借阅申请被拒绝或主动取消)
五态流转对应到后端代码里有顺序:待确认 -> 借阅中 -> 待归还 -> 已完成。中间任何一步都能跳到已取消。
表格结构上,借阅记录表必须携带:book_id、borrower_id(借阅人)、owner_id(共享者)、apply_time、borrow_time、return_time(实际归还时间)、due_time(应还时间)、status、remark。
这个表是后面后端接口设计的主线,建议拿到代码后先花一个小时把这张表的字段梳理明白,再去看接缝代码就非常顺畅了。曾经有粉丝找我看项目,说运行不起来,我排查到最后发现借阅表漏了due_time字段,导致所有逾期判断的地方都报空指针。字段先行,这话不是空话。
2.4 辅助表:分类、公告、收藏、评论
辅助表在论文里可以用来凑“系统功能模块设计”的篇幅,但它们的结构同样有讲究。
book_category分类表,最简单,id + category_name + sort_order。在首页导航栏遍历展示时,sort_order控制顺序。
notice公告表,id + title + content + create_time,注意发布公告只涉及管理员,不需要做评论互动,保持简单即可。
favorites收藏表和comment评论表属于锦上添花的功能,也可以换成“点赞”或“浏览记录”。如果项目周期紧,这两张表可以拆掉不做,不会影响主流程。但如果做了,建议在论文的需求分析里专门提一句,因为这会丰富系统的功能层次感。
MySQL 8和5.7在建表时的差异也要提一下。比如8.0支持DEFAULT CURRENT_TIMESTAMP的默认值更规范,同时驱动名从com.mysql.jdbc.Driver变成了com.mysql.cj.jdbc.Driver,连接字符串还需要加serverTimezone=Asia/Shanghai,这些细节在部署文档里要写清楚,否则很多同学MySQL装好了,代码一启动就报时区错误。
3. SpringBoot后端:把借书流程的状态流转做扎实
SpringBoot层的核心工作就是提供RESTful接口、处理业务逻辑、操作MySQL。很多同学拿到源码第一反应是晕,因为Controller、Service、Mapper三层太多了。我建议不要按文件顺序去读,而是按业务流水线走一遍,尤其要吃透借书流程。
3.1 三层命名与唯一约定
先记住一套约定,这套约定直接让你从“看不懂代码”变成“能给别人讲代码”:
- Controller层:负责接收HTTP请求、参数校验、调用Service、返回统一结果
- Service层:负责业务逻辑,事务也打在这一层
- Mapper层:负责SQL操作,对应MyBatis/MyBatis-Plus的接口
真正理解这三层,可以用生活类比:Controller是餐厅的前台,客人点菜它接单;Service是后厨,所有的食材处理和烹饪逻辑都在这;Mapper是仓库管理员,后厨说需要什么食材,它就负责从仓库(数据库)拿出来。
如果项目用的是MyBatis-Plus,你会在Mapper层发现大部分方法都是直接继承BaseMapper来的,比如selectById、insert、updateById,不用写SQL。这非常省事,但答辩时必须有一个人能讲清楚:MyBatis-Plus的自动填充和条件构造器是怎么工作的。不然“你既然用了MyBatis-Plus,那你了解它的底层原理吗”这一问就会尴尬。
3.2 一图看懂借书接口的全流程
整个系统最核心的接口是“借阅申请”。我在梳理这块代码时,通常建议按这个顺序走读,不管项目本身的命名如何:
- 前端传入bookId和当前登录用户,调用
/api/borrow/apply - Controller层接收参数,校验图书状态是否为“可借”
- Service层开启事务:把图书状态改成“已借出”,插入一条借阅记录状态为“待确认”
- 如果图书的owner_id有意义,则要通知共享者(先可以不做消息推送,但把这条记录关联清楚)
- 返回给前端“申请成功,等待确认”
这里“图书状态”和“借阅记录状态”是两条链路,一定要同时更新。如果只改了图书状态没插入借阅记录,那归还时会发现没有关联记录可以操作,整个流程就卡死了。
这部分的代码逻辑,关键用MyBatis-Plus可以写成这样:
java复制@Transactional
public Result applyBorrow(BorrowApplyDTO dto) {
Book book = bookMapper.selectById(dto.getBookId());
if (book == null || book.getStatus() != 0) {
return Result.error("图书不存在或不可借");
}
// 更新图书状态
book.setStatus(1);
bookMapper.updateById(book);
// 插入借阅记录,状态为待确认
BorrowRecord record = new BorrowRecord();
record.setBookId(book.getId());
record.setBorrowerId(dto.getUserId());
record.setOwnerId(book.getOwnerId());
record.setStatus(1); // 待确认
record.setApplyTime(new Date());
// 计算应还时间,默认30天
record.setDueTime(DateUtil.offsetDay(new Date(), 30));
borrowRecordMapper.insert(record);
return Result.success("借阅申请提交成功");
}
注意我特别写了@Transactional注解,这是事务控制的标志。只要任何一个数据库操作失败,整个流程都会回滚,不会出现“书借出去了,但记录没插上”这种脏数据。
3.3 JWT登录认证与权限拦截
共享书角的接口分用户端和管理端,这个在SpringBoot里主要通过拦截器实现。推荐的技术方案是JWT(JSON Web Token),因为它是无状态的,服务器不需要保存Session。
前端登录成功后,后端会签发一个token返回给前端。前端把它存在本地存储里,每次请求在Header里带上Authorization: token值。后端通过拦截器解析这个token,拿到用户ID和角色信息。
代码大体是这样:
java复制public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("Authorization");
if (token == null || token.isEmpty()) {
throw new BusinessException("未登录");
}
// 解析token
Claims claims = JwtUtil.parseToken(token);
Long userId = claims.get("userId", Long.class);
Integer role = claims.get("role", Integer.class);
request.setAttribute("userId", userId);
request.setAttribute("role", role);
return true;
}
}
然后注册拦截器时,排除登录、注册、图书列表查询这些免认证接口。对于管理员接口,可以再加一道角色判断。
这里有一个很常见的坑:token有效期和续期策略。很多毕业设计直接把token有效期设置为24小时,结果学生做演示时,头天部署好,第二天打开页面发现“未登录”,没有经验的答辩者会当场慌神。建议把有效期设长一点,比如7天,并且在论文测试部分写明这个参数。
3.4 统一返回结果与全局异常处理
有经验的开发者看一个SpringBoot项目的第一眼,就是看有没有统一返回结构。共享书角项目一般会定义一个Result类:
java复制public class Result {
private Integer code; // 200成功,500失败,401未登录
private String message;
private Object data;
}
所有Controller接口返回的都是Result.success(data)或者Result.error("提示信息")。前端axios拦截器统一判断code,不是200就直接弹报错提示。
这个设计带来的最大好处是,前端处理逻辑会非常统一。不会出现“有的接口返回字符串、有的返回对象、有的直接抛出异常页面”这种混乱状况。答辩时,这段代码可以去讲“统一规范”,是很加分的架构意识。
全局异常处理通常用@RestControllerAdvice注解,配合@ExceptionHandler,把已知的业务异常和未知的运行时异常都包装成Result返回。否则一旦数据库出问题,前端会看到一个白色错误页,现场很尴尬。
4. Vue前端:几个必须处理的交互细节
前端用的是Vue,无论是Vue2配合Element UI,还是Vue3配合Element Plus,整体的页面交互逻辑是类似的。如果拿到的是Vue2项目,第一个要确认的是Node版本。Vue2和node-sass的版本兼容问题是重灾区,很多人部署时卡在npm install报错,大概率就是这里。
4.1 路由与登录拦截
共享书角的页面路由大体分两层。外层是游客可访问的:首页、图书列表、图书详情、登录注册页。内层是登录后才能进的:个人中心、借阅记录、上架图书、管理后台。
Vue Router的全局前置守卫在处理这个需求时非常顺手:
javascript复制router.beforeEach((to, from, next) => {
const token = localStorage.getItem("token");
if (to.meta.requiresAuth && !token) {
next("/login");
} else {
next();
}
});
这里需要注意一个细节:为什么用localStorage而不是sessionStorage?很多学生会问。很简单,sessionStorage关闭浏览器之后就清空了,用户每次刷新重进浏览器都要重新登录,体验很差,也不利于演示。localStorage只要用户不主动点退出登录,token就一直存在。这对毕业设计的现场演示来说,能少很多低级失误。
4.2 页面结构与Element组件的合理使用
前端页面通常包括:首页推荐图书、分类筛选、图书详情、借阅状态跟踪、个人中心、后台数据看板。
用Element组件库做页面效率很高。但从答辩角度,不要只堆组件,也要能回答“你为什么要用这个组件”。比如:
- 使用
el-table展示借阅记录列表,因为表格形式适合展示结构化数据 - 使用
el-pagination做分页,因为图书数量大了之后前端一次性渲染全部数据会导致页面卡顿 - 使用
el-dialog做借阅确认弹窗,避免页面跳转打断操作流
这类细节讲出来,会明显提升项目的“完成度”,评委看得出你是理解过交互设计的,而不是单纯套了一个前端模板。
图书搜索这块,常用的是按书名关键字模糊查询。前端输入关键词,请求后端接口,后端用MyBatis-Plus条件构造器处理:
java复制LambdaQueryWrapper<Book> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.isNotBlank(keyword), Book::getBookName, keyword);
keyword为空时不加查询条件,这个细节非常实用。推荐在论文的“系统实现”部分把它点出来。
4.3 跨域问题的处理办法
前后端分离项目最经典的坑就是跨域。开发环境下,前端跑在localhost:8080(Vue默认端口),后端跑在localhost:9090,浏览器会直接拦截后端返回的数据。
解决方案一般有两种。第一种是在后端加全局跨域配置:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*");
}
}
第二种是利用Vue的代理转发。在vue.config.js里配置devServer,让前端的/api前缀请求转发到后端地址,从而绕开浏览器跨域限制。
这两种方案建议都掌握。因为开发阶段用代理方便调试,生产部署用Nginx反向代理时又要把/api转发到后端服务上,本质逻辑是相通的。
4.4 页面级的视频或动态效果处理
还有一个很多同学问到的问题:Vue里一些特殊资源的播放或展示怎么做。比如有人问“Vue播放m3u8视频流”,这跟共享书角的主业务关系不大,但如果想在首页放一片共享书角宣传视频,m3u8这种流媒体格式就需要借助video.js支持,如果用普通mp4文件,原生video标签就行。
坦白讲,毕业设计不建议在视频播放上花太多时间,除非你论文的“系统创新点”专门写多媒体功能。没有把握就不要硬上,一个正常的静态封面图比一个播放失败的视频体面得多。
5. 从源码到上线:本地跑通与服务器部署全流程
这一部分是最容易翻车、也是最能拉开差距的地方。很多学生拿到源码,本地能跑就觉得自己会了,但答辩现场用的是另一台电脑,部署失败就直接崩了。所以下面把从零跑通的完整步骤过一遍。
5.1 环境准备:JDK、MySQL、Node、Maven一个都不能少
先确认本机环境:
- JDK 1.8或11都可以(我碰到过用JDK 17跑SpringBoot 2.x项目出问题的,所以尽量别用太高版本)
- MySQL 5.7或8.0(推荐8.0,但要注意驱动配置不一样)
- Node.js 14以上(Vue3建议Node 16+)
- Maven 3.6以上
装环境这件事,最容易被忽略的是“版本匹配”。SpringBoot 2.7用JDK8没问题,但SpringBoot 3.x必须要JDK17起。如果你拿到的是新版项目,一定要先看pom.xml里的spring-boot-starter-parent版本,再决定安装什么JDK。这个顺序搞反了,后面全是坑。
5.2 数据库导入与配置
用Navicat命令创建数据库:
sql复制CREATE DATABASE bookshare DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
然后导入sql文件。执行完成后,用use bookshare;切库,show tables;查看表数量,确认表都建出来了。
接下来打开后端项目的application.yml,核对数据库连接信息:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/bookshare?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: yourpassword
driver-class-name: com.mysql.cj.jdbc.Driver
一个小经验:账号密码不要用root/root的空口令组合,部分环境的MySQL默认不允许root无密码连接。为了省事,直接把信息配置对,比在代码里反复调试省时间。
5.3 后端启动与常见报错
使用IDEA导入后端项目,等待Maven下载依赖。依赖下载慢是永恒话题,可以在settings.xml里配置阿里云镜像:
xml复制<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
启动类通常在src/main/java下的某个包中,名为Application或MainApplication。右键运行后,如果控制台打印出Tomcat started on port(s): 9090,说明后端已经起来了。
常见报错和处理思路:
Access denied for user 'root'@'localhost'——数据库账号密码或权限有问题Unknown database 'bookshare'——没有建库或者库名写错Table doesn't exist——SQL导入失败或连错库Port 9090 was already in use——端口被占用,改端口或杀进程
5.4 前端启动与接口联调
前端项目在IDEA里打开或在VS Code里打开都行。第一步安装依赖:
bash复制npm install
如果因为网络原因装不动,用淘宝镜像:
bash复制npm install --registry=https://registry.npmmirror.com
依赖装完后启动开发服务:
bash复制npm run serve
当界面能打开时,先不要急着操作。打开浏览器开发者工具F12,点击一个需要登录的功能,看Network面板中请求/api开头的接口是否404或报401。如果404,就去检查Vue的开发代理配置是否正确。代理配置在vue.config.js:
javascript复制module.exports = {
devServer: {
port: 8080,
proxy: {
"/api": {
target: "http://localhost:9090",
changeOrigin: true
}
}
}
};
这里有一个常见的绕弯之处:后端接口不一定是/api前缀,可能直接就是/user/login。这时代理配置就要写"/"而不是"/api"。具体的以前端封装的axios默认baseURL为准,千万别想当然。
5.5 生产部署:Nginx + Jar包
答辩前如果要在服务器上演示,把前后端部署到一台轻量云服务器上是加分项,部署的核心逻辑是:
- 前端构建生成静态资源:
npm run build,产出dist目录 - 把dist目录里的内容上传到Nginx的web根目录
- 后端打包生成jar包:
mvn clean package -Dmaven.test.skip=true - 上传jar包到服务器,用
nohup java -jar bookshare.jar > log.txt 2>&1 &后台运行 - Nginx配置,把
/api前缀的请求反向代理到本地9090端口
Nginx反向代理配置核心:
nginx复制server {
listen 80;
server_name your_server_ip;
root /usr/share/nginx/html; # dist上传后的目录
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:9090;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
这里最容易被忽视的是history路由模式。Vue默认可能开启了createWebHistory(),页面刷新时如果Nginx找不到对应的路由会404。解决办法是加一个fallback配置:
nginx复制location / {
try_files $uri $uri/ /index.html;
}
很多同学本地跑一切正常,部署到服务器上只有首页能看,一刷新页面就404,基本都是这个问题。在部署文档里一定要写明这句话,否则现场演示会很难看。
6. 论文与答辩:把项目讲成“自己的作品”
最后聊点干货之外的竞争力。毕业设计的分数,一半看代码实现,一半看论文写作和答辩表达。项目再好,如果讲不出来,等于白做。
6.1 论文结构不建议标新立异
共享书角系统的论文我建议按最传统的六章走:绪论、相关技术介绍、需求分析、系统设计、系统实现、系统测试。要不要加“总结与展望”?加,但两页以内就够了。
相关技术介绍这一章是凑字数重灾区,很多人花三四页介绍SpringBoot是什么、Vue是什么。我的建议是压缩到两页,而且每介绍一个技术,一定要在末尾补一句“本系统为何采用该技术”。这句话才是评委想看到的。
比如:
SpringBoot采用自动装配机制,简化了Spring应用的初始化和配置流程,使开发者可以快速搭建独立运行的Web服务。本系统选择SpringBoot作为后端开发框架,主要原因在于其与Vue前后端分离架构的契合度高,能够通过RESTful接口快速完成数据交互。
论文不是技术手册,要体现“选型是思考过的”。
6.2 需求分析部分要画清楚用例图
共享书角系统的用例图,至少要有用户和管理员两个角色。用户的用例包括:注册登录、浏览图书、搜索图书、发起借阅、归还图书、上架共享图书。管理员的用例包括:图书审核、借阅登记、归还确认、用户管理、公告管理。
画这张图的目的不是好看,而是帮你自己梳理清楚“系统应该有哪些功能”。如果用例图里没有“图书审核”,说明需求分析阶段就漏了核心功能。这种问题在答辩时被评委发现,比自己改代码时发现要麻烦得多。
6.3 答辩常见追问与应对
根据两届毕业生答辩的经验,评委针对这类系统最常追问的问题基本集中在以下几个:
“你的系统如何防止用户借了书不还?”
这个问题不是让你讲技术,而是讲业务设计。可以回答:一是设有应还时间due_time,系统会在过期后自动标记;二是通过信用分机制,逾期扣分,信用分过低限制借阅;三是管理员可以介入处理,在“借阅记录”中强制标记归还。
“数据库里图书表和借阅记录表是一对多关系吧,为什么要这么设计?”
这个问的是数据库设计的基本功。正常回答:一本书可以被不同用户在不同时间多次借用,所以图书表和借阅记录表是一对多。每次借阅对应一条记录,记录里保存book_id和borrower_id,避免在图书表中冗余存储借阅人信息。字段冗余会导致数据更新不一致。
“如果两个用户同时借同一本书,你用什么方案避免超卖?”
这个问题属于进阶题。最基本的回答是:在图书表加状态字段,借出前先更新状态。用乐观锁where status=0来更新,更新影响行数为0说明已经被借走:
java复制boolean success = bookMapper.updateStatus(bookId, 0, currentStatus);
if (!success) {
throw new BusinessException("该书已被借走");
}
如果项目里没有实现这部分,在答辩时坦诚说“目前采用了简单的状态判断,后续可优化为乐观锁方案”也是可以的。关键是要知道知识点,而不是空白。
“你的项目有哪些不足?”
这道题几乎必问。千万别回答“没有不足”,也不要答“全部是优点”。合适的答法是:系统针对中小型共享场景设计,未考虑高并发和大数据量;目前信用惩罚是手动触发,后续可以用定时任务实现自动扣分;借阅通知依赖站内消息,未来可接入邮件或公众号模板消息推送。这些“不足”每一个都说明你思考过系统的演进方向,反而加分。
6.4 部署文档要写到什么颗粒度
部署文档是很多同学交付时最容易写糊弄的一环。我见过太多“部署文档”只有三步:装JDK、装MySQL、运行。这对第一次操作的人来说跟没写一样。
合格的部署文档颗粒度应该到:每一步用什么命令、命令在哪个目录执行、执行成功后出现什么标志算成功、碰到什么报错信息代表哪里配错了。比如:
bash复制# 检查Java版本,出现java version "1.8"或"11.0"才算成功
java -version
# 启动后端服务,日志出现"Started XXXApplication in X.XX seconds"才算成功
nohup java -jar bookshare.jar > log.txt 2>&1 &
这个颗粒度写下来,不光是方便别人,也是在答辩时向评委展示你的交付意识。评委听到“部署文档写到了命令级”,第一印象一定比“代码能跑”高得多。
把上面这些内容吃透了,“共享书角”毕业设计对你来说就不再是一个黑盒源码,而是可以应对任何追问的完整项目。最后再分享一个小经验:做这类全栈项目,不要一开始就想着把源码跑起来,而是先画一张“借阅状态流转图”和一张“数据库表关系图”,这两张图吃透了,剩下的代码就是按图索骥的体力活。动手之前多花两小时建模,实操时能省下两天。
