ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java+Vue在线招投标系统毕业设计:从部署到核心模块深度解析

Java+Vue在线招投标系统毕业设计:从部署到核心模块深度解析 如果你正在为计算机专业的毕业设计选题发愁想找一个既能体现技术栈完整性又能解决实际业务问题的项目那么“在线招投标系统”很可能就是你一直在找的那个“完美”选题。它不像一个简单的图书管理系统那样千篇一律也不像电商系统那样庞大到无从下手。更重要的是它背后涉及的业务逻辑、权限控制和数据一致性要求恰恰是面试官考察你工程化思维时最看重的点。很多人拿到一个“开源免费”的源码包第一反应是直接运行然后草草写个论文。但这样做的结果往往是系统跑起来了但一问三不知代码看懂了但不知道为什么要这样设计。这篇文章要解决的就是帮你从“能运行”到“真理解”。我们将基于一个典型的 Java Vue Spring Boot MySQL 技术栈的在线招投标系统不仅带你一步步部署运行更会深入拆解其核心模块的设计思路、技术选型背后的考量以及那些在真实开发中必然会遇到的“坑”。读完本文你将能清晰地回答一个招投标系统有哪些核心角色和业务流程前后端分离架构下权限如何精细控制高并发场景下的数据一致性问题如何解决以及如何将这个项目转化为你简历上的一个亮眼经历。1. 为什么“在线招投标系统”是毕业设计的黄金选题在众多毕业设计选题中“在线招投标系统”脱颖而出并非偶然。它完美地平衡了技术深度、业务复杂度和可实现性。首先业务场景真实且逻辑闭环。它不像“学生信息管理系统”那样只有简单的增删改查。一个完整的招投标流程包括招标方发布项目、投标方报名/提交标书、专家评审、中标公示等环节。这天然引入了状态机的概念例如项目状态草稿、发布中、投标中、评审中、已结束非常适合用设计模式如状态模式来优雅实现这能极大提升你代码的设计感。其次技术栈覆盖全面且主流。“Java Vue Spring Boot MySQL”几乎是当前企业级Web应用开发的“标准答案”。Spring Boot让你快速搭建后端服务Vue让你构建现代化的交互界面MySQL处理结构化数据。通过这个项目你可以实践前后端分离、RESTful API设计、JWT认证授权、MyBatis Plus数据操作等核心技能这些都是面试高频考点。再者能深入考察多个技术难点。权限控制RBAC系统涉及招标方、投标方、评审专家、系统管理员等多角色不同角色看到的数据和操作权限天差地别。如何设计一个清晰、可扩展的权限模型是核心挑战。数据一致性在开标截止时间如何确保所有投标文件被“冻结”且不可修改这涉及到事务和业务锁的运用。文件管理标书通常是PDF、Word等文件如何安全地上传、存储、预览和下载这引出了文件服务器如本地存储、FastDFS、OSS的知识点。安全性如何防止投标信息在评审前泄露如何防范SQL注入和XSS攻击这些安全考量能让你的项目脱颖而出。最后有丰富的扩展空间。基础版本完成后你可以根据兴趣和能力进行深化性能方向为项目列表、投标排名加入Redis缓存。微服务方向将用户服务、项目服务、文件服务拆分为独立微服务。高可用方向引入消息队列如RabbitMQ异步处理邮件通知、文件转换等耗时任务。因此选择这个项目你收获的不仅仅是一个能运行的代码包更是一套应对复杂业务系统的分析、设计与实现能力。2. 系统核心概念与业务流程拆解在动手写代码之前必须彻底理解业务。一个在线招投标系统核心是围绕“项目”或称为“标段”的生命周期展开的。2.1 核心角色与职责角色核心职责典型操作系统管理员系统基础维护用户管理、角色权限分配、系统参数配置、日志查看招标方发起并管理招标项目创建招标项目、发布公告、审核投标方资质、组织评审、确认中标结果投标方参与项目竞标浏览招标公告、报名参与、提交/修改投标文件、查看中标结果评审专家对投标文件进行评审接收评审任务、在线评阅标书、提交评分与评审意见2.2 核心业务流程状态流转这是系统的灵魂。一个项目的典型状态流转如下【招标方】创建项目 - 项目状态草稿 ↓ 填写详情发布 项目状态已发布招标中 ↓ 到达报名截止时间 项目状态报名截止 ↓ 【投标方】报名、提交标书 项目状态投标中 ↓ 到达投标截止时间 项目状态投标截止自动触发所有标书锁定 ↓ 【招标方】分配专家启动评审 项目状态评审中 ↓ 【评审专家】完成评分 项目状态评审完成 ↓ 【招标方】确认并公示中标结果 项目状态已结束已公示理解这个状态机是设计数据库表状态字段和业务逻辑的基础。例如在“投标截止”状态所有投标文件应设置为不可修改这需要在业务层进行校验。2.3 核心功能模块基于以上流程系统通常包含以下模块用户认证与权限模块登录、注册、JWT令牌管理、基于角色的菜单与按钮权限控制。招标项目管理模块项目的CRUD、状态管理、时间节点报名截止、投标截止设置。投标管理模块投标报名、投标文件上传/版本管理、投标保证金管理可选。评审管理模块专家库管理、评审任务分配、在线评审打分、评审汇总。通知公告模块系统消息、邮件/短信通知如项目发布、中标通知。文件管理模块标书、资质证明等文件的上传、存储、在线预览。数据统计与报表模块项目统计、投标分析等用于管理员驾驶舱。3. 技术栈选型与环境准备我们选择最主流、资料最丰富的技术组合确保项目的成功率和学习价值。3.1 后端技术栈 (Spring Boot)框架Spring Boot 2.7.x (稳定版)安全与认证Spring Security JWT (JSON Web Token)数据持久层MyBatis-Plus (极大简化CRUD操作)数据库MySQL 8.0依赖管理MavenAPI文档Knife4j (Swagger增强UI)其他工具Lombok, Hutool, Fastjson3.2 前端技术栈 (Vue 3)框架Vue 3 (Composition API)构建工具Vite (速度远快于Webpack)UI组件库Element Plus (适用于管理后台)路由Vue Router 4状态管理Pinia (Vuex的替代品更简洁)HTTP客户端Axios开发语言TypeScript (推荐提升代码健壮性)3.3 开发环境准备请确保你的电脑已安装以下软件并配置好环境变量。JDK版本 8 或 11 (推荐11长期支持版)。安装后执行java -version验证。java -version # 应输出类似openjdk version 11.0.xxMaven版本 3.6。安装后执行mvn -v验证。mvn -v # 应输出Maven版本信息Node.js版本 16 (推荐18 LTS)。安装后执行node -v和npm -v验证。node -v npm -vMySQL版本 5.7 (推荐8.0)。安装后创建数据库。-- 使用MySQL命令行或客户端如Navicat, Workbench CREATE DATABASE bidding_system CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;IDE后端IntelliJ IDEA (社区版或旗舰版) 或 Eclipse。前端Visual Studio Code (VSCode) 或 WebStorm。Git(可选但推荐)用于版本管理和获取开源代码。4. 项目初始化与数据库搭建假设你已经从一个可靠的来源如Gitee, GitHub获得了一个“在线招投标系统”的源码包。其目录结构通常如下bidding-system/ ├── bidding-backend/ # Spring Boot后端项目 │ ├── src/ │ ├── pom.xml │ └── ... ├── bidding-frontend/ # Vue前端项目 │ ├── src/ │ ├── package.json │ └── ... └── docs/ # 文档、SQL脚本等 └── db/ # 数据库脚本 ├── bidding_system.sql # 建表语句 └── data_init.sql # 初始数据用户、角色等4.1 数据库初始化找到docs/db/bidding_system.sql文件在MySQL中执行创建所有表结构。执行data_init.sql插入管理员账号、角色、菜单等基础数据。-- 示例查看初始化的管理员用户通常密码是加密的 SELECT username, password, role FROM sys_user;常见账号admin / admin123 (具体看脚本)4.2 后端项目配置与启动用IDEA打开bidding-backend文件夹。等待Maven自动下载依赖右下角进度条。修改配置文件src/main/resources/application.yml(或application.properties)。# application.yml 示例 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/bidding_system?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghai username: root # 改为你的MySQL用户名 password: 123456 # 改为你的MySQL密码 servlet: multipart: max-file-size: 50MB # 文件上传大小限制 max-request-size: 100MB # JWT配置 jwt: secret: your-secret-key-here-change-in-production # 生产环境务必修改 expire: 7200 # token过期时间(秒) # 日志级别 logging: level: com.yourcompany.bidding: debug找到主启动类通常名为XxxApplication.java运行它。// 文件路径bidding-backend/src/main/java/com/example/bidding/BiddingApplication.java SpringBootApplication MapperScan(com.example.bidding.mapper) // 扫描MyBatis Mapper接口 public class BiddingApplication { public static void main(String[] args) { SpringApplication.run(BiddingApplication.class, args); } }控制台输出Started BiddingApplication in x.xxx seconds即表示启动成功。默认端口可能是8080。4.3 前端项目配置与启动用VSCode打开bidding-frontend文件夹。在终端中进入项目根目录安装依赖。cd bidding-frontend npm install # 或使用淘宝镜像加速npm install --registryhttps://registry.npmmirror.com修改前端请求的后端API地址。配置文件通常是.env.development或vite.config.ts中的proxy设置。// .env.development 示例 VITE_APP_BASE_API /api// vite.config.ts 示例 - 配置代理解决跨域 import { defineConfig } from vite export default defineConfig({ server: { proxy: { /api: { target: http://localhost:8080, // 后端地址 changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ) } } } })启动开发服务器。npm run dev终端会输出本地访问地址如http://localhost:5173。用浏览器打开即可。5. 核心功能模块代码实现深度解析仅仅运行起来是不够的。我们来深入几个核心模块的代码理解其设计。5.1 基于Spring Security JWT的认证授权这是系统的安全大门。典型的实现流程如下登录用户提交用户名密码 - 后端校验 - 生成JWT令牌返回。鉴权前端将令牌存入localStorage或Cookie并在后续请求的Header中携带。授权后端通过过滤器解析令牌获取用户角色和权限判断能否访问当前API。关键代码示例JWT工具类// 文件路径bidding-backend/src/main/java/com/example/bidding/common/utils/JwtUtil.java Component public class JwtUtil { Value(${jwt.secret}) private String secret; Value(${jwt.expire}) private Long expire; // 生成Token public String generateToken(String username, String role) { MapString, Object claims new HashMap(); claims.put(username, username); claims.put(role, role); return Jwts.builder() .setClaims(claims) .setSubject(username) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() expire * 1000)) .signWith(SignatureAlgorithm.HS512, secret) .compact(); } // 解析Token public Claims parseToken(String token) { return Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); } // ... 其他验证方法 }关键代码示例Spring Security配置类核心// 文件路径bidding-backend/src/main/java/com/example/bidding/config/SecurityConfig.java Configuration EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { Autowired private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; Override protected void configure(HttpSecurity http) throws Exception { http // 关闭CSRF因为使用JWT无状态且前后端分离 .csrf().disable() // 允许跨域 .cors().and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests() // 登录接口、Swagger文档等放行 .antMatchers(/user/login, /doc.html, /webjars/**).permitAll() // 其他所有请求都需要认证 .anyRequest().authenticated().and() // 添加JWT过滤器 .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); } Bean public PasswordEncoder passwordEncoder() { // 密码加密器 return new BCryptPasswordEncoder(); } }5.2 招标项目状态机与业务逻辑实现项目状态流转是业务核心。我们可以在Service层实现状态校验。关键代码示例项目发布服务// 文件路径bidding-backend/src/main/java/com/example/bidding/service/impl/ProjectServiceImpl.java Service public class ProjectServiceImpl extends ServiceImplProjectMapper, Project implements ProjectService { Override Transactional(rollbackFor Exception.class) // 添加事务 public boolean publishProject(Long projectId) { Project project this.getById(projectId); if (project null) { throw new BusinessException(项目不存在); } // 状态校验只有“草稿”状态的项目才能发布 if (!ProjectStatus.DRAFT.equals(project.getStatus())) { throw new BusinessException(只有草稿状态的项目才能发布); } // 业务校验例如必须填写了预算、截止时间等必要信息 if (project.getBudget() null || project.getBidEndTime() null) { throw new BusinessException(项目信息不完整无法发布); } // 更新状态为“已发布”并设置发布时间 project.setStatus(ProjectStatus.PUBLISHED); project.setPublishTime(new Date()); boolean updated this.updateById(project); if (updated) { // 发布成功后可以触发其他操作如生成公告、发送通知等 // notificationService.sendPublishNotification(project); log.info(项目[{}]发布成功, projectId); } return updated; } // 其他状态变更方法报名截止、开始评审、结束等逻辑类似核心是状态校验和原子操作。 }5.3 投标文件上传与存储策略文件上传是常见功能需考虑安全、重名和存储路径。关键代码示例文件上传控制器// 文件路径bidding-backend/src/main/java/com/example/bidding/controller/FileController.java RestController RequestMapping(/file) public class FileController { Value(${file.upload.path}) // 从配置读取存储路径如D:/upload/ private String uploadPath; PostMapping(/upload) public ResultString uploadFile(RequestParam(file) MultipartFile file, RequestParam(bizType) String bizType) { if (file.isEmpty()) { return Result.error(文件不能为空); } // 1. 校验文件类型白名单 String originalFilename file.getOriginalFilename(); String suffix originalFilename.substring(originalFilename.lastIndexOf(.)); ListString allowedSuffix Arrays.asList(.pdf, .doc, .docx, .zip); if (!allowedSuffix.contains(suffix.toLowerCase())) { return Result.error(不支持的文件类型); } // 2. 生成唯一文件名防止覆盖 String newFileName UUID.randomUUID().toString() suffix; // 3. 按业务类型分目录存储便于管理 String bizPath bizType / LocalDate.now().toString().replace(-, /) /; File dest new File(uploadPath bizPath newFileName); // 4. 确保目录存在 if (!dest.getParentFile().exists()) { dest.getParentFile().mkdirs(); } try { file.transferTo(dest); // 5. 返回访问路径可以是相对路径或完整URL需配合静态资源映射 String accessPath /upload/ bizPath newFileName; // 6. 将文件信息存入数据库关联业务ID // fileService.saveRecord(accessPath, originalFilename, ...); return Result.success(accessPath); } catch (IOException e) { log.error(文件上传失败, e); return Result.error(上传失败); } } }前端Vue组件调用示例!-- 文件路径bidding-frontend/src/views/bid/BidSubmit.vue -- template el-upload classupload-demo action/api/file/upload !-- 后端上传接口 -- :data{ bizType: bid_doc } :on-successhandleSuccess :before-uploadbeforeUpload el-button typeprimary点击上传标书/el-button div slottip classel-upload__tip只能上传pdf/doc/docx/zip文件且不超过50MB/div /el-upload /template script setup langts import { ElMessage } from element-plus; const handleSuccess (response: any) { if (response.code 200) { ElMessage.success(上传成功); // 将返回的文件路径保存到表单数据中 form.filePath response.data; } else { ElMessage.error(response.msg); } }; const beforeUpload (file: File) { const isLt50M file.size / 1024 / 1024 50; if (!isLt50M) { ElMessage.error(文件大小不能超过50MB!); return false; } return true; }; /script6. 系统运行与功能验证当后端和前端都成功启动后打开浏览器访问前端地址如http://localhost:5173。6.1 登录验证使用初始化脚本中的管理员账号如 admin/admin123登录。观察浏览器开发者工具F12的“网络(Network)”选项卡。登录请求应返回一个token后续请求的Authorization头部应携带Bearer token。6.2 核心业务流程验证请按照以下顺序操作验证系统核心流程是否通畅管理员登录后进入“用户管理”创建一个“招标方”角色用户如tender_user1。招标方退出管理员账号用新创建的招标方账号登录。进入“项目管理”点击“新建”。填写项目信息标题、预算、报名截止时间、投标截止时间等保存为草稿。找到刚创建的项目点击“发布”。此时项目状态应变更为“已发布”。管理员登录创建“投标方”用户如bidder_user1和“评审专家”用户如expert_user1。投标方用投标方账号登录。在“招标公告”页面应能看到刚发布的项目。点击“查看详情”然后“报名参与”。在“我的投标”页面找到已报名的项目点击“提交标书”上传文件。关键验证点在投标截止时间前应允许修改标书在投标截止时间后可通过修改数据库时间模拟“修改”按钮应禁用。招标方登录在项目投标截止后进入项目详情页。点击“开始评审”为项目分配若干评审专家选择之前创建的专家用户。评审专家用专家账号登录。在“我的评审”任务列表中应看到被分配的项目。点击“评审”在线查看投标文件并填写评分和意见提交。招标方登录待所有专家评审完成后进入项目详情页。查看评审汇总确认中标方点击“公示结果”。项目状态最终变为“已结束”。6.3 接口与数据验证除了界面操作还应直接验证后端API是否正常工作。启动后端后访问Swagger文档页面如果集成了Knife4j通常是http://localhost:8080/doc.html。在这里你可以看到所有API接口并在线调试这对于理解前后端交互和数据格式至关重要。7. 常见问题与排查思路避坑指南在部署和开发过程中你几乎一定会遇到以下问题。别慌按此思路排查。问题现象可能原因排查方式解决方案前端启动失败npm install报错1. Node.js版本不兼容2. 网络问题依赖下载失败3. 项目依赖的特定包版本不存在1.node -v检查版本2. 查看错误日志是否超时或4043. 检查package.json中依赖版本1. 使用LTS版本Node.js (16, 18)2. 切换npm镜像源npm config set registry https://registry.npmmirror.com3. 删除node_modules和package-lock.json重试npm install后端启动失败端口被占用8080端口已被其他程序如旧Spring Boot应用、Tomcat使用控制台错误信息会明确提示Port 8080 was already in use1. 在application.yml中修改server.port2. 命令行查找并杀死占用进程netstat -ano | findstr :8080然后taskkill /PID 进程号 /F(Windows)数据库连接失败1. MySQL服务未启动2. 配置文件中用户名密码错误3. 数据库名错误或不存在4. 时区设置问题1. 检查MySQL服务状态2. 核对application.yml中的url,username,password3. 尝试用客户端连接验证1. 启动MySQL服务2. 修正配置文件3. 创建指定的数据库4. 在JDBC URL中添加serverTimezoneAsia/Shanghai前端访问后端API 404 或跨域错误1. 后端服务未启动2. 前端代理配置错误3. 后端接口路径与前端请求不匹配1. 确认后端控制台无报错且已启动2. 检查浏览器Network看请求URL是否正确代理到后端3. 核对后端RequestMapping注解路径1. 确保后端服务运行2. 检查vite.config.ts中的proxy配置目标地址是否为后端地址和端口3. 在后端使用CrossOrigin注解或全局配置解决跨域SecurityConfig中已配置登录成功但后续请求401未授权1. 前端未正确存储或发送Token2. Token已过期3. 后端JWT密钥(jwt.secret)不一致或解析失败1. 查看浏览器Application/Local Storage是否存有token2. 查看请求Header中Authorization字段格式是否为Bearer token3. 检查后端日志是否有JWT解析异常1. 检查前端登录成功后的token存储逻辑2. 延长jwt.expire或重新登录3. 确保生产环境修改了默认的jwt.secret且前后重启后一致文件上传失败或找不到1. 上传目录没有写权限2. 配置文件中的file.upload.path路径不存在3. 前端上传文件大小超限4. Nginx等未配置静态资源映射1. 检查后端日志中的IO异常2. 确认配置的路径存在且可写3. 检查后端spring.servlet.multipart.max-file-size配置4. 确认访问路径是否正确映射到磁盘文件1. 创建目录并赋予权限2. 使用绝对路径或确保相对路径正确3. 调整大小限制前后端需一致4. 在后端配置静态资源映射spring.web.resources.static-locationsfile:${file.upload.path}8. 项目优化与进阶实践让毕业设计更出彩完成基础功能后以下优化点能让你的项目从“及格”跃升到“优秀”。8.1 引入Redis缓存提升性能场景招标项目列表、热门投标排名等频繁读取且变化不频繁的数据。实现添加Redis依赖。!-- pom.xml -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency配置Redis连接。# application.yml spring: redis: host: localhost port: 6379 password: database: 0在Service层使用缓存注解。Service public class ProjectServiceImpl implements ProjectService { Cacheable(value projects, key #status _ #pageNum _ #pageSize) public PageInfoProjectVO getPublishedProjects(String status, int pageNum, int pageSize) { // 查询数据库逻辑 return pageInfo; } // 当项目更新时清除缓存 CacheEvict(value projects, allEntries true) public boolean updateProject(Project project) { // 更新逻辑 } }8.2 使用消息队列异步处理任务场景发布项目后给所有潜在投标方发送邮件通知、投标截止后批量生成评审任务。这些操作耗时不应阻塞主流程。实现以RabbitMQ为例添加依赖并配置。定义消息生产者在项目发布成功后发送消息。Service public class NotificationService { Autowired private RabbitTemplate rabbitTemplate; public void sendPublishNotification(Project project) { // 构造消息 MapString, Object msg new HashMap(); msg.put(projectId, project.getId()); msg.put(projectTitle, project.getTitle()); // 发送到队列 rabbitTemplate.convertAndSend(project.publish.notice, msg); } }定义消息消费者专门发送邮件。Component RabbitListener(queues project.publish.notice) public class EmailNotificationConsumer { public void handleMessage(MapString, Object msg) { // 异步发送邮件逻辑 System.out.println(发送项目发布通知邮件: msg.get(projectTitle)); } }8.3 完善日志与监控操作日志使用AOP或注解记录关键业务操作如发布项目、提交标书、评审打分的用户、时间、IP和详情便于审计。异常日志全局异常处理器中记录错误堆栈并告警。API监控使用Spring Boot Actuator暴露健康检查、性能指标端点。8.4 前端体验优化路由守卫在Vue Router中配置全局前置守卫根据用户角色和权限动态加载路由实现真正的权限菜单。状态管理使用Pinia集中管理用户信息、全局配置等状态避免组件间复杂的传值。组件封装将通用的表格、表单、文件上传等逻辑封装成业务组件提高代码复用率。9. 从项目到简历如何呈现你的毕业设计一个优秀的项目需要优秀的表达。在简历和面试中你可以这样组织你的“在线招投标系统”项目描述项目名称基于Spring Boot Vue的在线招投标管理系统项目描述独立设计并开发了一个支持多角色招标方、投标方、专家、管理员协同的在线招投标平台实现了从项目发布、投标、评审到定标的全流程数字化管理。我的职责/技术亮点架构设计采用前后端分离架构后端基于Spring Boot构建RESTful API前端使用Vue 3 Element Plus实现响应式管理界面。核心业务实现设计了基于RBAC模型的权限控制系统结合Spring Security与JWT实现接口级权限拦截。实现了招投标项目的状态机管理确保业务流程草稿-发布-投标-评审-结束的状态流转正确性与数据一致性。完成了投标文件的安全上传、存储与在线预览功能通过文件类型校验、重命名策略保障系统安全。性能与扩展针对高频访问的项目列表接口引入Redis缓存响应时间提升约70%。使用RabbitMQ将邮件通知等耗时任务异步化提升主业务响应速度。工程化实践使用Git进行代码版本管理遵循阿里Java开发规范编写了详细的API文档Swagger和项目部署文档。遇到的挑战与解决挑战1在投标截止瞬间如何防止投标信息被篡改解决在业务层使用Transactional确保状态变更和文件锁定的原子性并在数据库表设计中增加final_version标志位截止时间后仅可读取最终版本。挑战2前端权限菜单如何根据后端动态生成解决设计菜单-角色关联表用户登录时后端返回其有权访问的菜单树前端通过Vue Router的addRoutes动态挂载路由。通过这样结构化的描述你不仅展示了技术栈更体现了你解决复杂业务问题的思维和能力这正是企业招聘时所看重的。
返回列表