苍穹外卖笔记day2

第二天 员工管理、分类管理等

gitee项目代码

第三节 – 启用禁用员工账号

一、需求分析和设计
产品原型:
业务规则:
  • 可以对状态为“启用” 的员工账号进行“禁用”操作
  • 可以对状态为“禁用”的员工账号进行“启用”操作
  • 状态为“禁用”的员工账号不能登录系统
接口设计:
二、代码开发
  1. 在Controller层,sky-server/src/main/java/com/sky/controller/admin/EmployeeController.java中编写“禁用与启用员工账号”的方法,调用Service层。
/**
 * 启用/禁用员工账号
 * 只改数据库状态,不返回最新数据
 *
 * @param status 目标状态  1-启用  0-禁用(URL 路径里传过来)
 * @param id     要操作的员工主键(URL 查询参数里传过来)
 * @return       统一响应包 Result,data 为 null,只代表成败
 */
@PostMapping("/status/{status}")          // POST 请求:/employee/status/1?id=123
@ApiOperation("启用禁用员工账号")          // 给 Swagger 的接口说明
public Result startOrStop(@PathVariable Integer status,   // 把 URL 里的 {status} 取出来
                          Long id) {                      // 把 ?id= 取出来
    // 日志:谁点了启用/禁用,一眼就能定位
    log.info("启用禁用员工账号:status={}, id={}", status, id);

    // 真正的业务逻辑:Service 里执行 update 语句,把 status 字段改掉
    employeeService.startOrStop(status, id);

    // 告诉前端“操作成功”,但不附带任何新数据(data = null)
    return Result.success();
}

在这里插入图片描述
2. 鼠标定位Controller的爆红处,按Alt + Enter,点击Create method……,自动跳转到Service层,sky-server/src/main/java/com/sky/service/EmployeeService.java创建了startOrStop方法。
在这里插入图片描述

    /**
     * 禁用与启用员工账号
     * @param status
     * @param id
     */
    void startOrStop(Integer status, Long id);

在这里插入图片描述

  1. 在ServicImpl实现类,sky-server/src/main/java/com/sky/service/impl/EmployeeServiceImpl.java中实现startOrStop方法。
/**
 * 启用/禁用员工账号
 * 只做“单字段更新”,不查库、不返回最新数据
 *
 * @param status 目标状态 1-启用 0-禁用
 * @param id     要更新的员工主键
 */
@Override
public void startOrStop(Integer status, Long id) {
    /*
     * 构造一个只有 id 和 status 两个字段的 Employee 对象,
     * 让 MyBatis 去做“按需更新”(只 update 非空字段)。
     * 这样就不会把其他字段覆盖成 null。
     */
    Employee employee = Employee.builder()
            .id(id)      // 主键,告诉 MyBatis 更新哪一行
            .status(status) // 要改的新状态
            .build();

    // 把“迷你对象”丢给 Mapper,真正发 SQL执行update employee set status = ? where id = ?
    employeeMapper.update(employee);
}

在这里插入图片描述

  1. Mapper层,sky-server/src/main/java/com/sky/mapper/EmployeeMapper.java
/**
 * 通用动态更新
 * 只更新 employee 对象里 **非空属性** 对应的列
 * @param employee 携带主键 id 和要改的字段(其余字段为 null 即不改)
 */
void update(Employee employee);

在这里插入图片描述

  1. 在Mapper映射文件xml中编写

因为 yml 里给 MyBatis 起了别名(type-aliases-package: com.sky.entity),
所以任何 XML 映射文件里写 parameterType="Employee" 等价于写om.sky.entity.Employee
省掉包名不写也不会报错——MyBatis 启动时会自动扫那个包,把简单类名注册成别名。

在这里插入图片描述
sky-server/src/main/resources/mapper/EmployeeMapper.xml映射文件中动态更新语句。

<!-- 动态更新语句:只改“非空”字段,绝不动其他列 -->
<update id="update" parameterType="Employee">
    update employee
    <set>   <!-- set 标签会自动去掉最后一个多余逗号 -->
        <if test="name != null">        name = #{name},      </if>
        <if test="password != null">    password = #{password}, </if>
        <if test="phone != null">       phone = #{phone},    </if>
        <if test="sex != null">         sex = #{sex},        </if>
        <if test="idNumber != null">    id_Number = #{idNumber}, </if>
        <if test="updateTime != null">  update_Time = #{updateTime}, </if>
        <if test="updateUser != null">  update_User = #{updateUser}, </if>
        <if test="status != null">      status = #{status},  </if>  <!-- ★ 本次只有它非空 ★ -->
    </set>
    where id = #{id}   <!-- ★ 保证只改这一行 ★ -->
</update>

在这里插入图片描述

