[!IMPORTANT]
新增员工
- 新增员工功能的整体流程是怎样的?
- 如何将前端提交的DTO对象转换为数据库实体对象?
- 新增员工时如何解决接口测试中JWT令牌校验失败导致的401错误?
- 如何处理用户名重复的异常?如何返回提示信息?
- 如何动态获取当前登录用户的ID来设置创建人和修改人?ThreadLocal在此处的作用是什么?
员工分页查询
分页查询功能的实现流程是怎样的?PageHelper插件的作用是什么?
返回结果中的时间格式不统一,如何全局处理日期格式化问题?
启用禁用员工账号
- 启用/禁用员工账号的流程是怎样的?
编辑员工
编辑员工功能的整体流程是怎样的?
如何实现数据回显?为什么要隐藏密码字段?
修改员工信息时,如何确保更新时间和修改人信息正确?
分类模块
菜品分类模块包含哪些核心功能?
删除分类时需要注意什么约束条件?
新增员工
-
新增员工功能的整体流程是怎样的?
- 客户端发起一个 POST 请求,将前端填写的员工相关表单数据发送给后端。
- 后端的控制器接收到这个 POST 请求后,利用
@RequestBody
注解把请求体里的数据绑定到EmployeeDTO
对象,完成数据封装。 - 控制器接着调用 Service 层的
save
方法,同时把封装好的EmployeeDTO
对象作为参数传递过去。 - Service 层开始处理业务逻辑:
- 首先创建一个
Employee
实体对象,这将用于后续存储完整的员工信息。 - 运用
BeanUtils.copyProperties
方法,把EmployeeDTO
对象中同名的属性复制到新创建的Employee
实体对象里。 - 为
Employee
实体对象设置账号状态,使用StatusConstant.ENABLE
来表示该账号为启用状态。 - 对默认密码
"123456"
进行处理,通过DigestUtils.md5DigestAsHex
方法对其进行 MD5 加密,然后把加密后的密码设置到Employee
实体对象中。 - 获取系统当前时间,借助
LocalDateTime.now()
方法得到的时间作为Employee
实体对象的创建时间。 - 将
Employee
实体对象的最后修改时间初始化为与创建时间相同。 - 从线程局部变量里获取当前操作者的 ID,使用
BaseContext.getCurrentId()
方法,把这个 ID 设置为Employee
实体对象的创建人 ID。 - 同样把该 ID 也设置为
Employee
实体对象的最后修改人 ID。
- 首先创建一个
- Service 层调用持久层的
employeeMapper.insert
方法,把装配好所有信息的Employee
实体对象插入到数据库中。 - 持久层完成插入操作后,将结果返回给 Service 层,Service 层再把结果返回给控制器。
- 控制器使用
Result.success()
方法,把成功标识和空数据体包装成统一的响应结构。 - 最后,控制器返回 HTTP 200 状态码给客户端,客户端接收到这个响应后,就确认员工信息创建操作已成功完成。
-
如何将前端提交的DTO对象转换为数据库实体对象?
(1) 使用
BeanUtils.copyProperties()
方法,将DTO对象的属性拷贝到Entity对象中。(2) 然后手动设置Entity对象中DTO没有的字段(如状态、密码、创建时间等)。
-
新增员工时如何解决接口测试中JWT令牌校验失败导致的401错误?
- 在接口测试工具中,先调用登录接口获取JWT令牌。
- 将JWT令牌添加到全局请求头中。
- 确保每次请求都携带该令牌。
-
如何处理用户名重复的异常?如何返回友好提示信息?
使用全局异常处理器捕获SQLIntegrityConstraintViolationException
→ 提取异常消息 → 判断是否包含Duplicate entry
关键字 → 是:按空格分割消息 → 提取索引为2的字段(如'zhangsan'
) → 去除单引号 → 拼接友好提示(用户名 zhangsan 已存在
) → 返回统一错误响应(Result.error(msg)
);否:返回未知错误提示。
-
如何动态获取当前登录用户的ID来设置创建人和修改人?ThreadLocal在此处的作用是什么?
动态获取:
- 在JWT拦截器中解析令牌,获取当前用户ID。
- 将用户ID存入ThreadLocal(
BaseContext.setCurrentId()
)。 - 在Service层通过
BaseContext.getCurrentId()
获取当前用户ID。
ThreadLocal作用:为每个线程提供独立的存储空间,确保在同一次请求中共享数据(如当前用户ID)。
员工分页查询
-
分页查询功能的实现步骤是怎样的?PageHelper插件的作用是什么?
流程:整体流程概述
前端传递分页参数(页码、每页记录数)和查询条件,后端通过 Controller 层接收并封装参数,Service 层设置分页并调用 Mapper 层进行数据库查询,最后将查询结果封装返回给前端进行渲染。其中,PageHelper 可自动拦截 SQL 语句添加
limit
分页条件,简化分页逻辑。Controller 层
- 接收请求:接收来自前端传递的分页参数(页码、每页记录数)和查询条件。
- 参数封装:将接收到的参数封装为
EmployeePageQueryDTO
对象,以便后续传递给 Service 层进行处理。 - 调用服务:调用 Service 层的对应方法,将封装好的
EmployeePageQueryDTO
对象作为参数传入。 - 返回响应:接收 Service 层返回的处理结果,将其封装为统一响应
Result<PageResult>
并返回给前端。
Service 层
- 设置分页:调用
PageHelper.startPage()
方法,根据EmployeePageQueryDTO
中的页码和每页记录数设置分页信息。PageHelper
会自动拦截后续执行的 SQL 语句,在其中添加limit
分页条件,从而简化手动编写分页逻辑的操作。 - 调用数据访问:调用 Mapper 层的方法,传入
EmployeePageQueryDTO
对象,执行数据库查询操作。 - 结果处理:接收 Mapper 层返回的
Page<Employee>
分页对象,从中提取总记录数和当前页的数据列表。 - 结果封装:将提取的总记录数和数据列表封装为
PageResult
对象,返回给 Controller 层。
Mapper 层
- 执行动态 SQL 查询:根据
EmployeePageQueryDTO
中的查询条件,执行动态 SQL 查询。若包含姓名条件,则拼接LIKE
查询语句进行模糊查询。 - 返回查询结果:将查询结果封装为
Page<Employee>
分页对象并返回给 Service 层。
PageHelper作用
自动拦截SQL语句,添加
limit
分页条件,简化分页逻辑。 -
返回结果中的时间格式不统一,如何全局处理日期格式化问题?
-
扩展Spring MVC的消息转换器,在WebMvcConfiuration中重写extendMessageConverters方法
-
使用自定义的
JacksonObjectMapper
,统一设置日期格式为"yyyy-MM-dd HH:mm "。
-
启用/禁用员工账号
流程:
前端点击操作 → URL路径参数传递状态值(/status/{status}
) + URL请求参数传递员工ID(?id=1
) → Controller层通过@PathVariable
提取状态、隐式接收ID → Service层构建Employee
对象(设置status
、id
,补充updateTime
(当前时间)和updateUser
(当前操作人ID)) → Mapper层执行动态SQL(通过<set>
标签更新status
及审计字段update_time
、update_user
) → 数据库返回影响行数 → Controller层返回统一响应Result.success()
→ 前端刷新状态。
编辑员工
1. 编辑员工功能的整体流程是怎样的?
前端传递员工ID → Controller层调用employeeService.getById()
查询员工信息 → 返回数据并回显到编辑页面 → 用户修改信息后提交 → 前端传递修改后的数据(EmployeeDTO
) →Service层将EmployeeDTO
转换为Employee
对象 → Controller层调用employeeService.update()
→ Mapper层执行动态SQL更新 → 返回操作结果(Result.success()
) → 前端刷新页面。
2. 如何实现数据回显?为什么要隐藏密码字段?
- 前端请求员工信息(传递ID) → Controller层调用
getById
→ Service层查询数据库 → 隐藏密码字段(setPassword("****")
) → 返回Employee
对象 → 前端渲染表单。。 - 隐藏密码字段:
- 在
getById()
方法中,将密码字段设置为****
,避免敏感信息泄露。 - 前端不需要显示或修改密码字段。
- 在
3. 修改员工信息时,如何确保更新时间和修改人信息正确?
-
更新时间:在Service层的
update()
方法中,手动设置updateTime
为当前时间(LocalDateTime.now()
)。 -
修改人ID:通过
BaseContext.getCurrentId()
从ThreadLocal中获取当前登录用户ID,并设置为updateUser
。
分类模块
- 菜品分类模块包含哪些核心功能?
- 新增分类
- 分页查询分类
- 根据ID删除分类
- 修改分类信息
- 启用/禁用分类
- 分类类型查询(用于下拉列表)
- 删除分类时需要注意什么约束条件?
- 约束条件:如果分类关联了菜品或套餐,则不允许删除。
- 实现:在删除前检查关联关系,确保数据完整性。