前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【瑞吉外卖】day03:完善登录功能与新增员工

【瑞吉外卖】day03:完善登录功能与新增员工

作者头像
陶然同学
发布2023-02-27 13:19:13
4590
发布2023-02-27 13:19:13
举报
文章被收录于专栏:陶然同学博客

目录

1. 完善登录功能

1.1 问题分析

1.2 思路分析

1.3 代码实现

1.4 功能测试

2. 新增员工

2.1 需求分析

2.2 数据模型

2.3 程序执行流程

2.4 代码实现

2.5 功能测试

2.6 全局异常处理

1. 完善登录功能

1.1 问题分析

前面我们已经完成了后台系统的员工登录功能开发,但是目前还存在一个问题,接下来我们来说明一个这个问题, 以及如何处理。

1). 目前现状

用户如果不登录,直接访问系统首页面,照样可以正常访问。

2). 理想效果

上述这种设计并不合理,我们希望看到的效果应该 是,只有登录成功后才可以访问系统中的页面,如果没有登录, 访问系统中的任何界面都直接跳转到登录页面。

那么,具体应该怎么实现呢?

可以使用我们之前讲解过的 过滤器、拦截器来实现,在过滤器、拦截器中拦截前端发起的请求,判断用户是否已经完成登录,如果没有登录则返回提示信息,跳转到登录页面。

1.2 思路分析

过滤器具体的处理逻辑如下:

A. 获取本次请求的URI

B. 判断本次请求, 是否需要登录, 才可以访问

C. 如果不需要,则直接放行

D. 判断登录状态,如果已登录,则直接放行

E. 如果未登录, 则返回未登录结果

如果未登录,我们需要给前端返回什么样的结果呢? 这个时候, 我们可以去看看前端是如何处理的 ?

1.3 代码实现

1). 定义登录校验过滤器

自定义一个过滤器 LoginCheckFilter 并实现 Filter 接口, 在doFilter方法中完成校验的逻辑。 那么接下来, 我们就根据上述分析的步骤, 来完成具体的功能代码实现:

所属包: com.itheima.reggie.filter

代码语言:javascript
复制
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">alibaba</span>.<span style="color:#000000">fastjson</span>.<span style="color:#000000">JSON</span>;
<span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">itheima</span>.<span style="color:#000000">reggie</span>.<span style="color:#000000">common</span>.<span style="color:#000000">R</span>;
<span style="color:#770088">import</span> <span style="color:#000000">lombok</span>.<span style="color:#000000">extern</span>.<span style="color:#000000">slf4j</span>.<span style="color:#000000">Slf4j</span>;
<span style="color:#770088">import</span> <span style="color:#000000">org</span>.<span style="color:#000000">springframework</span>.<span style="color:#000000">util</span>.<span style="color:#000000">AntPathMatcher</span>;
​
<span style="color:#770088">import</span> <span style="color:#000000">javax</span>.<span style="color:#000000">servlet</span>.<span style="color:#981a1a">*</span>;
<span style="color:#770088">import</span> <span style="color:#000000">javax</span>.<span style="color:#000000">servlet</span>.<span style="color:#000000">annotation</span>.<span style="color:#000000">WebFilter</span>;
<span style="color:#770088">import</span> <span style="color:#000000">javax</span>.<span style="color:#000000">servlet</span>.<span style="color:#000000">http</span>.<span style="color:#000000">HttpServletRequest</span>;
<span style="color:#770088">import</span> <span style="color:#000000">javax</span>.<span style="color:#000000">servlet</span>.<span style="color:#000000">http</span>.<span style="color:#000000">HttpServletResponse</span>;
<span style="color:#770088">import</span> <span style="color:#000000">java</span>.<span style="color:#000000">io</span>.<span style="color:#000000">IOException</span>;
​
<span style="color:#aa5500">/**</span>
 <span style="color:#aa5500">* 检查用户是否已经完成登录</span>
 <span style="color:#aa5500">*/</span>
