简介这套毕业设计管理系统采用 Java Web 技术面向即将做毕设的计算机专业学生和需要项目实战的 Java 学习者系统围绕选题、过程、答辩三个核心阶段为四种角色提供对应操作入口。学生可以查询可选课题、完成选题、上传开题报告与论文并查看评阅结果导师可以发布课题、审核选题、下发任务书、评阅论文并提交成绩院系管理员负责课题审核、时间设置、答辩分组与成绩发布系统管理员则实现平台初始化、权限分配及院系专业年级维护整体权限划分清晰、业务逻辑完整。资源包共含三个文件项目说明文档、数据库脚本和项目源码压缩包整体仅4.33MB结构紧凑。数据库脚本可直接导入 MySQL便于快速建立后台数据环境源码基于 JSP、Servlet、JDBC 编写配合 Eclipse 和 Tomcat 即可运行。该资源已获得 10191 人学习下载适合作为毕业设计项目直接使用也可作为在校学生理解毕业设计管理流程的实战参考。1. 毕业设计管理系统是什么一个人的毕设一群人的进度协同毕业设计管理系统属于典型的JavaWeb管理类项目它把毕业设计里“选题、开题、中期、答辩、成绩”全流程搬到线上学生、教师、管理员三个角色在同一套系统里协同。你拿到的项目源码和数据库脚本是一套完整可跑的闭环源码负责页面交互和业务逻辑数据库脚本负责把选题记录、评分数据、角色权限这些内容落库两者对上才能让系统在浏览器里真正转起来。市面上这个方向的实现很多但核心套路一致先有数据库设计和权限模型再写CRUD和流程状态流转。如果你正在选毕业设计方向或者想借一个管理类项目把SSM框架串起来这套系统是很合适的载体。接下来我按技术选型、数据库设计、本地部署、核心模块和常见坑的顺序把整个思路一次讲透让你能跑起来也能在答辩时把每个设计决策讲清楚。2. JavaWeb技术选型与数据库设计SSM框架为什么还是主流选择2.1 技术栈对比SSM 与 Spring Boot拿到源码后大家第一句话往往问“是不是Spring Boot”。这确实是个绕不开的话题。市面上的毕业设计管理系统版本很多经典版用SSM新一点的上Spring Boot。SSM是Spring加SpringMVC加MyBatis三件套Spring管BeanSpringMVC管请求路由MyBatis管数据库访问。Spring Boot则把配置进一步自动化内嵌服务器打一个JAR就能跑。SSM的优势是能清楚看到Bean在哪里注册、事务在哪里切、SQL映射文件在哪里写对学习阶段其实更友好。对比项SSMSpring Boot配置方式XML为主注解为辅起步依赖加自动配置分层边界包结构加XML划分职责同样可分层但隐含默认运行方式外置Tomcat打WAR包内嵌Tomcat打JAR包上手难度稍高适合理解原理较低但难讲清原理我见过用Spring Boot版本去答辩的同学被问到“Spring MVC处理流程”时当场冷场因为Boot把太多细节收进去了。用SSM只要答辩前对着三层架构走一遍请求链路基本就能讲明白。所以我一般建议既然是毕业设计选SSM更稳。不是说Boot不能选如果目标是快速出系统且不纠结原理展示Boot能省很多事。关键在于源码里的框架要和答辩说辞对齐别拿着Boot的源码非说是SSM。2.2 数据库表设计从用户表到答辩评分表这个系统能支撑完整流程靠的是一组关联紧密的关系表。核心表至少有这些用户表、学生表、教师表、题目表、选题记录表、进度表、评分表、答辩分组表。很多人拿到数据库脚本后不看表结构直接执行了就往下一步走这是很危险的。后面你扩展功能、排查数据问题时都依赖这套表结构的理解。先看最核心的用户表。多数做法是用户表里放一个role字段区分三种角色再各自扩展学生表和教师表存角色专属信息。好处是登录时一次查询就能拿到身份。下面是一个典型用户表CREATE TABLE t_user ( id INT NOT NULL AUTO_INCREMENT COMMENT 主键, username VARCHAR(50) NOT NULL COMMENT 登录账号, password VARCHAR(100) NOT NULL COMMENT 密码MD5加密后存储, real_name VARCHAR(50) NOT NULL COMMENT 真实姓名, role TINYINT NOT NULL DEFAULT 3 COMMENT 角色1管理员 2教师 3学生, status TINYINT DEFAULT 1 COMMENT 状态1启用 0禁用, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT系统用户表;逻辑说明主键自增是常见做法username加唯一索引保证登录账号不重复。密码不能明文存脚本里一般会存MD5的32位十六进制字符串部分版本用Base64甚至明文——如果看到明文答辩前要改成MD5这是评审老师容易追问的点。role用TINYINT而不是字符串省空间、比对快查询时拿数字去匹配常量即可。参数说明utf8mb4是首选字符集存中文和特殊符号不会乱码utf8mb4_general_ci对中文友好。如果你看到的脚本是latin1或gbk导入前统一改成utf8mb4否则后续中文乱码的概率极高。再多看一张选题记录表它是业务的核心枢纽学生选谁出的题、选了哪个题目、审核到哪一步都在这条记录里。CREATE TABLE t_selection ( id INT NOT NULL AUTO_INCREMENT COMMENT 主键, topic_id INT NOT NULL COMMENT 关联题目表主键, student_id INT NOT NULL COMMENT 关联学生表主键, status TINYINT DEFAULT 0 COMMENT 状态0待审核 1通过 2驳回, apply_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 申请时间, audit_time DATETIME DEFAULT NULL COMMENT 审核时间, audit_comment VARCHAR(500) DEFAULT NULL COMMENT 审核意见, PRIMARY KEY (id), KEY idx_topic (topic_id), KEY idx_student (student_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT选题记录表;逻辑说明topic_id和student_id是外键语义字段但很多脚本不建物理外键只建普通索引。这是刻意为之——外键约束在导入时容易造成顺序问题在低并发场景不建外键也不会有性能瓶颈。不要在答辩时把这事说成缺陷而是说成“在数据完整性和写入灵活性之间做了权衡”。状态字段用TINYINT表示0/1/2程序里通过常量类做映射前端展示时再转中文。评分表也是关键。有的设计是成绩分成指导老师评分和答辩评分最后按权重合并比如final_score teacher_score * 0.4 defense_score * 0.6。常见做法是只存明细分总成绩实时计算这样改小分时总分不用手动同步减少数据不一致的坑。2.3 项目结构说明与在IDE中导入拿到源码后先别急着执行脚本把项目结构看一遍。这个方向的工程通常是Maven单模块结构依赖管理在pom.xml里。目录大概长这样src/main/java ├── cn/example/graduation │ ├── controller // 控制层接收请求返回视图 │ ├── service // 业务逻辑层事务边界放这层 │ ├── dao // 数据访问层Mapper接口 │ ├── entity // 实体类对应表结构 │ ├── interceptor // 登录拦截器等 │ └── utils // 工具类 src/main/resources ├── mappers // MyBatis的SQL映射XML ├── spring // Spring配置文件 ├── jdbc.properties └── mybatis-config.xml src/main/webapp ├── WEB-INF │ ├── views // JSP页面 │ └── web.xml逻辑说明controller包只负责接收参数、调服务、返回视图业务判断必须放service层dao层放Mapper接口XML里写SQL。这样后续改功能时只动service和对应mapper不需要碰页面。有些版本没有service层controller直接调dao这种结构风险很大多个功能共用同一查询逻辑时改动会牵连一片。在IDE里导入时按Maven工程导入等依赖拉完。如果pom.xml里配了Tomcat插件直接用插件启动即可如果没有就打WAR包放外置Tomcat的webapps下。引入工程时看到一堆报错先别慌十有八九是Maven仓库源太慢或依赖版本冲突下面细说。3. 本地跑通源码JDK/Tomcat/MySQL环境搭建与数据库脚本导入3.1 环境版本匹配JDK/Tomcat/MySQL 对照跑这套系统最常见的失败原因不是代码不对而是环境版本不对。我建议按下面这个经典组合先在本地跑通组件推荐版本理由JDK1.8SSM配置兼容性最好Tomcat 8直接支持Tomcat8.5JavaWeb部署最常见的容器版本MySQL5.7或8.05.7最稳8.0需同步升级驱动Maven3.6管理依赖拉包稳定先说JDK。SSM项目用JDK 8基本零问题。如果你装了JDK 17Tomcat 8.5可能起不来即使起来旧版asm或cglib也会在反射时抛异常。有人用JDK 11跑一个Spring 4的毕设源码启动不报错一进登录页就抛ClassNotFoundException查了半天是ASM库不兼容。建议不要在环境上硬撑直接切回JDK 8这套代码跑通率最高。MySQL版本方面如果脚本是5.x导出格式直接拿到MySQL 8.0里执行多数也可以但要注意驱动版本。MySQL 8.0之后驱动类从com.mysql.jdbc.Driver改为com.mysql.cj.jdbc.Driver连接串要加serverTimezoneAsia/Shanghai否则会回报“Server returns invalid timezone”。如果脚本里的驱动JAR还是老版本且你用的是MySQL 8.0把驱动升级到8.x再运行就是常见解法。Maven方面拉依赖时如果网络慢在settings.xml里配置国内镜像源。这一步很多人忽略拉包拉到一半失败导致整个工程一片红叉。换镜像后执行mvn clean compile能过就说明依赖没问题。3.2 执行数据库脚本从SQL文件到可联调的表结构数据库脚本通常是.sql文件导入前先在命令行里建库。用可视化工具导入虽然直观但命令行能避免很多因字符集不一致带来的隐藏问题。操作如下mysql -u root -p进入MySQL命令行后执行-- 创建数据库并指定字符集 CREATE DATABASE graduate_manage DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 切换到该库 USE graduate_manage; -- 导入脚本路径换成你自己的 SOURCE /Users/你的路径/graduate_manage.sql;逻辑说明先建库再导入避免脚本里没有CREATE DATABASE语句时报“No database selected”。SOURCE是MySQL命令行导入命令比在可视化工具里直接跑整个SQL更稳定脚本较大时不会中途卡在某个语句。有些工具导入时遇到注释里的中文会报错命令行反而不会。导入完成后要确认有没有导对。执行以下验证USE graduate_manage; SHOW TABLES; SELECT COUNT(*) FROM t_user;如果SHOW TABLES出来的表数量和脚本里的CREATE TABLE语句数不一致说明导入过程有跳过重新执行一次脚本或检查权限。能在t_user表里查到默认管理员账号说明基础数据也进去了。注意脚本里如果只有表结构没有初始数据你需要先手动往用户表插一条管理员记录否则系统没有账号能登录这是新手跑源码时常被卡住的地方。3.3 配置数据源并在Tomcat中启动数据库导入完成后去工程里找数据库连接配置文件通常是jdbc.properties或db.properties。打开会看到类似这些配置项jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://127.0.0.1:3306/graduate_manage?useUnicodetruecharacterEncodingutf-8 jdbc.usernameroot jdbc.password123456参数说明jdbc.url里的127.0.0.1是本地地址3306是MySQL默认端口graduate_manage是刚建的库名。如果数据库端口改过这里必须同步改。characterEncodingutf-8保证应用往MySQL写中文时编码正确如果MySQL是8.0要增加serverTimezoneAsia/Shanghai并把驱动类换成com.mysql.cj.jdbc.Driver。用户名密码改成你本机实际账号别拿脚本默认值硬跑。启动方式分两种。一种是在IDE里配置Tomcat ServerDebug模式启动适合本地改代码调试另一种是打WAR包丢到Tomcat的webapps目录。Debug模式每次改代码自动重启效率高一点但启动前要确认Server的Deploy行为正确。启动后在浏览器访问http://localhost:8080/项目名/看到跳转到登录页说明项目起来了。如果404先看控制台有没有部署错误如果页面起来了但样式全丢多半是静态资源路径问题下面避坑章节展开。4. 核心业务模块拆解登录权限、选题流程与答辩评分4.1 登录与权限三个角色的路由设计系统跑起来之后最核心的其实是权限模型。学生、教师、管理员三者的入口不同能操作的业务不同。实现方式通常是登录成功后把用户ID和角色写进Session再用拦截器统一校验每个请求是否放行。下面是一个通用拦截器骨架也是这类系统的标配public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object user request.getSession().getAttribute(loginUser); if (user null) { // 未登录重定向到登录页 String contextPath request.getContextPath(); response.sendRedirect(contextPath /login); return false; } String uri request.getRequestURI(); if (uri.contains(/admin/) !1.equals( String.valueOf(((User) user).getRole()))) { response.sendRedirect(contextPath /403); return false; } return true; } }代码逻辑说明拦截器核心是两个判断。先判断Session里有没有loginUser没有就送回登录页再通过URL片段识别管理员专属路径把非管理员拦下。这里用传统的路径前缀硬匹配是因为部分旧版本Spring MVC对注解拦截的支持不稳定硬匹配更稳妥。答辩时你要能讲清楚拦截器何时生效、为什么return false时要重定向。注册拦截器要在Spring MVC配置里声明同时排除登录页、注册接口和静态资源路径mvc:interceptors mvc:interceptor mvc:mapping path/**/ mvc:exclude-mapping path/login/ mvc:exclude-mapping path/register/ mvc:exclude-mapping path/static/**/ bean classcn.example.graduation.interceptor.LoginInterceptor/ /mvc:interceptor /mvc:interceptors参数说明path/**表示拦截全部请求exclude-mapping放行登录页、注册接口和静态资源。一个常见的翻车点是有人把静态资源也拦了结果登录页能打开但CSS、JS全加载不出来页面一片裸奔。/static/**的写法对应你的静态资源目录如果它放在webapp/static写法就是正确放在别处需要同步改。登录成功后session.setAttribute(loginUser, user)的key要和拦截器里取的一致别一个用user一个用loginUser。4.2 选题申报与审批流程选题流程在业务上是状态机教师发布题目学生发起申请状态为待审核教师通过后状态为已通过学生不能再改选驳回则允许学生重新申请。这套流转在代码里体现为service层的一段核心逻辑。以“学生申请选某题”为例public boolean applyTopic(Integer studentId, Integer topicId) { // 题目是否存在 Topic topic topicDao.selectByPrimaryKey(topicId); if (topic null) { throw new BusinessException(题目不存在); } // 该题目是否还有名额 if (topic.getSelectedCount() topic.getMaxCount()) { throw new BusinessException(该题目已选满); } // 学生是否已有有效选题 Selection old selectionDao.selectByStudentId(studentId); if (old ! null old.getStatus() 1) { throw new BusinessException(已有进行中的选题不能再申报); } Selection selection new Selection(); selection.setStudentId(studentId); selection.setTopicId(topicId); selection.setStatus(0); // 0待审核 1通过 2驳回 selection.setApplyTime(new Date()); int rows selectionDao.insert(selection); // 题目表已选人数加一 if (rows 0) { topicDao.increaseCount(topicId); } return rows 0; }代码逻辑要点是三重校验题目存在性、名额、学生是否已有生效选题顺序不能乱。有两个容易踩坑的地方一是名额校验和加一之间没有事务保护并发场景下两人同时看到名额剩1会插出两条记录。解决办法是给方法加Transactional并在更新名额时用条件更新。二是业务异常用自定义异常抛而不是返回false这样上层能拿到中文提示不用在Controller里做一堆数据判断。审核流程代码差异不大教师点“通过”或“驳回”时改状态数字并写入审核时间。需要注意题目名额要跟随审核结果联动变化。比如审核通过时学生其他待审核状态的选题记录要批量置为失效这部分很多版本会漏。答辩时被问到可以答“通过update t_selection set status2 where student_id? and status0清理其余待审核记录”。4.3 答辩评分与成绩汇总评分模块常见设计是指导教师评一次给出质量和规范性分答辩小组再评一次给出答辩表现分最终成绩按权重合并。成绩表典型结构如下CREATE TABLE t_score ( id INT NOT NULL AUTO_INCREMENT, selection_id INT NOT NULL COMMENT 选题记录ID, teacher_score DECIMAL(5,2) DEFAULT 0 COMMENT 指导老师评分, defense_score DECIMAL(5,2) DEFAULT 0 COMMENT 答辩评分, final_score DECIMAL(5,2) DEFAULT 0 COMMENT 综合成绩, remark VARCHAR(200) COMMENT 评语, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;逻辑说明DECIMAL(5,2)表示三位整数加两位小数适合百分制评分。性能上比FLOAT可靠FLOAT存小数有精度误差成绩场景不能忍。保存评分时final_score可以实时算final_score teacher_score * 0.4 defense_score * 0.6权重按业务调整展示时直接把算好的值查出来即可。成绩汇总一般按专业统计平均分、最高分、最低分。这步用MyBatis写统计查询在XML里拼SQLselect idselectScoreStatsByMajor resultTypemap SELECT su.major_id AS majorId, COUNT(s.id) AS studentCount, ROUND(AVG(sc.final_score), 2) AS avgScore, MAX(sc.final_score) AS maxScore, MIN(sc.final_score) AS minScore FROM t_selection s JOIN t_student su ON s.student_id su.id JOIN t_score sc ON s.id sc.selection_id WHERE s.status 1 GROUP BY su.major_id /select如果发现resultTypemap查出来的键是下划线风格或大写常见做法是写别名的时候直接改成Java风格属性名避免在Controller层再做一层转换。统计时WHERE s.status1很关键过滤掉未选题成功的学生否则成绩汇总会把还没走完流程的人兜进来拉低平均分。5. 避坑指南从导入到部署最常见的5个问题这套系统真正花时间的往往不在常规跑通而在下面这些细节上。5.1 数据库连接失败时区、编码、驱动版本现象项目启动后点登录页面直接500控制台报SQLException: Cannot create PoolableConnectionFactory或Connection refused。原因最常见是三类。MySQL 8.0驱动差异老连接串在新驱动下报The server time zone value is unrecognized字符集配置不对连上库后取中文全是问号端口和账号不对比如本机MySQL端口改成3307配置文件还是3306。解决先用mysql -u root -p确认本机能登录再按驱动版本改连接串。MySQL 5.7用老驱动没问题MySQL 8.0把驱动JAR升到8.x并在URL上追加?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai。改完重启Tomcat再试。本地场景useSSL不用特意处理。5.2 页面乱码UTF-8全链路排查现象登录页能打开但页面上中文全变成问号或方块提交表单后后台存进去取出来也是乱码。原因乱码是链路问题。数据库字符集不是utf8mb4、JDBC连接串没带characterEncodingutf-8、JSP页面声明没写UTF-8、Spring的CharacterEncodingFilter没配这四环任一环掉链子最终显示就是乱的。解决逐个排查。第一查看页面源码开头的% page contentTypetext/html;charsetUTF-8 %这个必须放最前面。第二检查web.xml是否配置了CharacterEncodingFilterfilter filter-nameencodingFilter/filter-name filter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param /filter filter-mapping filter-nameencodingFilter/filter-name url-pattern/*/url-pattern /filter-mapping第三确认MySQL库和表的字符集统一为utf8mb4。如果表按latin1建的用ALTER TABLE t_user CONVERT TO CHARACTER SET utf8mb4整体转过来。按这个顺序查乱码基本能定位到具体哪一环。5.3 文件上传失败Tomcat临时目录与大小限制现象上传开题报告或论文附件时提示上传失败小文件能传稍大点的PDF必挂日志出现FileUploadException。原因最常见是SpringMVC配置里maxUploadSize设太小比如限制1MB另一个是部署到Linux后Tomcat用的临时目录被系统清理或权限不足上传中断连报错都不明显。解决调大文件大小限制。在Spring MVC配置中bean idmultipartResolver classorg.springframework.web.multipart.commons.CommonsMultipartResolver property namemaxUploadSize value104857600/ property namedefaultEncoding valueUTF-8/ /bean104857600是100MB的字节数。同时确认服务器Tomcat临时目录存在且可写。本地Windows基本不会遇到这个问题上线到Linux一传文件就翻车是很典型的部署坑。5.4 权限绕过拦截器放行与Session验证现象退出登录后复制之前的URL回车页面还能访问甚至管理员后台也拦不住。原因很多版本的路径设计没把权限校验做全。拦截器只校验是否登录不校验角色或者关键路径不在拦截范围Controller方法路径缩水了还有一种情况是重新部署后contextPath变了重定向不对但接口本身还能访问。解决在拦截器里把角色校验做强。如果源码里只判断登录没判断角色自己补一段Integer role Integer.valueOf(request.getSession().getAttribute(role).toString()); String uri request.getRequestURI(); if (uri.startsWith(request.getContextPath() /admin/) role ! 1) { response.sendRedirect(request.getContextPath() /403); return false; }同时检查登录成功后的跳转逻辑把角色写进Session。权限校验放后端不要依赖前端隐藏入口。这套设计是答辩高频问题值得认真看一遍源码。5.5 部署到服务器后无法访问端口、路径与防火墙现象本地跑得好好的打WAR包丢到Linux服务器Tomcat的webapps下IP换成服务器地址就打不开控制台也没明显报错。原因多数不是应用没起来而是网络层不通防火墙没放行8080云服务器安全组没开端口Tomcat实际占用了其他端口访问路径少写上下文路径。解决先开HTTP端口。以CentOS为例# 开放8080端口 firewall-cmd --zonepublic --add-port8080/tcp --permanent firewall-cmd --reload # 确认Tomcat在监听8080 ss -tlnp | grep 8080如果ss看不到8080先启动Tomcat确认没有报错。如果端口通了还是打不开去云平台安全组增加一条入方向规则允许TCP 8080从任意来源访问。用80端口时访问不带端口号但需要改Tomcat配置或做反向代理不建议在毕设阶段折腾。6. 进阶给毕设管理系统加一个“中期检查”模块主线跑通后想让系统更有区分度加一个“中期检查”模块很合适它在毕业设计流程里普遍存在加它属于顺理成章的加分项。先明确业务动作学生提交一段中期说明教师在线审核填意见管理员能看整体进度。实现分四步走。第一步加表。在数据库脚本里增加中期检查表CREATE TABLE t_midcheck ( id INT NOT NULL AUTO_INCREMENT, selection_id INT NOT NULL COMMENT 选题记录ID, commit_content TEXT COMMENT 学生中期说明, commit_time DATETIME DEFAULT CURRENT_TIMESTAMP, status TINYINT DEFAULT 0 COMMENT 0待检查 1通过 2退回, teacher_comment VARCHAR(500) COMMENT 教师意见, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;第二步新增实体类Midcheck.java、新增Mapper接口MidcheckDao和XML文件SQL写基本CRUD和按selection_id查最新一条。第三步service层新增MidcheckService查询学生是否有有效选题、校验是否已提交过、插入记录并把状态置为待检查。教师在操作时只改状态和评语。第四步Controller层加两个URL映射Controller RequestMapping(/midcheck) public class MidcheckController { Autowired private MidcheckService midcheckService; PostMapping(/submit) public String submit(RequestParam Integer selectionId, RequestParam String content) { midcheckService.submit(selectionId, content); return redirect:/student/midcheck/list; } PostMapping(/audit) public String audit(RequestParam Integer id, RequestParam Integer status, RequestParam String comment) { midcheckService.audit(id, status, comment); return redirect:/teacher/midcheck/list; } }代码说明submit和audit两个入口的路径前缀分别落在/student/**和/teacher/**这样权限拦截器能自动覆盖新功能不需要单独处理授权。JSP页面照着现有列表页样式写复用分页组件和CSS类即可。加完这个模块你还要完整走一遍流程学生提交中期报告教师端看到待办、审核学生端看到状态变化。这个闭环跑通答辩时展示的连贯性会好很多。做新功能最大的教训是别上来就写代码先把表和状态机理清想清楚状态变了哪些字段要联动更新再动手往往一次就能做对。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?