SpringBoot+Vue员工管理系统:从数据库设计到前后端部署全解析 每年的毕业季都能看到大量“计算机毕业设计”相关的求助帖其中“公司员工管理系统”绝对是出场率最高的选题之一。无论你是准备自己动手做一个还是拿到了一套基于 SpringBoot Vue 的成品源码准备跑通、看懂、写进论文这个题目都绕不开几个核心问题系统到底由哪些功能构成、表结构怎么设计、前后端怎么联调、最终能不能顺利打包部署。我接手过不少这种项目也帮别人远程调过代码今天就把这套“SpringBoot Vue 员工管理系统”从头到尾给你拆开讲清楚包括源码的核心结构、数据库表的建设思路、文档怎么去写以及实操里最常见的坑。这套系统面向的是一个典型的中小公司人事管理场景解决的是纸质档案、Excel 表格满天飞考勤和工资核算全靠手工的问题。系统做出来以后管理员可以维护员工档案、管理部门岗位、审核请假申请、录入考勤和薪资员工自己则可以登录系统查看个人信息、提交请假和查看工资条。适合拿来做毕业设计、课程设计也适合刚入门的 Java 开发者作为前后端分离项目的练手案例。1. 项目整体设计与技术选型1.1 为什么是 SpringBoot Vue 这个组合很多同学刚开始选题的时候会纠结用 SSM 还是 SpringBoot用 JSP 还是前后端分离。我的建议很直接只要不是学校强制要求 SSH 或者 JSP就优先选 SpringBoot Vue 这个组合。原因很简单这已经是目前企业级 Java 开发里最常见的前后端分离方案了招聘岗位要求里大量出现这两个关键词做毕业设计选它既好写论文也好答辩。SpringBoot 对比传统的 SSM最大的优势在于“约定大于配置”不用再写一堆繁琐的 XML 配置文件内嵌了 Tomcat一个 main 方法直接启动项目。Maven 帮我们管好了依赖版本常用的 starter 拿过来直接就能用。这种开发体验对做毕设的学生来说非常友好出 bug 的概率也小得多。Vue 这边就用到了当前主流的前端工程化方案Vue CLI 或 Vite 创建工程、vue-router 做路由、axios 发请求、Element UI/Element Plus 做界面组件。我个人的习惯是用 Vue 2 Element UI因为网上的配套资料最多教学视频也多遇到问题随便一搜就有答案。如果学校要求新一点Vue 3 Element Plus 也没问题只是相关答疑资料相对少一些但核心逻辑大同小异。前后端分离的好处是前端只负责页面渲染和交互后端只负责提供 JSON 接口。两边解耦清晰写论文的时候“系统架构设计”这一章非常容易描述层次画架构图也顺理成章。团队分工的话一个人负责前端一个人负责后端可以并行开发互不阻塞。1.2 系统功能模块拆解一套标准的员工管理系统按角色划分至少应该包含两类用户管理员和普通员工。两个角色看到的功能菜单和操作权限是不一样的这套权限设计也是论文里“系统需求分析”的核心部分。管理员端的功能一般包括员工管理员工信息的增删改查包括姓名、工号、性别、手机号、邮箱、身份证号、入职日期等部门管理部门信息的维护组织架构的展示岗位管理岗位名称、所属部门、岗位描述考勤管理手动录入或导入员工考勤记录包括上下班时间、考勤状态请假审批查看员工提交的请假申请通过或驳回薪资管理设定基本工资、岗位工资、请假扣款、实发工资按月生成工资单公告管理发布公司公告推送给全站用户系统管理管理员账号维护、数据备份入口等普通员工端的功能相对收敛个人信息查看与部分字段修改查看本部门同事信息提交请假申请填写请假类型、起止时间、请假事由查看请假审批状态和审批历史查看历史考勤记录查看每月工资条这些功能模块其实每一块都不是特别难但组合在一起系统的完整度一下子就上来了。写需求分析的时候把这几块列清楚数据流图、用例图都好画论文的框架感也就出来了。1.3 项目整体目录结构拿到源码以后第一步不是急着启动项目而是先看目录结构。一个清晰的工程结构能帮你快速定位代码位置改 bug 的时候才不会手忙脚乱。后端 SpringBoot 工程典型的包结构是这样com.example.employee ├── controller # 控制器层接收前端请求返回 JSON ├── service # 业务逻辑层处理业务规则 │ └── impl # 业务逻辑实现类 ├── mapper # MyBatis 数据访问层接口 ├── entity # 数据库实体类也可用 model/pojo 命名 ├── dto # 前后端交互的数据传输对象 ├── config # 配置类如跨域配置、拦截器配置 ├── common # 通用返回结果、异常处理 └── utils # 工具类比如 JWT 工具、导出 Excel 工具前端 Vue 工程的典型结构src ├── api # axios 接口请求封装 ├── assets # 静态资源 ├── components # 公共组件 ├── router # 路由配置 ├── store # Vuex 状态管理 ├── views # 页面视图 │ ├── admin # 管理员端页面 │ └── employee # 员工端页面 └── utils # 前端工具函数这种分包分层的模式本身就是企业开发里标准的工程规范。论文里的“系统实现”部分完全可以拿包结构的截图配合说明显得非常专业。2. 数据库设计与核心表结构2.1 数据库设计的原则员工管理系统说到底是一个典型的 CRUD 系统数据表的设计决定了整个开发效率。我的建议是遵循三大范式但不要过度设计能一张表解决的不要拆成两张否则查询起来关联关系复杂反而给自己挖坑。以我拆过的项目为例这套系统的表数量一般在 8 到 12 张之间比较合适。需要特别注意的是创建数据库时统一使用 UTF-8 字符集排序规则用 utf8mb4_general_ci避免出现中文乱码。数据库名建议取employee_system表名统一用小写加下划线的风格比如sys_user、attendance_record不要用驼峰命名。实体表应该包含的字段类型我这里给出一个尽量详细的清单主键统一用 idBIGINT 类型自增长时间字段统一用 datetime 类型金额字段用 decimal(10,2)不要用 float否则算工资会有精度问题状态字段用 tinyint0 和 1 表示或者几个固定值所有表建议都加上 create_time 和 update_time 两个公共字段2.2 核心表结构详解第一张核心表是员工档案表我习惯命名为 employee对应的实体类是 EmployeeEntity。字段至少包含字段名类型说明idbigint主键emp_novarchar(20)员工工号唯一namevarchar(30)员工姓名gendervarchar(10)性别birth_datedate出生日期phonevarchar(20)手机号emailvarchar(50)邮箱id_cardvarchar(18)身份证号department_idbigint所属部门 IDposition_idbigint岗位 IDentry_datedate入职日期educationvarchar(20)学历addressvarchar(200)住址statustinyint在职状态 0在职 1离职create_timedatetime创建时间update_timedatetime更新时间第二张关键表是用户表 sys_user它主要承担登录认证的功能和员工表可以一一对应也可以独立存在。字段包含 id、username、password、employee_id、role管理员还是普通员工、status是否锁定、create_time。要注意的是密码字段我强烈建议存储为 BCrypt 加密后的密文这是 Spring Security 里最常见的做法。即便毕设项目不需要像商业系统那样安全也尽量不要明文存密码答辩时老师特别喜欢问这个问题你回答“使用 BCrypt 加密存储”会加分不少。其他业务表还包括department 部门表id、dept_name、parent_id支持树形结构但对于中小公司可以简化、leader_name、create_timeposition 岗位表id、position_name、department_id、position_descattendance 考勤表id、employee_id、attendance_date、check_in_time、check_out_time、status正常/迟到/早退/缺勤leave_application 请假表id、employee_id、leave_type事假/病假/年假/调休、start_time、end_time、days、reason、approval_status待审批/通过/驳回、approval_remarksalary 薪资表id、employee_id、salary_month、basic_salary、position_salary、bonus、attendance_deduction、leave_deduction、social_security、actual_salaryannouncement 公告表id、title、content、publisher、create_time2.3 表关系与 SQL 脚本处理表之间的关系说白了就是外键逻辑约束。department 和 employee 是一对多position 和 employee 是一对多user 和 employee 是一对一其他业务表都通过 employee_id 关联到员工表。建表脚本最好写到 project.sql 文件里方便别人一键导入。如果你拿到的源码里没有现成的 SQL 文件那就要自己根据实体类去反推建表语句。实操里我用得最多的是 Navicat 的数据模型功能先把表创建出来再用它生成 SQL 文件或者可视化模型图直接截图放进论文就是一张数据关系图。有一点需要提醒不要把表建得过于“灵活”比如为了让系统看起来很厉害搞一张动态字段表去存储员工所有属性。这种设计查询极麻烦还不利于写论文。直接了当的业务表就是最好的。3. 后端核心功能实现3.1 SpringBoot 项目初始化与基础配置拿到一个 SpringBoot 后端源码首先要把基础配置跑通。打开 src/main/resources/application.yml 或者 application.properties这里面主要配置数据源、MyBatis、端口号、日志级别这几项。server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/employee_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 123456 mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.employee.entity这里有个非常坑的细节JDBC 连接 URL 里一定要加 serverTimezone 参数否则在特定 MySQL 版本下启动会直接报时区错误。还有如果数据库密码配置错了报错信息会显示 Access denied for user排查的时候先去看用户名密码再去怀疑驱动包问题。启动类很简单一个 SpringBootApplication 注解加上一个 main 方法。如果是多模块 Maven 工程root 模块需要先执行 mvn clean install然后再启动子模块很多同学第一步就在这卡死了。3.2 员工模块的增删改查接口实现后端实现的重头戏就是员工管理模块它是整个系统的核心功能。前后端交互采用 RESTful 风格接口返回值统一用 Result 对象包装前端好处理文档也好写。Result 对象一般长这样Data public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(操作成功); result.setData(data); return result; } public static T ResultT error(String message) { ResultT result new Result(); result.setCode(500); result.setMessage(message); return result; } }Controller 层实现RestController RequestMapping(/api/employee) public class EmployeeController { Resource private EmployeeService employeeService; GetMapping(/list) public ResultPageResultEmployeeDO list(RequestParam Integer pageNum, RequestParam Integer pageSize, RequestParam(required false) String keyword) { PageResultEmployeeDO page employeeService.getEmployeeList(pageNum, pageSize, keyword); return Result.success(page); } PostMapping(/add) public ResultVoid add(RequestBody EmployeeDTO employeeDTO) { employeeService.addEmployee(employeeDTO); return Result.success(null); } PutMapping(/update) public ResultVoid update(RequestBody EmployeeDTO employeeDTO) { employeeService.updateEmployee(employeeDTO); return Result.success(null); } DeleteMapping(/delete/{id}) public ResultVoid delete(PathVariable Long id) { employeeService.deleteEmployee(id); return Result.success(null); } }分页查询用 PageHelper 插件是最省事的先引入依赖然后在配置里写好分页插件Service 层调用 PageHelper.startPage(pageNum, pageSize) 再执行查询就好。Mapper 层用 MyBatis 的 XML 文件还是注解取决于个人习惯。XML 方式的好处是 SQL 不用拼 Java 字符串维护性好适合复杂的多表关联查询。比如员工列表一般都需要关联部门表和岗位表查询出部门名称和岗位名称这个时候写 SQL 要像下面这样select idselectEmployeePage resultTypecom.example.employee.entity.EmployeeDO SELECT e.*, d.dept_name AS departmentName, p.position_name AS positionName FROM employee e LEFT JOIN department d ON e.department_id d.id LEFT JOIN position p ON e.position_id p.id where if testkeyword ! null and keyword ! AND (e.name LIKE CONCAT(%, #{keyword}, %) OR e.emp_no LIKE CONCAT(%, #{keyword}, %)) /if /where ORDER BY e.create_time DESC /select把这段 SQL 写进配置文件后列表接口返回的 JSON 里直接带上了部门名和岗位名前端表格列就省得再做一次映射和联查效率更高。写论文的时候这一段也可以作为“系统实现难点”的素材。3.3 登录认证与 JWT 权限控制员工管理系统的登录模块看起来简单但要做到规范还是需要几步。我强烈建议用 JWT 而不是沿用传统的 Session 方式因为前后端分离项目天然适合 Token 认证而且答辩时这是一个高频考点。登录流程是这样前端把用户名密码发给 /api/auth/login后端校验用户是否存在、密码是否正确校验通过后用 JWT 生成一个包含用户 ID、用户名、角色的 Token 返回给前端。前端把 Token 存到 localStorage 或者 sessionStorage每次请求在 Header 里带上 Authorization: Bearer token。后端写一个拦截器或者 Spring Security 的过滤器对所有需要登录的接口做 Token 校验。JWT 工具类里核心方法有生成 token 和解析 tokenpublic String generateToken(Integer userId, String username, String role) { return Jwts.builder() .setSubject(username) .claim(userId, userId) .claim(role, role) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() 1000 * 60 * 60 * 24)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); }实操中最容易踩的坑是Shiro 或 Spring Security 的拦截链配置不当导致所有请求都被拦截或者不拦截。建议先拿 Postman 逐个接口测试确认哪些接口是放行的比如 /api/auth/login、静态资源哪些必须带 Token再调整配置。权限控制的部分最基础的做法是在拦截器里解析 Token 后取出 role 字段判断是否允许访问。如果想做得更细可以直接用 Spring Security 配合注解 PreAuthorize(hasRole(ADMIN))但配置和实现成本略高毕设阶段用拦截器做简单的角色判断也完全足够。3.4 Excel 导入导出与文件上传为了让系统看起来有亮点建议在员工管理模块加上“Excel 导入导出”功能。导出用阿里巴巴的 EasyExcel 工具库比传统 POI 写代码少很多内存占用也更低。核心代码是public void exportEmployees(HttpServletResponse response) throws IOException { ListEmployeeDO list employeeService.getAllEmployees(); response.setContentType(application/vnd.openxmlformats-officedocument.spreadsheetml.sheet); response.setCharacterEncoding(utf-8); String fileName URLEncoder.encode(员工信息, UTF-8).replaceAll(\\, %20); response.setHeader(Content-disposition, attachment;filename*utf-8 fileName .xlsx); EasyExcel.write(response.getOutputStream(), EmployeeDO.class).sheet(员工信息).doWrite(list); }注意不要把整整一个月的数据一次性全查出来来导出否则数据量一大内存直接打满。如果数据超过一万条拆成循环分批写每批 1000 条不然毕业答辩演示现场导出卡死会很狼狈。除此之外公告模块一般会涉及图片上传。文件上传需要在前端用 FormData 传给后端后端用 MultipartFile 接收保存到一个本地磁盘目录同时在数据库里记录访问路径。开发环境推荐把上传目录配置为系统临时目录部署到服务器以后再改成正式目录。最容易出错的是处理跨域导致下载文件失败要在 config 全局配置类的 addCorsMappings 方法里把允许的路径和来源配好。4. 前端 Vue 实现与联调细节4.1 Vue 项目初始化与环境配置前端工程是基于 Vue CLI 生成的创建命令我就不赘述了关键在环境配置这一步。你需要准备 Node.js 环境版本尽量保持团队统一建议 LTS 版本不要新到特别离谱的版本否则一些依赖库会报兼容性问题。安装依赖的时候容易踩坑。npm install 中途报错属于常态常见的有 node-sass 编译失败、Python 环境缺失等。这种问题最快的解决方式是删掉 node_modules 和 package-lock.json切换 npm 源到国内镜像然后重新安装。我个人的习惯是用 pnpm 或者 cnpm 做包管理速度快坑也相对少。Vue 项目启动以后在浏览器里访问 localhost:8080Vue 默认端口页面能正常渲染说明基础环境没问题。如果页面上控制台报错多半是依赖缺失、路由配置错误或接口请求跨域这三个原因逐个排查即可。4.2 前端路由与页面架构员工管理系统的前端页面一般分为三大类第一类是登录页第二类是管理员端的主布局页第三类是员工端的主布局页。路由设计时通常会用一个父路由对应主布局组件嵌套若干子路由对应具体页面。典型的路由配置const router new VueRouter({ routes: [ { path: /login, component: Login }, { path: /admin, component: AdminLayout, redirect: /admin/dashboard, children: [ { path: dashboard, component: Dashboard }, { path: employee, component: EmployeeList }, { path: department, component: DepartmentList }, { path: attendance, component: AttendanceList }, { path: salary, component: SalaryList }, { path: leave, component: LeaveApproval } ] }, { path: /employee, component: EmployeeLayout, redirect: /employee/myInfo, children: [ { path: myInfo, component: MyInfo }, { path: myLeave, component: MyLeave }, { path: mySalary, component: MySalary }, { path: myAttendance, component: MyAttendance } ] } ] })路由守卫是前端权限控制的关键在路由跳转之前检查本地有没有 Token没有就强制跳转登录页router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.path ! /login !token) { next(/login) } else { next() } })在菜单显示上推荐用动态路由或者 v-if 判断用户角色来渲染不同的菜单项。管理员登录后显示全套菜单员工登录后只显示自己的菜单这样看起来权限管理做得很完整。如果拿到的源码是这种实现平时多留意一下这个逻辑因为答辩老师可能会问“前端怎么控制不同角色看到不同菜单”。4.3 Axios 请求封装前端与后端联调是一大痛点。最稳妥的做法是在 src/utils/request.js 里对 axios 做统一封装import axios from axios import { Message } from element-ui import router from /router const service axios.create({ baseURL: process.env.VUE_APP_BASE_URL || /api, timeout: 10000 }) // 请求拦截器自动携带 token service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] Bearer token } return config }, error Promise.reject(error)) // 响应拦截器处理业务异常 service.interceptors.response.use( response { const res response.data if (res.code ! 200) { Message.error(res.message || 请求失败) return Promise.reject(new Error(res.message)) } return res }, error { if (error.response error.response.status 401) { localStorage.removeItem(token) router.push(/login) } Message.error(error.message || 网络异常) return Promise.reject(error) } ) export default service封装完成后每个模块的接口再单独建一个 js 文件比如 api/employee.js 里放员工接口import request from /utils/request export function getEmployeeList(params) { return request({ url: /employee/list, method: get, params }) }这样做的好处是每个页面组件里只需要引入对应的 api 函数代码非常干净。如果后端接口改了地址只需调整 api 文件不用去每个页面里翻找。4.4 页面布局与组件实现前端页面视觉效果取决于能否合理上手 Element UI。以员工列表页为例一个核心页面的布局包括顶部搜索栏、操作按钮区和中间的表格区。搜索栏放置员工姓名输入框和搜索按钮操作区放新增、导出、批量删除按钮表格列展示员工基本信息、所属部门、岗位、状态等。表格用 el-tableel-table :dataemployeeList border stripe el-table-column propempNo label工号 width120/el-table-column el-table-column propname label姓名 width120/el-table-column el-table-column propdepartmentName label部门 width140/el-table-column el-table-column proppositionName label岗位 width140/el-table-column el-table-column propphone label手机号/el-table-column el-table-column label操作 width220 template slot-scopescope el-button typeprimary sizemini clickhandleEdit(scope.row)编辑/el-button el-button typedanger sizemini clickhandleDelete(scope.row)删除/el-button /template /el-table-column /el-table新增和编辑建议用 el-dialog 对话框嵌套 el-form 表单来实现。表单校验是一个非常容易被忽视的细节例如身份证号不能为空、手机号要符合手机号格式、入职日期不能晚于今天等等Element UI 自带校验规则开发时把这些配置好填报数据不合法时前端直接拦截减轻后端压力。这一块的完善程度也会直接影响答辩评分老师大概率会现场输入非法数据“刁难”系统表单校验住了印象分自然高。5. 部署、踩坑与答辩准备5.1 前后端打包与部署流程做完的项目不能只停留在本地跑通毕设一般还需要部署到服务器上演示好一点的情况还需要把整个流程写进论文。部署步骤无非三个环节前端打包、后端打包、服务器部署。前端打包npm run build打包完成后会生成一个 dist 目录里面的 index.html 和 static 文件夹是纯静态文件。如果你不打算为前端单独配置 Nginx可以直接把这堆静态文件放到 SpringBoot 项目的 src/main/resources/static 目录下重新打包后端为一个 Jar 包这样访问的是同一个 8080 端口就完全不需要处理前端跨域问题了。后端打包mvn clean package -DskipTests执行完这行命令target 目录下会生成一个 jar 文件。启动命令java -jar employee-system.jar如果有外网服务器用宝塔面板部署会简单很多只需把 Jar 和 SQL 文件传到服务器导入数据库配置好 MySQL 的用户权限然后启动进程。注意服务器上 MySQL 的账号密码要和 application.yml 里配置的一致文本编码保持 utf8mb4其他基本没问题。如果没有服务器也可以在本地虚拟机里部署演示效果一样。5.2 常见报错与排查建议下面是我实际调试这类系统时最常遇到的问题做个速查表省得你逐个踩一遍问题现象解决方法MySQL 连接失败启动报 Communications link failure 或 Access denied检查数据库账号密码、端口号、MySQL 服务是否启动URL 里加 serverTimezone数据库中文乱码页面和数据库看到都是问号创建数据库时字符集选 utf8mb4JDBC URL 加 characterEncodingutf8前端请求跨域浏览器控制台报 CORS errorNetwork 里看到请求失败后端写跨域配置类或部署时用 Nginx 反向代理 /api 到后端端口前端打包后白屏访问服务器 IP 看到空白页检查 vite.config.js 里 base 配置设为 ./ 相对路径否则静态资源路径指向根目录接口返回 401登录后调用接口就报 401检查 Token 是否传到后端检查拦截器是否放行了登录接口分页查不到数据PageHelper 分页参数不生效确认 PageHelper 版本与 SpringBoot 2.x 兼容分页语句紧接着另一条 SQL 执行身份证号精度丢失Excel 导入后身份证变成科学计数法让后端以 String 接收前端也用文本格式单元格导出时间显示差 8 小时前端看到的时间比数据库少或多 8 小时统一在 Jackson 配置里设置时间格式和时区前端同时格式化时间字段5.3 答辩时容易被问到的问题毕业设计的评分很大程度看答辩表现。老师一般不会盯着代码逐行看更多是问系统设计思路和实现细节。我这里把最常见的问题列出来你可以提前准备答案系统用到了哪些技术栈为什么选择 SpringBoot 和 Vue登录模块是怎么实现认证的Token 过期了怎么处理数据库的表是怎么设计的为什么这么分表员工列表的分页查询是怎么实现的底层原理是什么如果并发量很大当前系统有哪些瓶颈怎么优化这个系统有哪些可以扩展的功能你在项目里遇到最大的困难是什么怎么解决的最后一个问题几乎是必问的。回答时别说什么“没遇到困难”也不要硬编一个假困难。最好的答案是用真实经历比如“在实现 Excel 导出时中文文件名在浏览器下载时总是乱码后来通过 URL 编码设置 Content-Disposition 的 filename* 解决了”这种真实的小故事既有细节又有说服力比背诵概念要强太多。5.4 项目扩展方向建议如果你的论文需要体现出“创新点”或者“后期改进”下面这些扩展方向可以写进论文的展望部分引入 Redis 缓存热点数据例如员工基本信息降低数据库查询压力引入 Spring Security JWT 强化权限控制加入基于 RBAC 模型的细粒度权限增加定时任务每月自动生成薪资单和考勤汇总增加消息通知请假审批结果通过 WebSocket 实时推送给员工引入工作流引擎让请假审批支持多级审批流程增加数据可视化看板用 ECharts 展示部门人数、考勤异常率、月度薪资总额等图表这些点不需要全部实现挑一两个做出雏形就能成为论文里的“系统特色”。尤其是数据可视化看板属于做起来相对简单、展示效果却非常亮眼的功能强烈推荐。个人在实际操作中的经验拿到任何一套源码项目第一件事不是跑起来而是把 ER 图和数据字典整理出来。数据字典是写文档和答辩的根基把每张表、每个字段的含义整理清楚后面的工作量会直线下降。毕业设计做员工管理系统难度适中覆盖面广确实是一个很适合展示综合能力的选择。只要把 SpringBoot 后端接口写明白、Vue 前端页面做周正、数据库表结构设计合理再配上一份逻辑通顺的设计文档这套作品放在任何一场答辩里都是拿得出手的。