ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Java+JSP网上拍卖系统毕设:架构设计、核心逻辑与避坑指南

Java+JSP网上拍卖系统毕设:架构设计、核心逻辑与避坑指南 简介一套基于JavaJSP的网上拍卖系统毕业设计源码面向Java Web初学者和毕业设计开发者完整实现了用户注册登录、商品浏览、在线竞拍、交易管理等功能。项目采用Java处理业务逻辑与数据管理JSP构建动态页面并结合Servlet、MVC思想、数据库操作、Session会话、安全编码等典型Web技术适合用于课程设计参考、毕业设计实现或二次开发练手。资源共137个文件压缩包仅2.36MB。其中包含42个JSP页面用于界面展示25个Class和20个Java源码文件承载请求处理与拍卖流程29个GIF和9个JPG图片提供页面素材另有3个JAR依赖库、1个MDF数据库文件及配置文件整体结构清晰便于对照学习。已有266人学习下载。通过源码可深入理解网上拍卖系统的完整实现从登录鉴权、商品上架到竞价结算均有对应Servlet和Java类支撑代码注释与模块划分适合逐段研读也可作为扩展开发的重要基础。1. 网上拍卖系统毕设一套 JavaJSP 项目到底值不值得做基于JavaJSP的网上拍卖系统毕业设计核心业务是让卖家发布商品、买家在截止时间前竞价、管理员后台监督它比普通的增删改查题库多出两个真正的技术难点出价时的并发控制和拍卖截止后的状态流转。适合正在纠结选什么题的在校生也适合已经拿到源码但不知道怎么改、怎么讲的人。这篇文章会从 Model 2 架构讲到四张核心表的设计再给出价逻辑和五个高频翻车点让你照着能把整套系统跑通答辩时也能把内容讲明白。2. 技术选型与项目结构为什么这套 JavaJSP 方案在毕设里不过时先说一个许多人不好意思问的问题企业里 Java 后端早就不用 JSP 写页面了为什么毕设还有大量题目挂着“JavaJSP”的名头答案很现实——JSP 项目把 Servlet 生命周期、内置对象、JDBC 事务、请求转发这些课程大纲里的重点全部摊开每个知识点都能在代码里找到对应位置。导师审题时看的是你复述原理的能力而不是你有没有跟上技术潮流。Spring Boot 固然新潮但大部分套壳生成的项目连 starter 原理都讲不清反而容易在答辩时露馅。JSP 方向还有一个隐形的便利网上能找到的完整毕设源码数量最多。你拿到一份 JavaJSP 的拍卖系统源码改动成本和调试成本都远低于冷门框架组合。下面从架构、数据表、目录结构三个维度把底子铺好。2.1 JSP Model 2 架构MVC 在你的项目里到底怎么分层Model 2 不是新东西它就是 MVC 在 JMSP 世界的标准说法JSP 只负责显示Servlet 接手所有请求转发和控制跳转JavaBean/DAO 负责数据访问。对比纯 JSP 时代把 SQL 写死在页面里的 Model 1Model 2 的代码虽然多写一层但换来了职责清晰你改页面不动逻辑改逻辑不碰 SQL。一个典型请求的流转浏览器提交表单 → Servlet 通过 DAO 读写数据库 → 把结果存到 request 或 session → forward 到 JSP 渲染页面。这段代码是登录请求的入口也是整个项目的骨架WebServlet(/login) public class LoginServlet extends HttpServlet { private UserDao userDao new UserDao(); Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding(UTF-8); String username req.getParameter(username); String password req.getParameter(password); User user userDao.findByUsernameAndPassword(username, password); if (user ! null) { req.getSession().setAttribute(loginUser, user); resp.sendRedirect(req.getContextPath() /index.jsp); } else { req.setAttribute(errorMsg, 用户名或密码错误); req.getRequestDispatcher(/login.jsp).forward(req, resp); } } }这里解释三个关键点。第一URL 映射用 WebServlet 注解而不是 web.xml省掉一段冗余配置但注意这要求 Tomcat 7 以上版本。第二doPost 第一行 setCharacterEncoding 很多人会漏漏掉后表单传过来的中文到 Servlet 就成乱码后面第五节再展开。第三登录成功后用 sendRedirect 重定向而不是 forward——重定向后浏览器地址栏变成了目标地址用户按 F5 刷新时执行的是 GET 请求不会重复提交登录表单。如果导师问你“为什么不用 Spring Boot”可以这样答JSP Model 2 把所有请求和响应的链路摊在明处更容易展示对 Servlet 核心机制的理解。这套回答不是借口而是毕设选题的真实加分逻辑前提是你真能懂每行代码在做什么。2.2 四张核心数据表从用户到出价记录网上拍卖系统有四个必不可少的数据实体用户、商品、出价记录、系统公告。设计原则是能不加外键就不加外键——MySQL 上外键会拖慢写入性能毕设阶段用逻辑关联在代码控制完全够用。用户表CREATE TABLE user ( id INT NOT NULL AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(64) NOT NULL, nickname VARCHAR(50) DEFAULT NULL, phone VARCHAR(20) DEFAULT NULL, role TINYINT DEFAULT 0 COMMENT 0-普通用户 1-管理员, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;商品表CREATE TABLE item ( id INT NOT NULL AUTO_INCREMENT, seller_id INT NOT NULL, title VARCHAR(100) NOT NULL, description TEXT, cover_image VARCHAR(255) DEFAULT NULL, start_price DECIMAL(10,2) NOT NULL, current_price DECIMAL(10,2) NOT NULL COMMENT 冗余当前价, status TINYINT DEFAULT 0 COMMENT 0-在拍 1-成交 2-流拍, start_time DATETIME NOT NULL, end_time DATETIME NOT NULL, PRIMARY KEY (id), KEY idx_status_end (status, end_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;出价记录表CREATE TABLE bid ( id INT NOT NULL AUTO_INCREMENT, item_id INT NOT NULL, user_id INT NOT NULL, bid_price DECIMAL(10,2) NOT NULL, bid_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_item_price (item_id, bid_price) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;字段设计上要重点说明 current_price它不是每次查询从 bid 表里聚合算出来的而是直接冗余在 item 表上。这么做的原因是——出价时只更新这一条记录列表页展示价格也不用连表聚合读写路径都最短。这是电商系统里空间换时间的经典做法答辩时主动提出来是明显的加分项。status 字段负责业务流程0 在拍、1 成交、2 流拍第四章的状态流转全靠它。2.3 项目导入与运行准备先绕过环境变量和 Target Runtime 两个卡点Eclipse 新建 Dynamic Web Project 后标准目录结构大概是这样的src/main/java // Servlet、DAO、Bean、工具类 src/main/resources // db.properties 等配置文件 src/main/webapp/WEB-INF/web.xml src/main/webapp/jsp // 业务页面放 WEB-INF 下防直接访问 src/main/webapp/css src/main/webapp/js src/main/webapp/images // 上传文件的目标目录两个约定要记牢。第一JDBC 驱动 jar 包必须放在 WEB-INF/lib 目录下而不是仅加入 Build Path——发布到 Tomcat 后只有这个目录下的 jar 会被加载放在别处运行时就报 ClassNotFoundException。第二页面文件尽量放 WEB-INF 子目录配合 Servlet 用 forward 跳转避免用户直接敲 URL 绕过登录访问受保护页面。这里补一个很多人翻车的环境配置问题项目导入 eclipse 后控制台报 NoClassDefFoundError: javax/servlet/ServletException你第一反应通常是去找 servlet-api.jar其实八成是 Tomcat 没挂到项目的 Target Runtime。右键项目 → Properties → Targeted Runtimes → 勾选你的 Tomcat 实例报错立刻消失。另外本地开发 JDK 用 8 或 11 就好装太高版本的 JDK 配老 Tomcat 反而容易碰到模块化相关的兼容问题。3. 用户注册与登录用 JSP Model 2 思想实现最小闭环这一章用代码走通注册和登录两条链路。注册涉及表单校验、密码加密、数据入库登录涉及查询验证、Session 写入、页面跳转。这两条链路把 JSP 面试八股文里最高频的 request、response、session、forward、redirect 全部覆盖也是你最该背熟编码的两段逻辑。3.1 注册前端校验、Servlet 处理、DAO 入库三段式前端 JSP 页面里放一个表单加一个最简单的 JS 必填校验。注意JS 校验只能拦住手滑拦不住恶意请求真正校验必须在 Servlet 里做。表单写法如下form action%request.getContextPath()%/register methodpost label用户名/label input typetext nameusername required minlength3 maxlength20/ label密码/label input typepassword namepassword required minlength6/ label确认密码/label input typepassword nameconfirmPassword required/ button typesubmit注册/button /form注意 action 地址写法。用 JSP 表达式%request.getContextPath()%拼前缀是为了项目改名或换部署路径时链接不至于 404。如果你写死/register项目发布名改成就全站按钮失效。这一行是 JSP 页面里最基础也最容易漏的接手的二手源码里经常就是这种隐患。Servlet 端接收参数后的核心校验逻辑WebServlet(/register) public class RegisterServlet extends HttpServlet { private UserDao userDao new UserDao(); Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding(UTF-8); String username req.getParameter(username).trim(); String password req.getParameter(password); String confirm req.getParameter(confirmPassword); if (password null || !password.equals(confirm)) { req.setAttribute(errorMsg, 两次密码输入不一致); req.getRequestDispatcher(/register.jsp).forward(req, resp); return; } if (userDao.exists(username)) { req.setAttribute(errorMsg, 用户名已存在); req.getRequestDispatcher(/register.jsp).forward(req, resp); return; } String salt MD5Util.getRandomSalt(); String hashed MD5Util.md5WithSalt(password, salt); userDao.insert(username, hashed, salt); resp.sendRedirect(req.getContextPath() /login.jsp); } }代码要点拆开说第一错误回显用 forward成功跳转用 redirect原因是防止刷新页面重复提交表单。第二equals 比较用的是password.equals(confirm)不是反过来写避免 confirm 为 null 时抛空指针。第三用户名校验用 exists 方法返回布尔值DAO 里执行一条 SELECT 1 FROM user WHERE username? 即可不要 SELECT 出整个用户对象再塞到列表里纯属浪费。3.2 密码存储MD5 加盐别把明文写进数据库毕设代码里最常见的翻车现场是 user 表 password 字段存明文。演示时导师瞄一眼数据库内容第一句话就是“密码怎么不加密”。所以这里直接给出可以照抄的加盐工具类public class MD5Util { public static String getRandomSalt() { return UUID.randomUUID().toString().replace(-, ).substring(0, 8); } public static String md5WithSalt(String pwd, String salt) { String src pwd salt; try { MessageDigest md MessageDigest.getInstance(MD5); byte[] bytes md.digest(src.getBytes(UTF-8)); StringBuilder sb new StringBuilder(); for (byte b : bytes) { sb.append(String.format(%02x, b)); } return sb.toString(); } catch (Exception e) { throw new RuntimeException(e); } } }salt 单独占一列和哈希值一起存。校验时根据用户名查出 salt对输入的密码重新加盐再做哈希比对两次结果即可。这种做法安全性比不上 BCrypt 那种自适应慢哈希但足以展示你理解了“密码不能明文存”这个底线。答辩时如果被追问就主动承认 MD5 加盐抗不住暴力破解生产环境应该换成 BCrypt然后补一句“毕设里用这个是为了直观展示加盐哈希的原理”——这个回答既诚实又有分寸。3.3 登录与 Session身份判断的常规动作登录 Servlet 的入口代码在 2.1 已经给过这一小节补一段 JSP 侧的身份判断和退出登录。页面顶部加这一段即可% User loginUser (User) session.getAttribute(loginUser); if (loginUser null) { response.sendRedirect(request.getContextPath() /login.jsp); return; } %这段 JSP 脚本片段放在每个受保护页面的第一行。要显示“欢迎 xx”直接用 loginUser.getNickname()。退出登录更简单调 session.invalidate() 清掉整份会话再重定向到登录页。有人会问为什么不把这段判断放进 Filter这样每个页面就不用重复写了。Filter 方案确实更规范但用在 JSP 项目里有一个真实的隐患除了登录注册静态资源的 css、js、图片路径也会被 Filter 拦一遍配置时要把这些路径全排除掉漏一个就出现“样式加载不出来”或“图片裂开”。我的建议是毕设阶段优先用页面顶部判断别在过滤链上跟自己较劲。如果你非要体验 Filtermapping 路径写 /pages/*静态资源单独放 /static/ 下两边彻底分开。4. 商品发布与出价拍卖核心业务逻辑和它的并发控制前面做完用户闭环这一章进入业务主体。拆成商品上架、出价并发控制、状态流转三小节。其中出价这一小节是整套毕设的含金量所在导师追问最凶的就是出价并发。4.1 商品上架文件上传和普通字段一起处理上架表单要同时提交图片和多个普通字段。form 标签需要加 enctypemultipart/form-data这意味着 Servlet 端不能用普通的 getParameter 直接拿字段要改用 Part 接口读取。先看页面form action%request.getContextPath()%/item/publish methodpost enctypemultipart/form-data input typetext nametitle/ textarea namedescription/textarea input typefile namecoverImage/ input typenumber namestartPrice min0.01 step0.01/ input typedatetime-local nameendTime/ button typesubmit发布/button /formServlet 端接收WebServlet(/item/publish) MultipartConfig(maxFileSize 5 * 1024 * 1024) public class PublishServlet extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding(UTF-8); String title req.getParameter(title); String description req.getParameter(description); String startPrice req.getParameter(startPrice); Part part req.getPart(coverImage); String fileName System.currentTimeMillis() _ Paths.get(part.getSubmittedFileName()).getFileName(); String savePath req.getServletContext().getRealPath(/images/ fileName); part.write(savePath); Item item new Item(); item.setTitle(title); item.setDescription(description); item.setStartPrice(new BigDecimal(startPrice)); item.setCurrentPrice(new BigDecimal(startPrice)); item.setCoverImage(/images/ fileName); item.setStatus(0); item.setEndTime(Timestamp.valueOf( req.getParameter(endTime).replace(T, ) :00)); new ItemDao().insert(item); resp.sendRedirect(req.getContextPath() /item/list); } }注意三个细节。第一MultipartConfig 不写的话默认文件大小上限 1M图片稍微大点就抛异常毕设演示时最好调成 5M。第二文件名加了时间戳前缀防重名两个用户同时传同名的 1.jpg 不会互相覆盖。第三Paths.get(...).getFileName() 用来剥掉 IE 老版本上传路径里带的盘符信息兼容性处理建议保留。getRealPath 拿到的是 Tomcat 部署后的实际磁盘路径不是 IDE 里的源码路径——这个差异在第五章第五节展开讲。4.2 出价并发控制一条 UPDATE 挡住脏数据网上拍卖和普通电商最大的区别在于出价是增量写入同一件商品可能同时被多个买家点击。如果代码写成“先查当前价再加价再更新”两个请求同时读到同一个 oldPrice后写的人会把先写的人覆盖掉这在并发里叫丢失更新。正确做法是把“价格必须大于当前价”这个约束直接压进 UPDATE 语句用条件更新保证原子性public boolean placeBid(int itemId, int userId, BigDecimal newPrice) { String sql UPDATE item SET current_price ? WHERE id ? AND status 0 AND current_price ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setBigDecimal(1, newPrice); ps.setInt(2, itemId); ps.setBigDecimal(3, newPrice); return ps.executeUpdate() 1; } catch (SQLException e) { throw new RuntimeException(e); } }把 current_price newPrice 写在 WHERE 里数据库会在行锁粒度上做比较两个并发请求只有一个能满足条件更新成功另一个 executeUpdate 返回 0。返回 0 就表示这次出价无效提示用户“价格落后了”。出价记录要同时写入 bid 表所以这两个操作必须放进同一个事务否则会出现价格变了但记录没落库public boolean bidWithRecord(int itemId, int userId, BigDecimal newPrice) { Connection conn DBUtil.getConnection(); try { conn.setAutoCommit(false); boolean ok updateCurrentPrice(conn, itemId, newPrice); if (!ok) { conn.rollback(); return false; } insertBidRecord(conn, itemId, userId, newPrice); conn.commit(); return true; } catch (Exception e) { try { conn.rollback(); } catch (SQLException ex) { /* ignore */ } throw new RuntimeException(e); } finally { DBUtil.closeQuietly(conn); } }这套方案锁的是 item 表那一行记录代价最小也最好讲。导师如果追问“为什么不用 synchronized 或悲观锁”标准回答是synchronized 在应用集群部署时锁不住多台机器的请求悲观锁要额外开事务并且容易死锁而条件更新是数据库行级原子操作不需要额外的锁机制天然适合这个场景。这句话背下来出价这块的答辩就稳了。4.3 拍卖状态流转在拍、成交、流拍怎么切换表设计里 status 有三个值0 在拍、1 成交、2 流拍。商品发布时是 0截止时间到了且有出价记录应该变 1没人出价就是 2。很多二手源码的做法是在列表页直接拿 end_time 和当前时间比较不更新 status 字段导致数据库里状态全是 0。能跑但导师一查数据就说你状态机设计缺失。规范又省事的写法是提供一个结算方法每次有人刷新页面时被动触发一次public void settleExpiredItems() { String sql UPDATE item SET status CASE WHEN current_price start_price THEN 1 ELSE 2 END WHERE status 0 AND end_time NOW(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } }这里用 CASE 表达式一次更新两种状态避免“先查再改”的两条语句。注意判断成交的条件是 current_price start_price也就是有人把价格抬过了起拍价如果你允许低价成交改成 current_price start_price 即可。主动在列表页加载时调用这个方法就能保证界面上看到的永远是正确状态。不要引入 Quartz 定时任务毕设阶段用被动触发就够了也少一层部署负担。5. 避坑指南JSP 网上拍卖毕设里翻车率最高的五个问题这一章专门盘点 JSP 毕设里真实踩坑率最高的五个点按出现频率排序。每一条都按“现象 → 原因 → 解决”三步走你遇到类似报错时可以直接对照。5.1 中文乱码JSP 页面正常Servlet 里全是问号现象JSP 页面上显示中文正常表单提交后用日志打印 request 参数中文全部变成“?????”进数据库也变成问号。原因三层编码不一致。Tomcat 8 以上的 GET 请求默认 UTF-8但不代表 POST 也默认 UTF-8request.getParameter 拿到的参数编码取决于请求体怎么提交的。加上 JSP 页面没写 pageEncoding、数据库表又是 latin1三处编码不统一乱码在所难免。解决三处统一。首先 JSP 页面顶部写% page contentTypetext/html;charsetUTF-8 pageEncodingUTF-8 %其次 Servlet 的 doPost 第一行写req.setCharacterEncoding(UTF-8)最后 JDBC URL 加?useUnicodetruecharacterEncodingutf8参数。提示如果这三点都改对了还乱码检查一下 filter 里是不是又调了一次 setCharacterEncoding重复调用后一次会覆盖前面的保持全项目只设置一次。5.2 Tomcat 10 启动失败javax.servlet 包找不到现象代码在你自己电脑跑得好好的发给同学打开后编译报错提示 javax.servlet 包不存在Tomcat 启动直接失败红字一堆。原因Tomcat 10 起把 Servlet API 的命名空间从 javax.servlet 迁移到了 jakarta.servlet所有 import javax.servlet.* 的代码在 Tomcat 10 下全部失效。这是生态级别的变更不是你的源码问题。解决最省事的是装 Tomcat 9.0.x 来跑不要去改代码里的 import。改 import 要动所有 Servlet 和 Filter工作量大还容易漏对毕设没有任何收益。判断方式很简单打开 Tomcat 的 lib 目录看有没有 jakarta.servlet-api.jar 这个文件有就是 Tomcat 10 以上。5.3 图片上传成功但列表页裂开现象商品发布时图片明明上传成功了但列表页的 img 标签显示裂图浏览器直接访问 /images/xxx.jpg 返回 404。原因part.write(savePath) 写的是 getRealPath 返回的物理路径这个路径在 Tomcat 的部署目录下但列表页的 img src 如果写成了相对路径比如 srcimages/xxx.jpg浏览器会基于当前页面 URL 去拼地址页面在 /jsp/ 子目录时图片请求就指向了错误的目录。解决JSP 页面里图片地址必须带 contextPath 前缀写成img src%request.getContextPath()%/images/xxx.jpg。另外要理解 getRealPath 目录在 IDE 里运行时指向的是 Tomcat 临时目录重启后文件可能被清空所以毕设阶段上传完演示时别中途重启服务器。5.4 并发出价互相覆盖成交价不对现象开两个浏览器窗口用两个账号同时出价同一商品最终 current_price 只等于其中一个账号的价格另一个账号操作看着成功但价格没涨出价记录也少了一条。原因代码写成“先 SELECT current_price然后加价再 UPDATE”两个请求同时读到了同一个旧价格后写入的覆盖了先写入的。这就是典型的读改写竞态你的程序里没有任何并发防线。解决按照第四章 4.2 的条件更新方案把 UPDATE 语句改成带 WHERE current_price ? 的形式。如果你拿到的是别人写的源码搜索 item 表的 update 语句看看有没有这个条件没有就是漏了并发保护。补上去再加个事务包住更新和插记录两步问题就解决了。5.5 返回键或刷新导致重复提交现象用户出价成功后按 F5 刷新页面系统又插入了一条完全相同的出价记录按浏览器返回键也会触发同样的重复提交。原因传统 JSPServlet 同步提交方式天然有这种缺陷。用户在出价页面点提交后浏览器记住了上一次 POST 请求的完整内容刷新或返回再确认一次服务器就会再执行一遍同样的逻辑。解决出价成功后必须用 sendRedirect 重定向到查询页不要用 forward。重定向后地址栏 URL 变成查询页的地址原来的 POST 请求已经完成F5 刷新执行的是 GET 查询而不是原 POST。辅助方案是加防重令牌——出价页渲染时在 session 里放一个 token提交时校验后立即失效两次提交第二次直接拒绝。毕设里用重定向方案就足够防重令牌可以作为答辩扩展点提一嘴。6. 从源码跑通到答辩演示版本匹配检查与加分做法最后一章不讲理论了直接给一份可以照着执行的检查清单和两个实用的答辩加分做法。6.1 运行前版本匹配速查表| 组件 | 推荐版本 | 检查目的 | | JDK | 8 或 11 | 兼容 Servlet 3.x 与 JSP 2.3 | | Tomcat | 9.0.x | 避免 javax.servlet 迁移导致编译失败 | | MySQL | 5.7 或 8.0 | 无外键设计下两者皆可 | | mysql-connector-java | 与 MySQL 大版本一致 | 驱动版本不匹配会连接失败 |这套组合五到十分钟就能确认完。最容易踩的还是 Tomcat 10 那个坑所以表格里直接锁死 9.0.x。6.2 答辩演示的五个必走流程注册一个买家账号并登录用卖家账号发布一件带图的商品并设置起拍价切换买家账号对商品出价并观察价格变化把截止时间改成过去后刷新列表确认状态流转最后以管理员身份登录模拟删除违规商品。演示时每个操作都要有可视反馈。很多扣分不是功能没做而是你没把功能有效性展示出来。6.3 加一个倒计时展示的进阶调整给商品列表加一个原生 JS 的倒计时展示不需要引框架。注意 JSP 和 JavaScript 的边界服务端输出的 endTime 是 Java 时间对象JS 需要接收 ISO 格式字符串再 new Date() 转换。格式必须是 yyyy-MM-ddTHH:mm:ss中间的 T 不能少否则部分浏览器解析失败时间显示成 NaN。把这段倒计时封装成一个 function 放在公共 js 文件里商品详情页和个人信息展示页面都能复用不需要每个页面重写一遍。这样既展示了原生 JS 能力也体现了模块化复用的意识答辩时能让你比同组同学明显多一个亮点。从我带过的项目经验看拿到任何一份源码包先不要改动任何代码原样部署跑通一次再看懂它的表结构和请求链路最后动手改三个点——密码加密、并发出价、状态流转。这比从零重写快得多也比朗读别人的源码稳得多。毕设答辩的本质是把代码讲明白而不是证明代码是你敲的。先把版本环境调通再把自己改过的每一处细节都过一遍你也有底气走到讲台前。希望这篇拆解帮到你。本文还有配套的精品资源点击获取
返回列表