Java --- 云尚办公角色管理模块实现

news2024/9/22 21:36:03

目录

一、项目介绍

1.1、项目简介

1.2、技术框架

 1.3、项目构建

1.4、配置依赖

二、mybatis-plus测试使用

三、角色管理

 3.1、完善统一返回信息

 3.2、整合knife4j

 3.3、分页查询功能

 3.4、添加、修改、删除功能

3.5、完善时间格式

3.6、异常统一处理

四、前端知识

4.1、vs code 安装与使用

4.1.1、创建文件夹,并添加到工作区 

4.1.2、测试功能

4.2、ES6知识

4.2.1、模板字符串 

 4.2.2、对象扩展运算符

4.2.3、箭头函数

4.3、vue基础

 4.3.1、vue入门案例

4.3.2、vue生命周期

 4.3.3、Axios

4.4、node.js

五、前端框架启动

5.1、修改前端登录访问路径 

5.2、角色增加修改删除前端构建

一、项目介绍

1.1、项目简介

云尚办公系统是一套自动办公系统,系统主要包含:管理端和员工端

管理端包含:权限管理、审批管理、公众号菜单管理

员工端采用微信公众号操作,包含:办公审批、微信授权登录、消息推送等功能

项目服务器端架构:SpringBoot + MyBatisPlus + SpringSecurity + Redis + Activiti+ MySQL

前端架构:vue-admin-template + Node.js + Npm + Vue + ElementUI + Axios

1.2、技术框架

基础框架:SpringBoot 
数据缓存:Redis
数据库:MySQL  
权限控制:SpringSecurity
工作流引擎:Activiti 
前端技术:vue-admin-template + Node.js + Npm + Vue + ElementUI + Axios |
微信公众号:公众号菜单 + 微信授权登录 + 消息推送

 1.3、项目构建

1.4、配置依赖

父工程依赖:

 <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <java.version>1.8</java.version>
        <mybatis-plus.version>3.4.1</mybatis-plus.version>
        <mysql.version>8.0.30</mysql.version>
        <knife4j.version>3.0.3</knife4j.version>
        <jwt.version>0.9.1</jwt.version>
        <fastjson.version>2.0.21</fastjson.version>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.11</version>
    </parent>
    <!--配置dependencyManagement锁定依赖的版本-->
       <dependencyManagement>
        <dependencies>
            <!--mybatis-plus 持久层-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--knife4j-->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
                <version>${knife4j.version}</version>
            </dependency>
            <!--jjwt-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>${jwt.version}</version>
            </dependency>
            <!--fastjson-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
        </dependencies>
       </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

 common-util模块依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>provided </scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
    </dependencies>

service-util模块依赖

<dependencies>
        <dependency>
            <groupId>org.cjc</groupId>
            <artifactId>common-util</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

model依赖

<dependencies>
        <!--lombok用来简化实体类-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <scope>provided </scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <scope>provided </scope>
        </dependency>
    </dependencies>

service-oa依赖

    <dependencies>
        <dependency>
            <groupId>org.cjc</groupId>
            <artifactId>model</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.cjc</groupId>
            <artifactId>service-util</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

二、mybatis-plus测试使用

 改yml

application.yml

spring:
  application:
    name: service-oa
  profiles:
    active: dev

application-dev.yml

server:
  port: 8080
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/yaya-oa?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8
    username: root
    password: 123456

数据库表

CREATE DATABASE `yaya-oa` ;
USE `yaya-oa`;