<span style="color:#555555">@WebFilter</span>(<span style="color:#000000">filterName</span> <span style="color:#981a1a">=</span> <span style="color:#aa1111">"loginCheckFilter"</span>,<span style="color:#000000">urlPatterns</span> <span style="color:#981a1a">=</span> <span style="color:#aa1111">"/*"</span>)
<span style="color:#555555">@Slf4j</span>
<span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">LoginCheckFilter</span> <span style="color:#770088">implements</span> <span style="color:#000000">Filter</span>{
    <span style="color:#aa5500">//路径匹配器,支持通配符</span>
    <span style="color:#770088">public</span> <span style="color:#770088">static</span> <span style="color:#770088">final</span> <span style="color:#000000">AntPathMatcher</span> <span style="color:#000000">PATH_MATCHER</span> <span style="color:#981a1a">=</span> <span style="color:#770088">new</span> <span style="color:#000000">AntPathMatcher</span>();
​
    <span style="color:#555555">@Override</span>
    <span style="color:#770088">public</span> <span style="color:#008855">void</span> <span style="color:#000000">doFilter</span>(<span style="color:#000000">ServletRequest</span> <span style="color:#000000">servletRequest</span>, <span style="color:#000000">ServletResponse</span> <span style="color:#000000">servletResponse</span>, <span style="color:#000000">FilterChain</span> <span style="color:#000000">filterChain</span>) <span style="color:#770088">throws</span> <span style="color:#000000">IOException</span>, <span style="color:#000000">ServletException</span> {
        <span style="color:#000000">HttpServletRequest</span> <span style="color:#000000">request</span> <span style="color:#981a1a">=</span> (<span style="color:#000000">HttpServletRequest</span>) <span style="color:#000000">servletRequest</span>;
        <span style="color:#000000">HttpServletResponse</span> <span style="color:#000000">response</span> <span style="color:#981a1a">=</span> (<span style="color:#000000">HttpServletResponse</span>) <span style="color:#000000">servletResponse</span>;
​
        <span style="color:#aa5500">//1、获取本次请求的URI</span>
        <span style="color:#008855">String</span> <span style="color:#000000">requestURI</span> <span style="color:#981a1a">=</span> <span style="color:#000000">request</span>.<span style="color:#000000">getRequestURI</span>();<span style="color:#aa5500">// /backend/index.html</span>
​
        <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"拦截到请求:{}"</span>,<span style="color:#000000">requestURI</span>);
​
        <span style="color:#aa5500">//定义不需要处理的请求路径</span>
        <span style="color:#008855">String</span>[] <span style="color:#000000">urls</span> <span style="color:#981a1a">=</span> <span style="color:#770088">new</span> <span style="color:#008855">String</span>[]{
                <span style="color:#aa1111">"/employee/login"</span>,
                <span style="color:#aa1111">"/employee/logout"</span>,
                <span style="color:#aa1111">"/backend/**"</span>,
                <span style="color:#aa1111">"/front/**"</span>
        };
        
        <span style="color:#aa5500">//2、判断本次请求是否需要处理</span>
        <span style="color:#008855">boolean</span> <span style="color:#000000">check</span> <span style="color:#981a1a">=</span> <span style="color:#000000">check</span>(<span style="color:#000000">urls</span>, <span style="color:#000000">requestURI</span>);
​
        <span style="color:#aa5500">//3、如果不需要处理,则直接放行</span>
        <span style="color:#770088">if</span>(<span style="color:#000000">check</span>){
            <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"本次请求{}不需要处理"</span>,<span style="color:#000000">requestURI</span>);
            <span style="color:#000000">filterChain</span>.<span style="color:#000000">doFilter</span>(<span style="color:#000000">request</span>,<span style="color:#000000">response</span>);
            <span style="color:#770088">return</span>;
        }
        
        <span style="color:#aa5500">//4、判断登录状态,如果已登录,则直接放行</span>
        <span style="color:#770088">if</span>(<span style="color:#000000">request</span>.<span style="color:#000000">getSession</span>().<span style="color:#000000">getAttribute</span>(<span style="color:#aa1111">"employee"</span>) <span style="color:#981a1a">!=</span> <span style="color:#221199">null</span>){
            <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"用户已登录,用户id为:{}"</span>,<span style="color:#000000">request</span>.<span style="color:#000000">getSession</span>().<span style="color:#000000">getAttribute</span>(<span style="color:#aa1111">"employee"</span>));
            <span style="color:#000000">filterChain</span>.<span style="color:#000000">doFilter</span>(<span style="color:#000000">request</span>,<span style="color:#000000">response</span>);
            <span style="color:#770088">return</span>;
        }