🙋‍代码含义(分清楚 数据库列名Java对象属性名

据库列名 = #{Java对象属性名}

符号/写法 代表含义 实际指向 命名风格 作用
update_Time 数据库列名 employeeupdate_time 字段 蛇形命名(下划线) SQL 语句中的列
#{updateTime} Java 属性占位符 Employee 对象的 getUpdateTime()
方法返回值
驼峰命名 预编译参数值
<if test=
"updateTime
!= null">
条件判断 检查传入的 Employee
对象中 updateTime
属性是否为 null
- 动态控制 SQL 片段是否生成
<set> 动态 SQL 标签 包裹所有 <if>
生成的 set 子句
- 自动去除末尾多余逗号,确保 SQL 语法正确
🙋‍ 知识点:使用泛型的典型场景:
场景 示例 是否需要泛型
封装返回结果 Result<T> ✅ 需要,因为返回的数据类型不确定
集合类 List<T>, Map<K,V> ✅ 需要,因为元素类型不确定
工具类方法 T getFirst(List<T> list) ✅ 需要,因为方法想适用于任意类型
查询类 UserQuery, OrderQuery ❌ 不一定需要,除非你想让它通用化

简单来说:

场景 要不要泛型 例子
类型会变 ✅ 要 Result<T> 今天装 User,明天装 Order
类型固定 ❌ 不要 User 永远是 User,只改字段值
三、功能测试
通过Swagger接口文档测试
  1. 代码已经写完,我们debug启动程序测试。
  2. 在Controller中添加一个断点
    在这里插入图片描述
  3. 我们jwt令牌的有效时间是7200秒=2小时,所以2小时后jwt令牌的token会失效。
    在这里插入图片描述
  4. 解决方法:在员工登录处,重新登录一下,复制新生成的令牌在这里插入图片描述
  5. 然后在 文档管理 →全局参数设置中粘贴刚刚我们复制的jwt临牌的token值过去,然后再关闭所有标签
    在这里插入图片描述
  6. 在接口文档中点击→ 员工相关接口→调试→请求参数→输入id参数值3和status参数值0,点击发送按钮。原status参数值为1。
    在这里插入图片描述
  7. 回到Controller控制层和控制台,我们可以看到我们已经把id和status都传递过来了。
    在这里插入图片描述
  8. 点2次单步调试,我们运行完了employeeService.startOrStop(status,id),可以看到我们已经把状态改成了0,update已经运行了1条数据。
    在这里插入图片描述
  9. 刷新数据库,id为3的用户,status已经改为0了,成功
    在这里插入图片描述
通过前后端联调测试
  1. 测试登录老六账号,上面已经把老六状态调为了0(禁用),所以登录不了。
    在这里插入图片描述

  2. 切换管理员账号登录。
    在这里插入图片描述

  3. 进入到首页后点击员工管理→在老六操作下点击“启用”
    在这里插入图片描述

  4. 回到后端代码,我们可以看到,zaiController层中,我们接收到id为3,status为1的参数。
    在这里插入图片描述

  5. 直接放行,回到前端页面,刷新,状态变为1,启用状态,可禁用。(添加了断点我的要刷新一下才会更新,而取消断点会弹出提示信息并实时更新。)
    在这里插入图片描述

  6. 再次用老六登录,登录成功。
    在这里插入图片描述

四、完整流程:启用禁用员工账号
步骤 位置 动作 关键代码/URL
1 前端页面 用户触发“启用/禁用”开关,组装请求参数 axios.post('/employee/status/1?id=123')
2 浏览器 发出 HTTP 请求,携带路径参数与查询参数 POST http://localhost:8080/employee/status/1?id=123
3 EmployeeController
(表现层)
接收路径变量 status 与查询参数 id,记录日志并转交 Service @PostMapping("/status/{status}")
4 EmployeeService
(业务层接口)
定义更新契约,保持层间解耦 void startOrStop(Integer status, Long id);
5 EmployeeServiceImpl
(业务层实现)
构建仅含主键与新状态的实体对象,调用 Mapper 完成持久化 Employee e = Employee.builder().id(id).status(status).build();
6 EmployeeMapper
(持久层接口)
声明动态更新方法,供 XML 映射文件绑定 void update(Employee employee);
7 mapper.xml
映射文件
依据非空字段动态生成 SQL,仅更新 status <update id="update">...</update>
8 MySQL 数据库 执行更新语句,返回受影响行数,事务提交 update employee set status = ? where id = ?

时序图
在这里插入图片描述

时序图代码(csdn显示不出来,markdown版本太低也不支持)

"MySQL" "mapper.xml 映射文件" "EmployeeMapper (持久层接口)" "EmployeeServiceImpl (业务层实现)" "EmployeeService (业务层接口)" "EmployeeController (表现层)" "浏览器" "前端页面 (Vue/React)" "用户" "MySQL" "mapper.xml 映射文件" "EmployeeMapper (持久层接口)" "EmployeeServiceImpl (业务层实现)" "EmployeeService (业务层接口)" "EmployeeController (表现层)" "浏览器" "前端页面 (Vue/React)" "用户" 点击"启用/禁用"开关 axios.post("/employee/status/1?id=123") POST /employee/status/1?id=123 日志记录 status=1,id=123 startOrStop(1,123) 动态代理调用实现类 Employee e = Employee.builder().id(123).status(1).build() update(e) 执行 id="update" 语句 update employee set status=1 where id=123 受影响行数=1 更新完成 void 返回 业务事务提交 方法返回 Result.success(){code:0,msg:"ok",data:null} 200 OK + JSON 按钮状态切换成功 "启用禁用员工账号完整链路"
Gitee代码提交

1.Git → Commit,输入“启用禁用员工账号业务代码开发”→Commit and Push
在这里插入图片描述
2. 如果弹出这个,继续点击Commit anyway and push,意思是提交的代码有 43 个警告,但没有编译错误;是否继续推送?
在这里插入图片描述
3. 弹出对话框,点击Push
在这里插入图片描述
4. 提交并推送成功
在这里插入图片描述
5. gitee登录刷新页面,显示刚刚提交的代码。
在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