CREATE TABLE `sys_role` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '角色id',
  `role_name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '角色名称',
  `role_code` VARCHAR(20) DEFAULT NULL COMMENT '角色编码',
  `description` VARCHAR(255) DEFAULT NULL COMMENT '描述',
  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `is_deleted` TINYINT(3) NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COMMENT='角色';

测试代码

@Mapper
public interface SysRoleMapper extends BaseMapper<SysRole> {

}

service层 

public interface SysRoleService extends IService<SysRole> {
}
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper,SysRole> implements SysRoleService {

}
@SpringBootTest
public class MapperTest {
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysRoleService service;
    /**
     * 查询所有记录
     */
    @Test
    public void getAll(){
        List<SysRole> sysRoles = sysRoleMapper.selectList(null);
        System.out.println(sysRoles);
    }

    /**
     * 添加操作
     */
    @Test
    public void getAdd(){
        SysRole sysRole = new SysRole();
        sysRole.setRoleName("权限管理员");
        sysRole.setDescription("权限管理员");
        sysRole.setRoleCode("power");
        sysRoleMapper.insert(sysRole);
    }

    /**
     * 修改功能
     */
    @Test
    public void getUpdate(){
        //根据id查询
        SysRole sysRole = sysRoleMapper.selectById(10);
        //设置修改值
        sysRole.setRoleName("权限管理员1");
        sysRoleMapper.updateById(sysRole);
    }

    /**
     * 根据id删除
     */
    @Test
    public void getDelete(){
        sysRoleMapper.deleteById(10);
    }
    /**
     * 批量删除
     */
    @Test
    public void getDeleteBatch(){
        sysRoleMapper.deleteBatchIds(Arrays.asList(1,2));
    }

    /**
     * 条件查询
     */
    @Test
    public void query(){
        //创建QueryWrapper对象,调用封装方法
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_name","管理员");
        List<SysRole> sysRoles = sysRoleMapper.selectList(queryWrapper);
        System.out.println(sysRoles);
    }
    @Test
    public void query1(){
        //创建LambdaQueryWrapper对象,调用封装方法
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleName,"管理员");
        List<SysRole> sysRoles = sysRoleMapper.selectList(queryWrapper);
        System.out.println(sysRoles);
    }
    @Test
    public void query2(){
        List<SysRole> list = service.list();
        System.out.println(list);
    }
}

三、角色管理

 3.1、完善统一返回信息

@Getter
public enum ResultCodeEnum {
    SUCCESS(200,"成功"),
    FAIL(201, "失败");

    private Integer code;
    private String message;

     private ResultCodeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}
@Data
public class Result<T> {
    private Integer code;//状态码
    private String message;//返回信息
    private T data;//数据信息
    //构造方法私有
    private Result() {
    }
    //返回数据
    public static <T> Result<T> build(T body,ResultCodeEnum resultCodeEnum){
        Result<T> result = new Result<>();
        //封装数据
        if (body != null){
            result.setData(body);
        }
        //状态码
        result.setCode(resultCodeEnum.getCode());
        //返回信息
        result.setMessage(resultCodeEnum.getMessage());
        return result;
    }
    //请求成功,无数据
    public static <T> Result<T> ok(){
        return build(null,ResultCodeEnum.SUCCESS);
    }
    //请求成功,有数据
    public static<T> Result<T> ok(T data){
        return build(data,ResultCodeEnum.SUCCESS);
    }
    //请求失败,无数据
    public static<T> Result<T> fail(){
        return build(null,ResultCodeEnum.FAIL);
    }
    //请求失败,有数据
    public static<T> Result<T> fail(T data){
        return build(data,ResultCodeEnum.FAIL);
    }
    //自定义返回信息
    public Result<T> message(String msg){
        this.setMessage(msg);
        return this;
    }

    public Result<T> code(Integer code){
        this.setCode(code);
        return this;
    }
}
@RestController
@RequestMapping("/admin/system/sysRole")
public class SysRoleController {
    @Autowired
    private SysRoleService sysRoleService;

    /**
     * 查询所有角色
     * @return SysRole
     */
//    @GetMapping("/findAll")
//    public List<SysRole> findAll(){
//        return sysRoleService.list();
//    }
    //统一返回数据结果
    @GetMapping("/findAll")
    public Result findAll(){
        List<SysRole> list = sysRoleService.list();
        return Result.ok(list);
    }
}

 3.2、整合knife4j

        <!--knife4j-->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
        </dependency>
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfig {
    @Bean
    public Docket adminApiConfig(){
        List<Parameter> pars = new ArrayList<>();
        ParameterBuilder tokenPar = new ParameterBuilder();
        tokenPar.name("token")
                .description("用户token")
                .defaultValue("")
                .modelRef(new ModelRef("string"))
                .parameterType("header")
                .required(false)
                .build();
        pars.add(tokenPar.build());
        //添加head参数end

        Docket adminApi = new Docket(DocumentationType.SWAGGER_2)
                .groupName("adminApi")
                .apiInfo(adminApiInfo())
                .select()
                //只显示admin路径下的页面
                .apis(RequestHandlerSelectors.basePackage("com.cjc"))
                .paths(PathSelectors.regex("/admin/.*"))
                .build()
                .globalOperationParameters(pars);
        return adminApi;
    }

    private ApiInfo adminApiInfo(){
        return new ApiInfoBuilder()
                .title("后台管理系统-API文档")
                .description("本文档描述了后台管理系统微服务接口定义")
                .version("1.0")
                .contact(new Contact("yaya", "http://yaya.com", "yaya@qq.com"))
                .build();
    }
}

异常报错: 

org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
    at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.27.jar:5.3.27]
    at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.27.jar:5.3.27]
    at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.3.27.jar:5.3.27]
    at java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_321]
    at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-5.3.27.jar:5.3.27]
    at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-5.3.27.jar:5.3.27]
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:937) ~[spring-context-5.3.27.jar:5.3.27]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.27.jar:5.3.27]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.11.jar:2.7.11]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) [spring-boot-2.7.11.jar:2.7.11]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) [spring-boot-2.7.11.jar:2.7.11]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-2.7.11.jar:2.7.11]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) [spring-boot-2.7.11.jar:2.7.11]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) [spring-boot-2.7.11.jar:2.7.11]
    at com.cjc.auth.ServiceAuthApplication.main(ServiceAuthApplication.java:11) [classes/:na]

解决方案:

在配置文件中进行配置

 访问地址:http://localhost:8080/doc.html#/home

 3.3、分页查询功能

@Configuration
@MapperScan("com.cjc.auth.mapper")
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }
}
    /**
     *
     * @param page 当前页
     * @param limit 每页显示记录数
     * sysRoleQueryVo 条件对象
     * @return
     */
    @ApiOperation("条件分页查询")
    @GetMapping("/pageQuery/{page}/{limit}")
    public Result pageQuery(@PathVariable("page") Long page,
                            @PathVariable("limit") Long limit,
                            SysRoleQueryVo sysRoleQueryVo){
        //创建Page对象,传递分页相关参数
        Page<SysRole> rolePage = new Page<>(page,limit);
        //封装条件
        String roleName = sysRoleQueryVo.getRoleName();
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        //如果传值就模糊查询
        if (StringUtils.hasLength(roleName)){
            wrapper.like(SysRole::getRoleName,roleName);
        }
        return Result.ok(sysRoleService.page(rolePage, wrapper));
    }

 3.4、添加、修改、删除功能

    @ApiOperation("添加角色")
    @PostMapping("/save")
    public Result save(@RequestBody SysRole role){
        boolean save = sysRoleService.save(role);
        if (save){
            return Result.ok();
        }
        return Result.fail();
    }
    @ApiOperation("根据id查询")
    @GetMapping("/getById/{id}")
    public Result getById(@PathVariable("id") Long id){
        SysRole sysRole = sysRoleService.getById(id);
        return Result.ok(sysRole);
    }
    @ApiOperation("修改角色")
    @PutMapping("/updateById")
    public Result updateById(@RequestBody SysRole role){
        boolean updateById = sysRoleService.updateById(role);
        if (updateById){
            return Result.ok();
        }
        return Result.fail();
    }
    @ApiOperation("根据id删除角色")
    @DeleteMapping("/deleteById/{id}")
    public Result deleteById(@PathVariable("id") Long id){
        boolean removeById = sysRoleService.removeById(id);
        if (removeById){
            return Result.ok();
        }
        return Result.fail();
    }
    @ApiOperation("批量删除角色")
    @DeleteMapping("/deleteBatch")
    public Result deleteBatch(@RequestBody List<Long> list){
        boolean removeByIds = sysRoleService.removeByIds(list);
        if (removeByIds){
            return Result.ok();
        }
        return Result.fail();
    }

3.5、完善时间格式

3.6、异常统一处理

/**
 * 自定义异常处理
 */
@Data
@ToString
public class CJCException extends RuntimeException{
    private Integer code;//状态码
    private String msg;//返回信息

    public CJCException(Integer code,String msg){
        super(msg);
        this.code = code;
        this.msg = msg;
    }

    /**
     * 接收枚举类型
     * @param resultCodeEnum
     */
    public CJCException(ResultCodeEnum resultCodeEnum){
        super(resultCodeEnum.getMessage());
        this.code = resultCodeEnum.getCode();
        this.msg = resultCodeEnum.getMessage();
    }
}
@ControllerAdvice
public class GlobalException {
    //全局异常处理方法
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result error(Exception e){
        e.printStackTrace();
        return Result.fail().message("执行全局异常处理");
    }
    //特定异常处理
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public Result error(ArithmeticException e){
        e.printStackTrace();
        return Result.fail().message("特定异常处理");
    }
    //自定义异常处理
    @ExceptionHandler(CJCException.class)
    @ResponseBody
    public Result error(CJCException e){
        e.printStackTrace();
        return Result.fail().code(e.getCode()).message(e.getMsg());
    }
}
 @ApiOperation("查询所有角色")
    @GetMapping("/findAll")
    public Result findAll(){
        List<SysRole> list = sysRoleService.list();
        //模拟异常
        try {
            int i = 10 /0;
        } catch (Exception e) {
            throw new CJCException(500,"执行自定义异常");
        }
        return Result.ok(list);
    }

四、前端知识

4.1、vs code 安装与使用

4.1.1、创建文件夹,并添加到工作区 

4.1.2、测试功能

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>hello</h1>
</body>
</html>

4.2、ES6知识

4.2.1、模板字符串 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        var name = "lucy"
        var age = 10
        //使用模板字符串 + 表达式
        //模板字符串符号:``
        //表达式:${}
        var info = `名字是:${name},年龄加1:${age + 1}`
        console.log(info)
    </script>
</body>
</html>

 4.2.2、对象扩展运算符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        let person1 = {name: "tom",age: 15}
        //对象复制
        let someone = {...person1}
        console.log(someone)
    </script>
</body>
</html>

4.2.3、箭头函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        var f1 = function(a){
            return a;
        }
        console.log(f1(2))

        var f2 = b => b
        console.log(f2(5))

        var f3 = function(x,y){
            return x + y;
        }
        console.log(f3(3,4))
        var f4 = (z,c) => z*c
        console.log(f4(9,7))
    </script>
</body>
</html>

4.3、vue基础

 4.3.1、vue入门案例

需要下载导入vue.min.js文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        {{message}}
    </div>
    <script src="vue.min.js"></script>
    <script>
       new Vue({
          el: '#app',
          data: {
            message:'hello vue'
          }
        })
    </script>
</body>
</html>

4.3.2、vue生命周期

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        {{message}}
    </div>
    <script src="vue.min.js"></script>
    <script>
       new Vue({
          el: '#app',
          data: {
            message:'hello vue'
          },
          created(){ //在渲染前执行
            debugger
             console.log('created')
          },
          mounted(){ //在渲染后执行
            debugger
            console.log('mounted')
          }
        })
    </script>
</body>
</html>

 4.3.3、Axios

需要引入axios.min.js文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="vue.min.js"></script>
    <script src="axios.min.js"></script>
    <div id="app">

    </div>
    <script>
    new Vue({
          el: '#app',
          data: {
            userList:[] //列表数组
          },
          created(){ //在渲染前执行
            //调用方法
             this.getList()
          },
          methods:{ //在渲染后执行
            //使用axios发送ajax请求
            getList(){
               axios.get("data.json")
                    //得到接口或者文件数据
                    .then(response => {
                        // console.log(response)
                        this.userList = response.data.data
                        console.log(this.userList)
                    })
                    //失败调用catch方法
                    .catch(error => {
                        console.log(error)
                    })
            }
          }
        })
    </script>
</body>
</html>
{
    "success":true,
    "code":200,
    "data":[
        {"name":"tom","age":12},
        {"name":"jack","age":15}
    ]
}

4.4、node.js

console.log('hello node.js')

五、前端框架启动

 启动命令:npm run dev

5.1、修改前端登录访问路径 

 

 proxy: {
      '/dev-api': { // 匹配所有以 '/dev-api'开头的请求路径
        target: 'http://localhost:8080',
        changeOrigin: true, // 支持跨域
        pathRewrite: { // 重写路径: 去掉路径中开头的'/dev-api'
          '^/dev-api': ''
        }
      }
    }

export function login(data) {
  return request({
    url: '/admin/system/index/login',
    method: 'post',
    data
  })
}

export function getInfo(token) {
  return request({
    url: '/admin/system/index/info',
    method: 'get',
    params: { token }
  })
}

export function logout() {
  return request({
    url: '/admin/system/index/logout',
    method: 'post'
  })
}

if (res.code !== 200) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })

 后端代码:

@RestController
@Api(tags = "后台登录模块")
@RequestMapping("/admin/system/index")
public class IndexController {
    //
    @PostMapping("/login")
    public Result login(){
        HashMap<String,String > map = new HashMap<>();
        map.put("token","admin-token");
        return Result.ok(map);
    }
    @GetMapping("/info")
    public Result info(){
        Map<String, Object> map = new HashMap<>();
        map.put("roles","[admin]");
        map.put("name","admin");
        map.put("avatar","https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
        return Result.ok(map);
    }
    @PostMapping("/logout")
    public Result logout(){
        return Result.ok();
    }
}

5.2、角色增加修改删除前端构建

import request from '@/utils/request'

const api_name = '/admin/system/sysRole'

export default {
  // 角色列表-条件分页查询
  getPageList(current, limit, searchObj) {
    return request({
      url: `${api_name}/pageQuery/${current}/${limit}`,
      method: 'get',
      // 普通对象参数
      params: searchObj
    })
  },
  // 删除角色
  deleteById(id) {
    return request({
      url: `${api_name}/deleteById/${id}`,
      method: 'delete'
    })
  },
  // 添加角色
  saveRole(role) {
    return request({
      url: `${api_name}/save`,
      method: 'post',
      data: role
    })
  },
  // 根据ID查询
  getById(id) {
    return request({
      url: `${api_name}/getById/${id}`,
      method: 'get'
    })
  },
  // 修改角色
  updateById(role) {
    return request({
      url: `${api_name}/updateById`,
      method: 'put',
      data: role
    })
  },
  // 批量删除
  deleteBatch(idList) {
    return request({
      url: `${api_name}/deleteBatch`,
      method: 'delete',
      data: idList
    })
  }

}
<template>
  <div class="app-container">
    <!--查询表单-->
    <div class="search-div">
      <el-form label-width="70px" size="small">
        <el-row>
          <el-col :span="24">
            <el-form-item label="角色名称">
              <el-input v-model="searchObj.roleName" style="width: 100%" placeholder="角色名称" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="display:flex">
          <el-button type="primary" icon="el-icon-search" size="mini" :loading="loading" @click="fetchData()">搜索</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetData">重置</el-button>
        </el-row>
      </el-form>
    </div>
    <!-- 表格 -->
    <el-table
      v-loading="listLoading"
      :data="list"
      stripe
      border
      style="width: 100%;margin-top: 10px;"
      @selection-change="handleSelectionChange"
    >

      <el-table-column type="selection" />

      <el-table-column
        label="序号"
        width="70"
        align="center"
      >
        <template slot-scope="scope">
          {{ (page - 1) * limit + scope.$index + 1 }}
        </template>
      </el-table-column>

      <el-table-column prop="roleName" label="角色名称" />
      <el-table-column prop="roleCode" label="角色编码" />
      <el-table-column prop="description" label="描述" />
      <el-table-column prop="createTime" label="创建时间" width="160" />
      <el-table-column label="操作" width="200" align="center">
        <template slot-scope="scope">
          <el-button type="primary" icon="el-icon-edit" size="mini" title="修改" @click="edit(scope.row.id)" />
          <el-button type="danger" icon="el-icon-delete" size="mini" title="删除" @click="removeDataById(scope.row.id)" />
        </template>
      </el-table-column>
    </el-table>
    <!-- 工具条 -->
    <div class="tools-div">
      <el-button type="success" icon="el-icon-plus" size="mini" @click="add">添 加</el-button>
      <el-button class="btn-add" size="mini" @click="batchRemove()">批量删除</el-button>
    </div>
    <!-- 分页组件 -->
    <el-pagination
      :current-page="page"
      :total="total"
      :page-size="limit"
      style="padding: 30px 0; text-align: center;"
      layout="total, prev, pager, next, jumper"
      @current-change="fetchData"
    />
    <el-dialog title="添加/修改" :visible.sync="dialogVisible" width="40%">
      <el-form ref="dataForm" :model="sysRole" label-width="150px" size="small" style="padding-right: 40px;">
        <el-form-item label="角色名称">
          <el-input v-model="sysRole.roleName" />
        </el-form-item>
        <el-form-item label="角色编码">
          <el-input v-model="sysRole.roleCode" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="sysRole.description" />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" icon="el-icon-refresh-right" @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" icon="el-icon-check" size="small" @click="saveOrUpdate()">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
// 引入定义接口js文件
import api from '@/api/system/sysRole'
export default {
  //
  data() {
    return {
      list: [], // 角色列表
      page: 1, // 当前页
      limit: 2, // 每页显示记录数
      total: 0, // 总记录数
      searchObj: {}, // 条件对象
      sysRole: {}, // 封装表单角色数据
      dialogVisible: false, // 开/关弹窗
      selection: [] // 多个复选框的值
    }
  },
  created() { // 渲染之前执行
    this.fetchData()
  },
  methods: { // 操作方法
  // 选择复选框,把复选框所在行内容进行传递
    handleSelectionChange(selection) {
      this.selections = selection
      console.log(this.selections)
    },
    // 批量删除
    batchRemove() {
      if (this.selections.length === 0) {
        this.$message.warning('请选择要删除的记录!')
        return
      }
      this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        var idList = []
        // 遍历循序将id添加到数组中
        this.selections.forEach(element => {
          var id = element.id
          idList.push(id)
        })
        return api.deleteBatch(idList)
          .then(response => {
            this.$message.success(response.message || '删除成功')
            this.fetchData()
          })
      })
    },
    // 点击修改弹窗,根据id查询显示
    edit(id) {
      this.dialogVisible = true
      // 根据id查询
      this.fetchDataById(id)
    },
    // 点击添加弹框
    add() {
      this.dialogVisible = true
    },
    // 条件分页查询
    fetchData(current = 1) {
      this.page = current
      api.getPageList(this.page, this.limit, this.searchObj)
        .then(response => {
          this.list = response.data.records
          this.total = response.data.total
        })
    },
    // 删除
    removeDataById(id) {
      this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => { // promise
      // 点击确定,远程调用ajax
        return api.deleteById(id)
      }).then(response => {
        this.fetchData()
        this.$message.success(response.message || '删除成功')
      })
    },
    // 调用添加和修改
    saveOrUpdate() {
      // 根据id判断修改/添加
      if (!this.sysRole.id) {
        this.save()
      } else {
        this.update()
      }
    },
    // 添加
    save() {
      api.saveRole(this.sysRole)
        .then(response => {
          // 提示
          this.$message.success(response.message || '添加成功')
          // 关闭弹窗
          this.dialogVisible = false
          // 刷新界面
          this.fetchData()
        })
    },
    // 修改
    update() {
      api.updateById(this.sysRole)
        .then(response => {
          // 提示
          this.$message.success(response.message || '修改成功')
          // 关闭弹窗
          this.dialogVisible = false
          // 刷新界面
          this.fetchData()
        })
    },
    // 根据id查询
    fetchDataById(id) {
      api.getById(id)
        .then(response => {
          this.sysRole = response.data
        })
    }
  }
}
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/547192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode662.设计循环队列||4种方法实现

目录 题目 思路1(链表) 代码 思路2(数组) 代码 题目 题目要求的队列需要实现的功能有 ①Creat---设置队列长度 ②Front---获取队列头 ③Rear---获取队列尾 ④en----插入元素 ⑤de---删除元素 ⑥empty---判空 ⑦full---判满 思路1(链表) &#x1f50d;普通队列长度没有限制&…

MySQL高级——第16章_多版本并发控制

第16章_多版本并发控制 1. 什么是MVCC MVCC &#xff08;Multiversion Concurrency Control&#xff09;&#xff0c;多版本并发控制。顾名思义&#xff0c;MVCC 是通过数据行的多个版本管理来实现数据库的 并发控制 。这项技术使得在InnoDB的事务隔离级别下执行 一致性读 操…

ARM学习笔记_1 介绍,Keil环境搭建

从零开始学ARM 学习自b站一口linux老师的课程。 文章目录 从零开始学ARM介绍为什么要学汇编&#xff1f;ARM是什么&#xff1f;SOC计算机历史冯诺依曼结构介绍哈佛架构介绍混合架构介绍CPU运行原理 环境搭建 介绍 学习ARM需要学计算机原理&#xff0c;汇编&#xff0c;C语言&…

强大,Midjourney Imagine API接口,AI画画的福音!

前几天跟大家分享过一篇 ”让chatGPT教你AI绘画|如何将chatGPT与Midjourney结合使用&#xff1f;“&#xff0c;但是由于许多小伙伴们使用Midjourney还有许多困难&#xff0c;又要上网&#xff0c;还要注册Discord&#xff0c;MJ的使用成本很高&#xff0c;让大家望而却步&…

【计算机视觉 | 目标检测】目标检测中的评价指标 mAP 理解及计算(含示例)

文章目录 一、目标检测的评价指标1.1 Precision1.2 Recall1.3 Average Precision&#xff08;AP&#xff09;1.4 mean Average Precision&#xff08;mAP&#xff09;1.5 Intersection over Union&#xff08;IoU&#xff09;1.6 F1-score 二、基础知识2.1 Precision2.2 Recall…

5.20下周黄金行情走势分析及开盘独家交易策略

近期有哪些消息面影响黄金走势&#xff1f;下周黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周五(5月19日)&#xff0c;现货黄金价格下跌又反弹&#xff0c;现货黄金持续走高美联储主席鲍威尔&#xff1a;那些积极的供应冲击不太可能重复出现&#xff0c;美联…

初阶数据结构之单链表的实现(四)

文章目录 链表的概念及结构一、链表的逻辑结构是什么样的&#xff1f;二、链表的初始化2.1链表初始化的示意2.2链表初始化代码实现 三、链表的各类接口函数定义四、链表的各类接口函数的代码实现4.1链表的打印代码实现4.1.1打印代码的实现 4.2链表的尾插代码实现4.2.1尾插代码实…

Mongodb 6.0 变化的配置参数与连接的方式变化

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

【故障排查】【伪处理】Jenkins在iframe窗口无法添加secret text凭证

问题描述 环境的ingress是&#xff0c;有个 svc 暴露 30080 -> 80 大致流程&#xff1a; svc&#xff08;ingress-nginx&#xff09; 30080端口 -> pod (nginx-ingress-controller ) 80端口 -> ingress -> svc -> pod &#xff08;Jenkins 8080端口&#xff0…

基于粒子群优化算法的路径问题优化研究及其在Python中的实现

基于粒子群优化算法的路径问题优化研究及其在Python中的实现 文章目录 基于粒子群优化算法的路径问题优化研究及其在Python中的实现一、简介二、引言1、粒子群优化算法简介2、PSO算法与鸟群的类比 三、PSO算法数学原理1、粒子的位置和速度2、适应度函数3、粒子的个体最优和全局…

基于html+css的图展示80

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

从零开始搭建属于自己的hexo博客

前提要素&#xff1a;一个提供博客运行的服务器或者XX云。 先展示一下搭建好的样子&#xff0c;给大家一点动力&#xff1a; 整个搭建过程大概需要30分钟不到&#xff0c;请各位控制自己的时间~ 好了&#xff0c;废话不多说我们开始&#xff01; 1、首先登录我们准备好的服…

redis高级篇二(分片集群)

一)进行测试Sentinel池: ​ Controller public class RestController {RequestMapping("/Java100")ResponseBodypublic String start(){//1.配置信息HashSet<String> setnew HashSet<>();// 连接信息 ip:port// set.add("127.0.0.1:27001");se…

[抓包] 微信小程序(PC版)如何抓包

本文抓包环境 Win10&#xff0c;微信(PC版本) v3.9.2.20&#xff0c;Burp Suite v1.7.32&#xff0c;Proxifier v3.42 不使用安卓模拟器 一、下载安装好Burp Suite&#xff0c;Proxifier 链接: https://pan.baidu.com/s/177BIEgCmZG9MfqQ4D0PTsg 提取码: 3hex 二、开始抓包 …

【ASP.NET Core笔记】 使用razor pages构建网站

使用ASP.NET Core Razor Pages 构建网站 sqlite 北风数据库 1. Northwind.Common.DataContext.Sqlite 是Sqlite的数据库上下文&#xff0c;有三个类&#xff1a;ConsoleLogger.csNorthwindContext.csNorthwindContextExtensions.cs 1.1 NorthwindContext 继承自 Microsoft.Enti…

计算机图形学-GAMES101-10

一、纹理 原模型网格->逐面Shading->逐像素Phong Shading->纹理贴图->换个纹理再贴图->环境光照。 &#xff08;1&#xff09;环境贴图 纹理就是一张图&#xff0c;纹理是GPU里的一块内存&#xff0c;可以进行点查询、范围查询、滤波。  环境光贴图、环境光映…

The authenticity of host ‘gitee.com (212.64.63.190)‘ can‘t be established.

在将本地仓库的代码推送到远程仓库时&#xff0c;出现下面报错。 $ git push -u origin master The authenticity of host gitee.com (212.64.63.190) cant be established. ECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQpKkGYoFgbVr17bmjey0Wc. Are you sure you w…

Kali-linux分析密码

在实现密码破解之前&#xff0c;介绍一下如何分析密码。分析密码的目的是&#xff0c;通过从目标系统、组织中收集信息来获得一个较小的密码字典。本节将介绍使用Ettercap工具或MSFCONSOLE来分析密码。 8.2.1 Ettercap工具 Ettercap是Linux下一个强大的欺骗工具&#xff0c;也…

Mysql中常用到的查询关键字

文章目录 1、join2、like 模糊查询3、or4、distinct5、in 包含6、group by 分组7、order by8、limit 1、join MySQL 的连接主要分为内连接和外连接。 什么是内连接&#xff1a; 取得两张表中满足存在连接匹配关系的记录。 什么是外连接&#xff1a; 不只取得两张表中满足存在…

设计高端大气上档次的时尚品?!微软工程师借助AIGC成功圆梦!

&#xff08;本文阅读时间&#xff1a;5 分钟&#xff09; 在这个创意横飞、想象力爆棚的时代中&#xff0c;有很多美丽且吸引人的东西围绕在我们身边。然而&#xff0c;遗憾的是&#xff0c;被誉为“攻城狮”的我&#xff0c;内心里虽然非常喜欢且欣赏这些夺目的作品&#xff…