​
        <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"用户未登录"</span>);
        <span style="color:#aa5500">//5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据</span>
        <span style="color:#000000">response</span>.<span style="color:#000000">getWriter</span>().<span style="color:#000000">write</span>(<span style="color:#000000">JSON</span>.<span style="color:#000000">toJSONString</span>(<span style="color:#000000">R</span>.<span style="color:#000000">error</span>(<span style="color:#aa1111">"NOTLOGIN"</span>)));
        <span style="color:#770088">return</span>;
​
    }
​
    <span style="color:#aa5500">/**</span>
     <span style="color:#aa5500">* 路径匹配,检查本次请求是否需要放行</span>
     <span style="color:#aa5500">* @param urls</span>
     <span style="color:#aa5500">* @param requestURI</span>
     <span style="color:#aa5500">* @return</span>
     <span style="color:#aa5500">*/</span>
    <span style="color:#770088">public</span> <span style="color:#008855">boolean</span> <span style="color:#000000">check</span>(<span style="color:#008855">String</span>[] <span style="color:#000000">urls</span>,<span style="color:#008855">String</span> <span style="color:#000000">requestURI</span>){
        <span style="color:#770088">for</span> (<span style="color:#008855">String</span> <span style="color:#000000">url</span> : <span style="color:#000000">urls</span>) {
            <span style="color:#008855">boolean</span> <span style="color:#000000">match</span> <span style="color:#981a1a">=</span> <span style="color:#000000">PATH_MATCHER</span>.<span style="color:#000000">match</span>(<span style="color:#000000">url</span>, <span style="color:#000000">requestURI</span>);
            <span style="color:#770088">if</span>(<span style="color:#000000">match</span>){
                <span style="color:#770088">return</span> <span style="color:#221199">true</span>;
            }
        }
        <span style="color:#770088">return</span> <span style="color:#221199">false</span>;
    }
}</span></span>

AntPathMatcher 拓展: 介绍: Spring中提供的路径匹配器 ; 通配符规则: 符号含义?匹配一个字符*匹配0个或多个字符**匹配0个或多个目录/字符

2). 开启组件扫描

需要在引导类上, 加上Servlet组件扫描的注解, 来扫描过滤器配置的@WebFilter注解, 扫描上之后, 过滤器在运行时就生效了。

代码语言:javascript
复制
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#555555">@Slf4j</span>
<span style="color:#555555">@SpringBootApplication</span>
<span style="color:#555555">@ServletComponentScan</span>
<span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">ReggieApplication</span> {
    <span style="color:#770088">public</span> <span style="color:#770088">static</span> <span style="color:#008855">void</span> <span style="color:#000000">main</span>(<span style="color:#008855">String</span>[] <span style="color:#000000">args</span>) {
        <span style="color:#000000">SpringApplication</span>.<span style="color:#000000">run</span>(<span style="color:#000000">ReggieApplication</span>.<span style="color:#770088">class</span>,<span style="color:#000000">args</span>);
        <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"项目启动成功..."</span>);
    }
}</span></span>

@ServletComponentScan 的作用:  在SpringBoot项目中, 在引导类/配置类上加了该注解后, 会自动扫描项目中(当前包及其子包下)的@WebServlet , @WebFilter , @WebListener 注解, 自动注册Servlet的相关组件 ;

1.4 功能测试

代码编写完毕之后,我们需要将工程重启一下,然后在浏览器地址栏直接输入系统管理后台首页,然后看看是否可以跳转到登录页面即可。我们也可以通过debug的形式来跟踪一下代码执行的过程。

