JSP+MySQL网上订餐管理系统:源码拆解、部署避坑与答辩提升指南

📅 发布时间:2026/10/7 13:03:20
JSP+MySQL网上订餐管理系统:源码拆解、部署避坑与答辩提升指南
简介基于JSPMySQL实现的网上订餐管理系统课程设计源码包面向高校计算机专业学生与JSP入门开发者。项目围绕在线订餐业务实现管理员登录与权限管理、菜谱及推荐菜品维护、购物车订单与支付、用户注册登录、配送地址修改、商家介绍更新等模块覆盖典型Web业务闭环。压缩包共138个文件核心为41个Java源文件与对应class编译文件搭配19个JSP页面、8个JAR依赖库另有SQL数据库脚本、CSS样式、XML工程配置、MD说明及DOCX文档整体约2.52MB结构清晰可直接导入IDE运行调试。已有503人浏览学习可作课程设计参考或二次开发基础。读者可依据SQL脚本快速建库结合JSP与Servlet源码理解分层实现与数据库交互逻辑并利用预留接口扩展功能是巩固JavaWeb开发技能、快速完成课程设计的实用案例。1. JSPMySQL网上订餐管理系统课程设计为什么都爱拿它当题一到期末网上订餐管理系统几乎是JSP课程设计里出现频率最高的选题之一。原因很直白它同时踩中了JSP课程要求的Servlet处理请求、JSP页面展示、JavaBean封装数据、JDBC操作MySQL这几个必考知识点功能上又覆盖了用户注册登录、菜品展示、购物车下单、订单支付、后台菜品管理这一整条业务链比学生信息管理系统有画面感比商城系统体量小一个学期内能做完。这套资源的核心价值也正在于此它不是一个只跑得起来的Demo而是把管理员端、用户端、菜品管理、订单流转全部串起来的完整工程。文中会出现OrdersDAOImpl、AddMenuServlet、DbcpConnectionPool这一串类名其实已经把项目的分层结构泄露得差不多了。适合正在做JSP课程设计、或者毕业设计想拿现成系统二次开发的人也适合想看看JSP传统三层架构到底怎么组织代码的初学者。提示项目编号100012326网上流传的版本里有的带源码有的只有class文件下文所有拆解都基于完整源码包的视角。2. 从Class文件名反推项目骨架DAO层、Servlet层与连接池的配合逻辑2.1 实体类与DAO接口的映射关系拿到项目先别急着部署看class文件命名的规律就能摸清结构。项目里同时出现了Menu.class、Orders.class显然对应菜单和订单两个核心实体。PersonDAOImpl和UserInfoDAOImpl同时存在这个很多人会看懵拆开看就明白PersonDAOImpl管的是登录认证用的用户账号密码UserInfoDAOImpl管的是用户配送信息、联系方式这些个人资料。两个DAO都操作user这张表但职责边界不同。这就是课程设计里常见的“同一个表拆成多个DAO”的写法核心目的就是让每个DAO的方法少而明确比如PersonDAOImpl只提供findByUsernameAndPasswordUserInfoDAOImpl只管updateAddress和updateUserInfo。对应关系理清之后再看每张业务表的归属。菜单表对应Menu实体和MenuDAOImpl订单表对应Orders实体和OrdersDAOImpl留言或公告对应MessageDAOImpl管理员相关操作没有单独的Admin实体而是用PersonDAOImpl带上type字段来做区分。这种设计不算优雅但胜在直观答辩时老师问“你这个管理员和用户怎么区分”直接回答“user表里加一个type字段type1是管理员type0是普通用户”就够了。// 典型的实体类写法对应数据库表字段 public class Menu { private int id; // 菜品编号主键自增 private String name; // 菜品名称 private double price; // 价格注意用double还是BigDecimal private String img; // 图片路径存相对路径而不是二进制 private int recommend; // 是否推荐1推荐0不推荐 public int getId() { return id; } public void setId(int id) { this.id id; } // 其余getter和setter省略课程设计的实体类都是这种模板代码 }这段代码有几点要说清楚。图片字段存的是字符串路径不是把图片文件塞进MySQL这是最常见的正确做法实际开发中图片会上传到服务器某个目录数据库只记录路径例如/upload/menu01.jpg。recommend字段是非常典型的课程设计加分点摘要里提到的“添加推荐菜品”和“删除推荐菜品”就是靠这个字段实现的首页查询时加一个WHERE recommend 1就能把推荐菜筛出来。另外价格字段课程设计里几乎都用double真做商城系统必须换BigDecimal这个答辩时如果老师问为什么不用BigDecimal能回答出来会很加分。2.2 DbcpConnectionPool数据库连接池为什么不直接DriverManager项目里专门拆了一个DbcpConnectionPool.class这个类值得细看。很多JSP课程设计偷懒直接在DAO里写DriverManager.getConnection(url, user, password)每次请求都新建一个连接用完就关。在本地测试数据量小看不出问题可一旦项目要提交到服务器上跑演示或者给老师答辩时反复点页面这种写法会导致MySQL连接数膨胀报错“Too many connections”是迟早的事。这套资源用DBCP连接池就是提前规避这个问题初始化时一次性创建一批连接放在池子里用的时候借出去用完还回来。// DbcpConnectionPool核心代码懒加载单例模式 public class DbcpConnectionPool { private static BasicDataSource dataSource null; public static void init() { if (dataSource null) { dataSource new BasicDataSource(); dataSource.setDriverClassName(com.mysql.jdbc.Driver); dataSource.setUrl(jdbc:mysql://localhost:3306/order_db? useUnicodetruecharacterEncodingutf8); dataSource.setUsername(root); dataSource.setPassword(123456); dataSource.setInitialSize(5); // 初始连接数 dataSource.setMaxActive(20); // 最大活跃连接数 } } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } }参数说明initialSize表示启动时预先建几个连接一般设5就够了maxActive是池子最多能撑起多少个并发连接课程设计场景20绰绰有余。URL里的useUnicodetruecharacterEncodingutf8这个参数建议以后所有MySQL连接都老老实实写上。很多人的系统中文乱码不是代码写的错而是这一步URL编码参数没加。另外init()用了单例模式保证整个Web应用生命周期内只初始化一次连接池避免重复创建耗尽数据库资源。这里要提醒的是DBCP用到的两个jar包commons-dbcp和commons-pool版本要配套DBCP 1.4对应commons-pool 1.6别混搭否则运行期报ClassNotFoundException的概率极高。2.3 订单与用户管理的表结构设计数据库脚本是这个资源的灵魂没有它代码再完整也跑不起来。按照系统功能反推MySQL里至少有这样几张表user表用户和管理员、menu表菜品、orders表订单、order_item表订单明细、message表留言或公告。其中orders表和order_item表是典型的一对多关系设计orders存一笔订单的主信息包括用户ID、下单时间、总金额、支付状态order_item存具体点了哪些菜、数量多少、当时的价格快照。这里必须强调一个细节订单明细要冗余一份菜品名称和价格不能只存menu_id。理由是菜品价格和管理员可能会改如果order_item只存外键用户查历史订单时看到的价格就是当前菜单价数据就错了。这是很多JSP课设系统做得不专业的地方而这套资源在订单字段设计上是考虑到了这一点的。修改用户配送地址功能对应的是user表里的address字段每次下单时从user表带出默认地址这个设计简单但能保证“修改配送地址”的功能确实有地方落地。3. 把核心流程拆开看注册登录、菜品管理、购物车下怎么串起来3.1 注册与登录UserUpdateServlet和PersonDAOImpl的分工用户模块是整套系统的入口从摘要看功能清单包括用户注册、用户登录控制、用户退出控制、修改用户个人信息全部走的是Servlet接收请求、调用DAO访问数据库、再转发到JSP的经典链路。具体拆解一下注册流程用户在register.jsp填写用户名、密码、手机号、配送地址表单提交到UserUpdateServletServlet从request里取出参数后先校验两次密码是否一致再调用UserInfoDAOImpl的insert方法把数据写入user表最后重定向到登录页面。// UserUpdateServlet核心逻辑注册和更新用户共用 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(utf-8); String action request.getParameter(action); UserInfoDAOImpl userDao new UserInfoDAOImpl(); if (register.equals(action)) { String username request.getParameter(username); String password request.getParameter(password); String phone request.getParameter(phone); String address request.getParameter(address); User user new User(); user.setUsername(username); user.setPassword(password); user.setPhone(phone); user.setAddress(address); boolean flag userDao.addUser(user); if (flag) { response.sendRedirect(login.jsp); // 注册成功去登录页 } else { request.setAttribute(msg, 用户名已存在); request.getRequestDispatcher(register.jsp).forward(request, response); } } }逻辑说明这段代码里有几个课程设计高频考点。第一是request.setCharacterEncoding(utf-8)这行不写POST提交的中文大概率乱码后面避坑部分还会专门说。第二是action参数的用法一个UserUpdateServlet同时处理注册和更新两种请求靠action字段区分这是Servlet一个类写多个业务方法的典型变通方案。第三是sendRedirect和forward的选择注册成功后用重定向避免刷新页面重复提交表单注册失败用forward把错误信息带回页面且保留表单数据这个细节答辩时可以说出点名堂。常见做法是登录校验逻辑放在PersonDAOImpl里查user表比对用户名密码同时把用户的type字段也查出来管理员和用户登录后进入完全不同的首页。3.2 菜品管理与菜单展示AddMenuServlet和MenuDAOImpl的增删改查菜品管理是后台管理端的核心功能包括添加菜谱、删除菜品、修改菜品信息、添加推荐菜品、删除推荐菜品。从类文件名看AddMenuServlet承担的不仅是添加而是菜品相关操作的统一入口。菜品管理界面提交表单后AddMenuServlet收到请求根据action参数区分add、update、delete、recommend四种操作。// MenuDAOImpl中推荐的批量推荐方法 public boolean setRecommend(int menuId, int recommend) { String sql UPDATE menu SET recommend ? WHERE id ?; try (Connection conn DbcpConnectionPool.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, recommend); ps.setInt(2, menuId); return ps.executeUpdate() 0; } catch (SQLException e) { e.printStackTrace(); return false; } }代码说明这套系统里DAO层全部使用PreparedStatement而不是Statement这一点要给到明确认可。虽然底层的SQL注入风险评委未必真的拿sqlmap去测但写SQL习惯必须从一开始就正确。PreparedStatement的?占位符有两个好处第一是避免拼接字符串引发的SQL注入比如用户在输入框写; DROP TABLE menu;--这种内容时不会被直接拼接进SQL第二是SQL预编译缓存在MySQL服务端同一句SQL反复执行时性能更好。菜品图片的处理在菜谱管理里是个麻烦点摘要里没有细说但从menu表的img字段存储路径的设计可以判断是文件上传方案。常见做法是两种一是用commons-fileupload包做文件上传到本地目录二是简单粗暴地在JSP里填一个图片URL地址存到数据库。第二种方案在课设验收里更容易出问题因为图片URL校验麻烦建议老老实实做文件上传。另外修改菜品信息功能中回显是个容易被忽略的环节点击编辑按钮后要先把菜品id传到后台查数据再跳转到编辑页面并且把原数据填回表单这步漏了画面就很难看。3.3 订单支付与购物车OrdersDAOImpl里藏着事务订单模块对应的功能是删除购物车订单、下单信息、订单支付这两个功能拆开放到OrdersDAOImpl里面。购物车这套资源没有单独建购物车表而是直接用orders表里加一个状态字段来区分“购物车中”“已提交未支付”“已支付”下单操作就是把这个状态从0改成1。// 模拟支付事务的try-catch结构 public boolean payForOrder(int orderId) { Connection conn null; PreparedStatement ps1 null; PreparedStatement ps2 null; try { conn DbcpConnectionPool.getConnection(); conn.setAutoCommit(false); // 关键关闭自动提交 ps1 conn.prepareStatement(UPDATE orders SET status 2 WHERE id ?); ps1.setInt(1, orderId); ps1.executeUpdate(); ps2 conn.prepareStatement(UPDATE user SET balance balance - ? WHERE id ?); ps2.setDouble(1, 100.0); ps2.setInt(2, 1); ps2.executeUpdate(); conn.commit(); // 全部成功才提交 return true; } catch (SQLException e) { try { conn.rollback(); } // 任何一个失败都回滚 catch (SQLException ex) { ex.printStackTrace(); } return false; } finally { if (conn ! null) { conn.close(); } } }代码说明这段模拟了支付时更新订单状态、扣减用户余额两个操作必须在一个事务里。如果不关自动提交第一个SQL成功、第二个SQL抛异常订单显示已支付但用户余额没扣系统的钱就乱了。conn.setAutoCommit(false)之后commit和rollback的控制权就到代码手里了。注意try-with-resources在这里不适用因为要手动控制conn的提交时机所以用了传统的finally块来关闭连接。这套资源在支付这个点上如果确实实现了类似的事务控制那课程设计的档次一下就上来了查订单列表、更新订单、删除订单、支付订单全都对应到OrdersDAOImpl的各个方法里分层合理。最怕看到的是有人把SQL写到JSP的scriptlet里那答辩时被连环追问代码规范撑不了两个问题。4. 从下载到浏览器跑通JDK、Tomcat、MySQL5.7的环境搭建与部署核查4.1 环境版本怎么选为什么推荐Tomcat 8.5配JDK 1.8部署JSP项目第一个门槛就是环境。这套资源是基于JSPServletMySQL的经典组合版本选错会直接导致项目起不来。结合MySQL相关技术背景参考如下版本组合最稳妥组件推荐版本说明JDK1.88u201以上最成熟稳定兼容所有JSP教程Tomcat8.5.x支持Servlet 3.1满足JSP 2.3规范Eclipse IDE2020-06及以上内置Tomcat插件部署更省事MySQL5.7.x课程设计主流版本教程最多JDBC驱动mysql-connector-java 5.1.49配MySQL5.7最稳别用8.x驱动DBCPcommons-dbcp 1.4 commons-pool 1.6和JDK1.8兼容性好强调一下MySQL 5.7的安装现在MySQL官网已经很难直接找到5.7的下载入口很多人的安装教程也是在讲8.0。要知道MySQL安装这个环节本身就能让不少人翻车5.7安装时的端口占用、字符集选utf8mb4、服务启动失败、Root密码安全策略每一个坑都踩一遍。网上关于MySQL 5.7.44安装过程详细的内容很多核心记住安装时选Server only、端口保持3306、字符集手动改成utf8、设置root密码后别忘记勾选“允许远程连接”和“把MySQL加入系统服务”。缺点是即使这样MySQL服务能不能起来还是有点玄学尤其Windows服务里显示“本地计算机上的MySQL服务启动后停止”大概率是my.ini配置问题删掉my.ini重装并不丢人这是血泪经验。JDK务必用1.8因为这套项目的编译级别几乎都是1.8写的用JDK 11以上跑Tomcat 8.5虽然也能动但会遇到”IllegalAccessError“之类的诡异报错不值得为升级折腾。4.2 Eclipse导入项目与配置Tomcat实际开发中把别人给的工程导入自己Eclipse需要经过几个步骤注意顺序。如果你的资源包里如果只有.class文件而没有.java源码需要先反编译但正规流传的课程设计资源都会带源码和SQL脚本以源码包为准继续。具体部署流程分为几步。第一步在Eclipse里新建项目时选择Dynamic Web Project项目名随意但要记住因为后续导入源码时要对应上。第二步找到你下载的文件包里的src文件夹和WebContent文件夹——有的叫WebRoot用Eclipse的Import功能把源码复制到刚建项目的对应目录里操作是用Import→File System把src里的java文件拷贝进src目录把WebContent下的内容拷到WebContent或src/main/webapp目录JSP页面文件一般叫login.jsp、register.jsp、index.jsp等直接放在WebContent根目录下。第三步右键项目选Build Path→Configure Build Path→Libraries→Add JARs把WEB-INF/lib下的mysql-connector-java.jar、commons-dbcp.jar、commons-pool.jar、jstl.jar全部加进去。第四步配置TomcatWindow→Preferences→Server→Runtime Environments添加你刚解压的Tomcat目录。Tomcat启动要在Servers视图里右键add然后选择你的Tomcat版本把项目Add All到Server配置里。这一步常见的坑是Servers面板里的catalina目录选错导致部署失败而且控制台报错信息非常隐晦。在Server配置里有一个“Use Tomcat installation”选项默认是使用工作区的副本建议改成使用Tomcat安装目录这样做的好处是后续改server.xml、web.xml直接改真身否则每次启动都用副本你改了等于白改。4.3 导入SQL脚本、修改连接配置、启动验证SQL脚本通常在资源包里叫order.sql或db.sql。用Navicat或MySQL命令行直接source导入即可。导入完成后打开src目录下的db.properties或JDBC工具类把数据库连接三个参数改成本地的值。修改的核心是数据库名、用户名、密码要和本机一致URL里的localhost:3306不用动字符集参数保持utf8不要删。文件配置完成后在Eclipse里右键项目名选择Run As → Run on Server等Tomcat启动日志出现以下内容就说明部署成功INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory浏览器输入http://localhost:8080/项目名/看到登录页面说明环境已通。这里需要注意JSP页面上传后第一次访问会经历编译成Servlet的过程所以首次加载稍慢是正常的。如果你改过JSP内容在Tomcat运行时页面不会自动更新常见做法是在JSP页面里让加载完后刷新一次逻辑其实就是加response头控制缓存更简单的做法是在项目右键Clean清理一下再重启Tomcat。Tomcat对JSP修改的检测机制是检查文件时间戳有的操作系统时间不同步就检测不到所以上课时课程设计调试阶段最常做的就是Clean和重启Tomcat。5. 避坑从部署到答辩JSPMySQL开发最容易翻车的八个位置这一章把整套资源实际运行中最常出现的问题整理成排查清单每一条都是真实项目里反复出现过的按“现象、原因、解决”三段式记录。这里的排查思路对所有JSPMySQL项目通用不只针对这一份。5.1 MySQL连接报SSL错误现象项目启动时后台报WARN: Establishing SSL connection without servers identity verification is not recommended老一点的驱动直接报Communications link failure。原因MySQL 5.7默认开启了SSL连接而JDBC驱动URL没指定useSSL驱动版本又不支持自动协商。解决在连接URL末尾加useSSLfalseserverTimezoneAsia/Shanghai只要服务器和驱动都是自己人的环境SSL不开完全没有影响还能免去证书配置的麻烦。有的做法是再加characterEncodingutf8乱码问题也一并解决。5.2 JSP页面中文乱码的三处叠加现象页面上所有中文都变成问号或乱码。原因这是三层编码不一致导致的JSP页面本身的pageEncoding没写或写错Servlet接收参数没指定request.setCharacterEncoding数据库连接URL没指定characterEncoding。这三层必须全部统一为UTF-8缺一不可。解决第一JSP文件头必须完整写% page languagejava contentTypetext/html; charsetUTF-8 pageEncodingUTF-8%。第二Servlet里有接收参数的地方在doPost第一行加request.setCharacterEncoding(utf-8)。第三连接URL的characterEncodingutf8一定要带三个都改完再重启Tomcat测试截至目前多数乱码问题就都解决了。5.3 数据库密码带特殊字符导致连接失败现象db.properties文件里密码明明是对的启动却报Access denied for user rootlocalhost。原因属性文件里password123#abc这种写法#会被当成注释起始符后面的内容就全被截断。解决第一种改数据库密码为纯字母数字第二种在db.properties里对特殊字符做转义比如#写成\#但properties转义规则各版本有差异并不完全统一。5.4 外键关联导致删除菜品失败现象后台删除一个菜品时SQL抛异常提示外键约束失败或者明明没建外键也没约束但删除菜品后订单里显示出了空数据。原因是orders表逻辑关联了menu表但没有真正建物理外键删除菜品时有脏数据残留。这种问题在课设系统里很常见。解决如果数据库建立了物理外键删除顺序必须先删子表再删主表如果没建物理外键需要在删除菜品前先查询一下订单明细表把关联数据一并处理保证数据完整性。5.5 登录状态失效刷新后直接跳回登录页现象登录成功进入首页刷新一次就回到登录页或者直接访问某页面就被拦截。原因没有正确配置Session或者Session失效时间过短。解决登录成功后将用户信息放入Sessionsession.setAttribute(user, user)同时设置Session最大存活时间Tomcat默认30分钟课设够用。另外有个容易忽略的配置点Eclipse里Run On Server启动时如果server.xml里改过Context reloadablefalse有时候会导致Session丢失改成reloadablefalse可以避免自动重载对Session的干扰。5.6 每次重启Tomcat后图片路径失效现象菜品图片当初默认上传到了user.home目录或临时目录重启Tomcat之后图片就显示不出来。原因图片没有存在Web应用的部署目录下Tomcat重启后临时文件被清理。解决图片上传路径不要用相对路径要动态获取项目部署的绝对路径同时把上传目录配置在项目目录之外路径在代码里做成配置项Tomcat重启不影响。5.7 登录验证用Statement导致SQL注入风险现象用户名框输入 or 11 --就能直接登录系统。原因老版本课设代码里密码比对用字符串拼接SQL比如String sql SELECT * FROM user WHERE username username AND password password 这个SQL在输入特定构造时可以被绕过。解决这套资源使用PreparedStatement本身就是为了防这一点代码里运行时一定确认用的是ps.setString(1, username)而不是字符串拼接。如果检查发现还有Statement就按这个思路全局替换。5.8 连接池耗尽导致系统假死现象演示时连续操作几次后页面卡死后台报Connection is not available, request timed out after 30000ms。原因DAO里获取连接后没有在finally块里释放连接池里的连接被耗尽。解决检查每个DAO方法的finally块是否都有conn.close()特别注意写事务的代码要把关闭放到finally里不能用try-with-resources就手动close。6. 进阶把课设系统从“能跑”改成“能看”登录拦截器与日志埋点如果已经把这套系统跑通并准备答辩下一步值得做两个低成本但高收益的改进。第一个是补一个登录拦截器Filter把“用户登录控制”从Servlet里解放出来。现在系统的登录校验逻辑很大概率是在每个JSP页面的scriptlet里判断session是否为空这样功能上不算错但代码风格和可维护性被老师看到会被扣分。第二个是打印SQL执行日志这能让你的答辩更有说服力。登录拦截器的建议写法新建一个Filter类在web.xml里配置映射规则只拦截需要登录才能访问的页面。建议Java代码实现思路如下public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req (HttpServletRequest) request; HttpServletResponse resp (HttpServletResponse) response; HttpSession session req.getSession(false); // 这里是放行路径一般放行登录页、注册页、静态资源 String uri req.getRequestURI(); if (/login.jsp.equals(uri) || /register.jsp.equals(uri) || uri.endsWith(.css) || uri.endsWith(.js) || uri.endsWith(.jpg) || uri.endsWith(.png)) { chain.doFilter(request, response); return; } if (session ! null session.getAttribute(user) ! null) { chain.doFilter(request, response); } else { resp.sendRedirect(login.jsp); } }说明一下这段的要点req.getSession(false)中参数false非常关键如果用户未登录这里不会自动创建新Session避免无效Session堆积每次请求都做“uri判断session判断”两件事能挡住未登录用户访问内部页面。有些课设系统靠JSP顶部一段脚本判断session是否为null那段脚本在用户未登录时虽然能跳转登录页但也可能因为逻辑顺序问题把登录页本身也拦截掉在Filter里不存在这种问题。日志埋点更具体地说是为订单支付流程加入MySQL事务日志支付前记录“开始支付”、扣款后记录“扣款完成”、commit后记录“事务已提交”用logger输出到控制台同时打印SQL执行时间。这种做法有两个直接的好处。第一答辩演示时出现问题能立刻定位是SQL错误还是逻辑错误第二网上下载的课设系统在支付环节几乎都不打印日志你打印了面试官或老师会觉得你理解生产级系统的运行逻辑这个细节会让你的答辩更顺畅。数据层面还有一个值得动手的改动把订单金额从double改成decimal并加CHECK约束或是给user表加上注册时间字段这种改动虽然简单但会让你在讲数据库设计时更有底气。这些做完之后这套系统才算真正属于你了。从那以后我每次部署这种下载来的课设项目都会强制走一遍“环境版本核对→SQL脚本导入→连接参数检查→启动验证→日志确认”的流程再翻一遍源码看有没有Statement、有没有finally没关连接这几步通用的流程帮我在课程设计和毕设上少熬了不少夜希望帮到你。本文还有配套的精品资源点击获取