对于前端的代码, 也可以进行debug调试。

F12打开浏览器的调试工具, 找到我们前面提到的request.js, 在request.js的响应拦截器位置打上断点。

2. 新增员工

2.1 需求分析

后台系统中可以管理员工信息,通过新增员工来添加后台系统用户。点击[添加员工]按钮跳转到新增页面,如下:

当填写完表单信息, 点击"保存"按钮后, 会提交该表单的数据到服务端, 在服务端中需要接受数据, 然后将数据保存至数据库中。

2.2 数据模型

新增员工,其实就是将我们新增页面录入的员工数据插入到employee表。employee表中的status字段已经设置了默认值1,表示状态正常。

需要注意,employee表中对username字段加入了唯一约束,因为username是员工的登录账号,必须是唯一的。

2.3 程序执行流程

在开发代码之前,我们需要结合着前端页面发起的请求, 梳理一下整个程序的执行过程:

A. 点击"保存"按钮, 页面发送ajax请求,将新增员工页面中输入的数据以json的形式提交到服务端, 请求方式POST, 请求路径 /employee

B. 服务端Controller接收页面提交的数据并调用Service将数据进行保存

C. Service调用Mapper操作数据库,保存数据

2.4 代码实现

在EmployeeController中增加save方法, 用于保存用户员工信息。

A. 在新增员工时, 按钮页面原型中的需求描述, 需要给员工设置初始默认密码 123456, 并对密码进行MD5加密。

B. 在组装员工信息时, 还需要封装创建时间、修改时间,创建人、修改人信息(从session中获取当前登录用户)。

代码语言:javascript
复制
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#aa5500">/**</span>
 <span style="color:#aa5500">* 新增员工</span>
 <span style="color:#aa5500">* @param employee</span>
 <span style="color:#aa5500">* @return</span>
 <span style="color:#aa5500">*/</span>
<span style="color:#555555">@PostMapping</span>
<span style="color:#770088">public</span> <span style="color:#000000">R</span><span style="color:#981a1a"><</span><span style="color:#008855">String</span><span style="color:#981a1a">></span> <span style="color:#0000ff">save</span>(<span style="color:#000000">HttpServletRequest</span> <span style="color:#000000">request</span>,<span style="color:#555555">@RequestBody</span> <span style="color:#000000">Employee</span> <span style="color:#000000">employee</span>){
    <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"新增员工,员工信息:{}"</span>,<span style="color:#000000">employee</span>.<span style="color:#000000">toString</span>());
​
    <span style="color:#aa5500">//设置初始密码123456,需要进行md5加密处理</span>
    <span style="color:#000000">employee</span>.<span style="color:#000000">setPassword</span>(<span style="color:#000000">DigestUtils</span>.<span style="color:#000000">md5DigestAsHex</span>(<span style="color:#aa1111">"123456"</span>.<span style="color:#000000">getBytes</span>()));
    
    <span style="color:#000000">employee</span>.<span style="color:#000000">setCreateTime</span>(<span style="color:#000000">LocalDateTime</span>.<span style="color:#000000">now</span>());
    <span style="color:#000000">employee</span>.<span style="color:#000000">setUpdateTime</span>(<span style="color:#000000">LocalDateTime</span>.<span style="color:#000000">now</span>());
    
    <span style="color:#aa5500">//获得当前登录用户的id</span>
    <span style="color:#008855">Long</span> <span style="color:#000000">empId</span> <span style="color:#981a1a">=</span> (<span style="color:#008855">Long</span>) <span style="color:#000000">request</span>.<span style="color:#000000">getSession</span>().<span style="color:#000000">getAttribute</span>(<span style="color:#aa1111">"employee"</span>);
​
    <span style="color:#000000">employee</span>.<span style="color:#000000">setCreateUser</span>(<span style="color:#000000">empId</span>);
    <span style="color:#000000">employee</span>.<span style="color:#000000">setUpdateUser</span>(<span style="color:#000000">empId</span>);
​
    <span style="color:#000000">employeeService</span>.<span style="color:#000000">save</span>(<span style="color:#000000">employee</span>);
    <span style="color:#770088">return</span> <span style="color:#000000">R</span>.<span style="color:#000000">success</span>(<span style="color:#aa1111">"新增员工成功"</span>);
}</span></span>

2.5 功能测试

代码编写完毕之后,我们需要将工程重启, 完毕之后直接访问管理系统首页, 点击 "员工管理" 页面中的 "添加员工" 按钮, 输入员工基本信息, 然后点击 "保存" 进行数据保存, 保存完毕后, 检查数据库中是否录入员工数据。

当我们在测试中,添加用户时, 输入了一个已存在的用户名时,前端界面出现错误提示信息:

而此时,服务端已经报错了, 报错信息如下:

出现上述的错误, 主要就是因为在 employee 表结构中,我们针对于username字段,建立了唯一索引,添加重复的username数据时,违背该约束,就会报错。但是此时前端提示的信息并不具体,用户并不知道是因为什么原因造成的该异常,我们需要给用户提示详细的错误信息 。

2.6 全局异常处理

2.6.1 思路分析

要想解决上述测试中存在的问题,我们需要对程序中可能出现的异常进行捕获,通常有两种处理方式:

A. 在Controller方法中加入 try...catch 进行异常捕获

形式如下:

如果采用这种方式,虽然可以解决,但是存在弊端,需要我们在保存其他业务数据时,也需要在Controller方法中加上try...catch进行处理,代码冗余,不通用。

B. 使用异常处理器进行全局异常捕获

采用这种方式来实现,我们只需要在项目中定义一个通用的全局异常处理器,就可以解决本项目的所有异常。

2.6.2 全局异常处理器

在项目中自定义一个全局异常处理器,在异常处理器上加上注解 @ControllerAdvice,可以通过属性annotations指定拦截哪一类的Controller方法。 并在异常处理器的方法上加上注解 @ExceptionHandler 来指定拦截的是那一类型的异常。

异常处理方法逻辑:

  • 指定捕获的异常类型为 SQLIntegrityConstraintViolationException
  • 解析异常的提示信息, 获取出是那个值违背了唯一约束
  • 组装错误信息并返回

所属包: com.itheima.reggie.common

代码语言:javascript
复制
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#770088">import</span> <span style="color:#000000">lombok</span>.<span style="color:#000000">extern</span>.<span style="color:#000000">slf4j</span>.<span style="color:#000000">Slf4j</span>;
<span style="color:#770088">import</span> <span style="color:#000000">org</span>.<span style="color:#000000">springframework</span>.<span style="color:#000000">stereotype</span>.<span style="color:#000000">Controller</span>;
<span style="color:#770088">import</span> <span style="color:#000000">org</span>.<span style="color:#000000">springframework</span>.<span style="color:#000000">web</span>.<span style="color:#000000">bind</span>.<span style="color:#000000">annotation</span>.<span style="color:#000000">ControllerAdvice</span>;
<span style="color:#770088">import</span> <span style="color:#000000">org</span>.<span style="color:#000000">springframework</span>.<span style="color:#000000">web</span>.<span style="color:#000000">bind</span>.<span style="color:#000000">annotation</span>.<span style="color:#000000">ExceptionHandler</span>;
<span style="color:#770088">import</span> <span style="color:#000000">org</span>.<span style="color:#000000">springframework</span>.<span style="color:#000000">web</span>.<span style="color:#000000">bind</span>.<span style="color:#000000">annotation</span>.<span style="color:#000000">ResponseBody</span>;
<span style="color:#770088">import</span> <span style="color:#000000">org</span>.<span style="color:#000000">springframework</span>.<span style="color:#000000">web</span>.<span style="color:#000000">bind</span>.<span style="color:#000000">annotation</span>.<span style="color:#000000">RestController</span>;
<span style="color:#770088">import</span> <span style="color:#000000">java</span>.<span style="color:#000000">sql</span>.<span style="color:#000000">SQLIntegrityConstraintViolationException</span>;
​
<span style="color:#aa5500">/**</span>
 <span style="color:#aa5500">* 全局异常处理</span>
 <span style="color:#aa5500">*/</span>
<span style="color:#555555">@ControllerAdvice</span>(<span style="color:#000000">annotations</span> <span style="color:#981a1a">=</span> {<span style="color:#000000">RestController</span>.<span style="color:#770088">class</span>, <span style="color:#000000">Controller</span>.<span style="color:#770088">class</span>})
<span style="color:#555555">@ResponseBody</span>
<span style="color:#555555">@Slf4j</span>
<span style="color:#770088">public</span> <span style="color:#770088">class</span>  <span style="color:#0000ff">GlobalExceptionHandler</span> {
​
    <span style="color:#aa5500">/**</span>
     <span style="color:#aa5500">* 异常处理方法</span>
     <span style="color:#aa5500">* @return</span>
     <span style="color:#aa5500">*/</span>
    <span style="color:#555555">@ExceptionHandler</span>(<span style="color:#000000">SQLIntegrityConstraintViolationException</span>.<span style="color:#770088">class</span>)
    <span style="color:#770088">public</span> <span style="color:#000000">R</span><span style="color:#981a1a"><</span><span style="color:#008855">String</span><span style="color:#981a1a">></span> <span style="color:#000000">exceptionHandler</span>(<span style="color:#000000">SQLIntegrityConstraintViolationException</span> <span style="color:#000000">ex</span>){
        <span style="color:#000000">log</span>.<span style="color:#000000">error</span>(<span style="color:#000000">ex</span>.<span style="color:#000000">getMessage</span>());
        <span style="color:#770088">if</span>(<span style="color:#000000">ex</span>.<span style="color:#000000">getMessage</span>().<span style="color:#000000">contains</span>(<span style="color:#aa1111">"Duplicate entry"</span>)){
            <span style="color:#008855">String</span>[] <span style="color:#000000">split</span> <span style="color:#981a1a">=</span> <span style="color:#000000">ex</span>.<span style="color:#000000">getMessage</span>().<span style="color:#000000">split</span>(<span style="color:#aa1111">" "</span>);
            <span style="color:#008855">String</span> <span style="color:#000000">msg</span> <span style="color:#981a1a">=</span> <span style="color:#000000">split</span>[<span style="color:#116644">2</span>] <span style="color:#981a1a">+</span> <span style="color:#aa1111">"已存在"</span>;
            <span style="color:#770088">return</span> <span style="color:#000000">R</span>.<span style="color:#000000">error</span>(<span style="color:#000000">msg</span>);
        }
        <span style="color:#770088">return</span> <span style="color:#000000">R</span>.<span style="color:#000000">error</span>(<span style="color:#aa1111">"未知错误"</span>);
    }
}</span></span>

注解说明: 上述的全局异常处理器上使用了的两个注解 @ControllerAdvice , @ResponseBody , 他们的作用分别为: @ControllerAdvice : 指定拦截那些类型的控制器; @ResponseBody: 将方法的返回值 R 对象转换为json格式的数据, 响应给页面; 上述使用的两个注解, 也可以合并成为一个注解 @RestControllerAdvice

2.6.3 测试

全局异常处理器编写完毕之后,我们需要将项目重启, 完毕之后直接访问管理系统首页, 点击 "员工管理" 页面中的 "添加员工" 按钮。当我们在测试中,添加用户时, 输入了一个已存在的用户名时,前端界面出现如下错误提示信息:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 完善登录功能
    • 1.1 问题分析
      • 1.2 思路分析
        • 1.3 代码实现
          • 1.4 功能测试
          • 2. 新增员工
            • 2.1 需求分析
              • 2.2 数据模型
                • 2.3 程序执行流程
                  • 2.4 代码实现
                    • 2.5 功能测试
                      • 2.6 全局异常处理
                      相关产品与服务
                      访问管理
                      访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档