结合Redis和MySQL实现的Gateway动态路由

Gateway动态路由

What?

前段时间买了个服务器,没怎么用,就跑了个在线获取IdeaCode的程序。使用率不怎么高,这次准备在跑一个Gateway网关,以后就把我所有的程序都接入到网关里。但是以前网关里的路由都是硬编码的形式写到配置文件里的,这就意味着我每发布一个程序都要重新打包部署一下网关。

程序猿的存在就是解决一些需要频繁操作的事件,所以要想办法解决硬编码路由的问题,所以我写了本篇Gateway动态路由。

思路

Gateway的路由配置有两种方式,一种是通过配置文件配置,一种是通过代码配置。我准备做一个类似于管理系统的系统来管理路由配置,所以要使用代码的方式配置路由。

在项目启动的时候从数据库读取配置并且存到Redis中。Gateway在初始化的时候从Redis中获取配置。

开发前的准备

  1. 一台电脑(废话,没有电脑怎么开发)
  2. Nacos注册中心(路由转发需要用到)
  3. MySQL数据库(持久化的储存路由配置)
  4. Redis(路由配置缓存)
  5. JDK1.8(我是基于JDK1.8做的开发)
  6. Maven(现在可是Maven的天下,总不能一个一个的添加依赖吧)

预览

Github:https://github.com/Ys2025/gateway-backend



Start

1、初始化数据库

CREATE TABLE `gateway_route` (
  `id` bigint NOT NULL,
  `route_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `uri` varchar(255) NOT NULL,
  `predicates` varchar(255) NOT NULL,
  `filters` varchar(255) DEFAULT NULL,
  `ord` int DEFAULT '0',
  `remarks` varchar(255) DEFAULT NULL,
  `create_time` date DEFAULT NULL,
  `update_time` date DEFAULT NULL,
  `is_deleted` int DEFAULT '0',
  `version` int DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

在这里插入图片描述

2、创建一个Gateway项目

启动类

package cn.yanghuisen.gateway;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@MapperScan("cn.yanghuisen.gateway.mapper")
@EnableDiscoveryClient
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }

}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.11.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.yanghuisen</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.yml

server:
  port: 8080
spring:
  application:
    name: GATEWAY
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/gateway_route?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
    username: root
    password: 123456
  redis:
    # Redis地址
    host: localhost
    # Redis端口
    port: 6379
    # RedisDB库
    database: 0
    # 链接超市
    timeout: 10000ms
    lettuce:
      pool:
        # 最大连接数
        max-active: 1024
        # 最大阻塞等待时间
        max-wait: 10000ms
        # 最大空闲时间
        max-idle: 200
        # 最小空闲链接
        min-idle: 5
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      logic-delete-value: 1       # 逻辑已经删除的值(默认为1)
      logic-not-delete-value: 0   # 逻辑没有删除的值(默认为0)

3、配置Redis

package cn.yanghuisen.gateway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author admin
 * @version 1.0
 * @date 2020/5/14 20:52
 * @Description 自定义模板
 */
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory){
        // 创建模板
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        // 设置String类型的Key的序列器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 设置String类型的value的序列器
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        // 设置Hash类型的Key的序列器
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        // 设置hash类型的value的序列器
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        // 设置连接方式
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        return redisTemplate;
    }
}

4、自定义路由储存库(核心1)

此类用于从Redis获取路由配置信息,以及监听的路由保存和删除

package cn.yanghuisen.gateway.config;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Y
 * @date 2020/11/28 0:02
 * @desc 自定义路由储存库
 */
@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {


    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    private static final String GATEWAY_ROUTES = "gateway:routes";


    /**
     * 获取路由信息,此处从Redis获取路由配置信息
     * @return
     */
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        List<RouteDefinition> routeDefinitions = new ArrayList<>();
        // 获取Redis中配置的路由信息
        List<Object> routes = redisTemplate.opsForHash().values(GATEWAY_ROUTES);
        // 遍历路由
        routes.forEach(route->{
            // 把json反序列话为RouteDefinition类对象
            RouteDefinition routeDefinition = JSON.parseObject(route.toString(), RouteDefinition.class);
            routeDefinitions.add(routeDefinition);
        });
        return Flux.fromIterable(routeDefinitions);
    }

    /**
     * 添加路由
     * @param route
     * @return
     */
    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return route.flatMap(routeDefinition -> {
            // 把路由信息存到Redis中
            redisTemplate.opsForHash().put(GATEWAY_ROUTES,routeDefinition.getId(), JSON.toJSONString(routeDefinition));
            return Mono.empty();
        });
    }

    /**
     * 删除路由
     * @param routeId
     * @return
     */
    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return routeId.flatMap(id -> {
            // 判断redis中是否有该id的路由数据
            if (redisTemplate.opsForHash().hasKey(GATEWAY_ROUTES,id)){
                // 删除数据
                redisTemplate.opsForHash().delete(GATEWAY_ROUTES,id);
                return Mono.empty();
            }
            return Mono.defer(()-> Mono.error(new NotFoundException("Redis中没有该路由:"+id)));
        });
    }
}

5、SpringBoot启动配置(核心2)

此类用于在SpringBoot启动的时候从数据库读取路由配置信息,并且把信息储存到Redis中。以及发布路由的增删改事件

package cn.yanghuisen.gateway.handler;

import cn.yanghuisen.gateway.dto.GatewayRouteDTO;
import cn.yanghuisen.gateway.entity.GatewayRoute;
import cn.yanghuisen.gateway.mapper.GatewayRouteMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Y
 * @date 2020/11/28 0:38
 * @desc
 */
@Slf4j
@Component
public class GatewayServiceHandler implements ApplicationEventPublisherAware, CommandLineRunner {

    private static final String GATEWAY_ROUTES = "gateway:routes";

    private ApplicationEventPublisher publisher;

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    @Autowired
    private GatewayRouteMapper gatewayRouteMapper;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher = applicationEventPublisher;
    }

    /**
     * 项目启动的时候执行
     * @param args
     * @throws Exception
     */
    @Override
    public void run(String... args) throws Exception {
        // 记载路由配置
        this.loadRouteConfig();
    }


    public String loadRouteConfig(){
        log.info("开始加载网关路由配置信息");
        // 删除Redis里的路由配置信息
        redisTemplate.delete(GATEWAY_ROUTES);
        // 从数据库查询数据
         List<GatewayRoute> gatewayRoutes = gatewayRouteMapper.selectList(null);
        gatewayRoutes.forEach(gatewayRoute -> {
            RouteDefinition definition = handleData(gatewayRoute);
            // 保存路由
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
        });
        // 发布事件,通知更新数据
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
        return "success";
    }

    /**
     * 保存路由
     * @param dto
     */
    public void saveRoute(GatewayRouteDTO dto){
        GatewayRoute gatewayRoute = new GatewayRoute();
        BeanUtils.copyProperties(dto,gatewayRoute);
        // GatewayRoute转为RouteDefinition
        RouteDefinition definition = handleData(gatewayRoute);
        // 保存路由数据
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
        // 发布事件,通知更新数据
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
    }

    /**
     * 更新路由
     * @param dto
     */
    public void updateRoute(GatewayRouteDTO dto){
        GatewayRoute gatewayRoute = new GatewayRoute();
        BeanUtils.copyProperties(dto,gatewayRoute);
        // GatewayRoute转为RouteDefinition
        RouteDefinition definition = handleData(gatewayRoute);
        // 根据路由ID删除路由信息
        routeDefinitionWriter.delete(Mono.just(dto.getOldRouteId())).subscribe();
        // 重新保存路由数据
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
        // 发布事件,通知更新数据
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
    }

    /**
     * 删除路由
     * @param routeId
     */
    public void deleteRoute(String routeId){
        // 根据路由ID删除路由信息
        routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();
        // 发布事件,通知更新数据
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
        log.info("删除完毕");
    }


    /**
     * GatewayRoute转RouteDefinition
     * @param gatewayRoute
     * @return
     */
    public RouteDefinition handleData(GatewayRoute gatewayRoute){
        RouteDefinition routeDefinition = new RouteDefinition();

        URI uri = null;
        // 判断Uri是不是http地址
        if (gatewayRoute.getUri().startsWith("http")){
            // http地址
            uri = UriComponentsBuilder.fromHttpUrl(gatewayRoute.getUri()).build().toUri();
        }else {
            // 微服务服务名
            uri = UriComponentsBuilder.fromUriString("lb://"+gatewayRoute.getUri()).build().toUri();
        }
        // 设置路由ID
        routeDefinition.setId(gatewayRoute.getRouteId());
        // 设置uri
        routeDefinition.setUri(uri);
        //谓语(路由转发条件)
        PredicateDefinition predicate = new PredicateDefinition();
        predicate.setName("Path");
        Map<String,String> predicateArgs = new HashMap<>();
        predicateArgs.put("pattern",gatewayRoute.getPredicates());
        predicate.setArgs(predicateArgs);
        routeDefinition.setPredicates(Collections.singletonList(predicate));

        // 设置ord
        if (null!=gatewayRoute.getOrd()){
            routeDefinition.setOrder(gatewayRoute.getOrd());
        }
        return routeDefinition;
    }

}

6、创建entity和DTO类

package cn.yanghuisen.gateway.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.util.Date;

/**
 * @author Y
 * @date 2020/11/28 1:16
 * @desc 实体类
 */
@Data
public class GatewayRoute {

    @TableId(type = IdType.ASSIGN_ID)
    private String id;

    private String routeId;

    private String uri;

    private String predicates;

    private String filters;

    private Integer ord;

    private String remarks;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;

    /**
     * 逻辑删除
     */
    @TableLogic
    private Integer isDeleted;

    /**
     * 乐观锁
     */
    @Version
    private Integer version;
}

package cn.yanghuisen.gateway.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * @author Y
 * @date 2020/11/28 1:16
 * @desc DTO类
 */
@Data
public class GatewayRouteDTO {

    private String id;

    private String routeId;

    private String oldRouteId;

    private String uri;

    private String predicates;

    private String filters;

    private Integer ord;

    private String remarks;

    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date createTime;

    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;

    private Integer isDeleted;

    private Integer version;
}

7、创建Service层接口

package cn.yanghuisen.gateway.service;

import cn.yanghuisen.gateway.dto.GatewayRouteDTO;

import java.util.List;

/**
 * @author Y
 * @date 2020/11/28 22:38
 * @desc
 */
public interface IRouteService {
    /**
     * 添加路由
     * @param dto
     * @return
     */
    Integer add(GatewayRouteDTO dto);

    /**
     * 更新路由
     * @param dto
     * @return
     */
    Integer update(GatewayRouteDTO dto);

    /**
     * 删除路由
     * @param routeId
     * @return
     */
    Integer delete(String routeId);

    /**
     * 获取列表
     * @return
     */
    List<GatewayRouteDTO> list();
}

package cn.yanghuisen.gateway.service.impl;

import cn.yanghuisen.gateway.dto.GatewayRouteDTO;
import cn.yanghuisen.gateway.entity.GatewayRoute;
import cn.yanghuisen.gateway.mapper.GatewayRouteMapper;
import cn.yanghuisen.gateway.service.IRouteService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Y
 * @date 2020/11/28 22:40
 * @desc
 */
@Service
public class RouteServiceImpl implements IRouteService {

    @Autowired
    private GatewayRouteMapper routeMapper;

    @Override
    public Integer add(GatewayRouteDTO dto) {
        GatewayRoute gatewayRoute = new GatewayRoute();
        BeanUtils.copyProperties(dto,gatewayRoute);
        return routeMapper.insert(gatewayRoute);
    }

    @Override
    public Integer update(GatewayRouteDTO dto) {
        GatewayRoute gatewayRoute = new GatewayRoute();
        BeanUtils.copyProperties(dto,gatewayRoute);
        return routeMapper.updateById(gatewayRoute);
    }

    @Override
    public Integer delete(String routeId) {
        QueryWrapper<GatewayRoute> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("route_id",routeId);
        return routeMapper.delete(queryWrapper);
    }

    @Override
    public List<GatewayRouteDTO> list() {
        List<GatewayRouteDTO> result = new ArrayList<>();
        List<GatewayRoute> gatewayRoutes = routeMapper.selectList(null);
        gatewayRoutes.forEach(gatewayRoute -> {
            GatewayRouteDTO dto = new GatewayRouteDTO();
            BeanUtils.copyProperties(gatewayRoute,dto);
            dto.setOldRouteId(gatewayRoute.getRouteId());
            result.add(dto);
        });

        return result;
    }
}

8、controller接口

package cn.yanghuisen.gateway.controller;

import cn.yanghuisen.gateway.dto.GatewayRouteDTO;
import cn.yanghuisen.gateway.handler.GatewayServiceHandler;
import cn.yanghuisen.gateway.service.IRouteService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author Y
 * @date 2020/11/28 22:28
 * @desc 路由API接口
 */
@RestController
@RequestMapping("/route")
@CrossOrigin
public class RouteController {

    @Autowired
    private GatewayServiceHandler gatewayServiceHandler;

    @Autowired
    private IRouteService routeService;

    /**
     * 刷新路由配置
     * @return
     */
    @GetMapping("/refresh")
    public String refresh(){
        return this.gatewayServiceHandler.loadRouteConfig();
    }

    /**
     * 添加路由配置
     * @param dto
     * @return
     */
    @PostMapping("/save")
    public String add(@RequestBody GatewayRouteDTO dto){

        if (StringUtils.isNotBlank(dto.getId())){
            this.gatewayServiceHandler.updateRoute(dto);
            this.routeService.update(dto);
        }else {
            this.gatewayServiceHandler.saveRoute(dto);
            this.routeService.add(dto);
        }
        return "success";
    }


    @GetMapping("/delete")
    public String delete(String routeId){
        this.gatewayServiceHandler.deleteRoute(routeId);
        this.routeService.delete(routeId);
        return "success";
    }

    @GetMapping("/list")
    public List<GatewayRouteDTO> list(){
        return this.routeService.list();
    }
}

9、前端代码

<template>
  <div>
    <el-row>
      <el-button type="primary" icon="el-icon-circle-plus-outline" @click="addRoute">新增路由</el-button>
      <el-button type="success" icon="el-icon-refresh" @click="refreshRoute">刷新路由</el-button>
    </el-row>
    <el-table
        :data="tableData"
        :row-class-name="tableRowClassName">
      <el-table-column
          prop="id"
          label="ID"
          show-overflow-tooltip>
      </el-table-column>
      <el-table-column
          prop="routeId"
          label="routeId"
          show-overflow-tooltip>
      </el-table-column>
      <el-table-column
          prop="uri"
          label="uri"
          show-overflow-tooltip>
      </el-table-column>
      <el-table-column
          prop="predicates"
          label="predicates"
          show-overflow-tooltip>
      </el-table-column>
      <el-table-column
          prop="filters"
          label="filters"
          show-overflow-tooltip>
      </el-table-column>
      <el-table-column
          prop="ord"
          label="order"
          width="150">
      </el-table-column>
      <el-table-column
          prop="remarks"
          label="remarks"
          width="150">
      </el-table-column>
      <el-table-column
          prop="createTime"
          label="createTime"
          width="150">
      </el-table-column>
      <el-table-column
          prop="updateTime"
          label="updateTime"
          width="150">
      </el-table-column>
      <el-table-column
          label="操作"
          fixed="right"
          width="150">
        <template slot-scope="scope">
          <el-button
              size="mini"
              @click="handleEdit(scope.row)">编辑</el-button>
          <el-button
              size="mini"
              type="danger"
              @click="handleDelete(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible">
      <el-form :model="form" label-width="100px">
        <el-form-item label="RouteId">
          <el-input v-model="form.routeId"></el-input>
        </el-form-item>
        <el-form-item label="Uri">
          <el-input v-model="form.uri"></el-input>
        </el-form-item>
        <el-form-item label="Predicates">
          <el-input v-model="form.predicates"></el-input>
        </el-form-item>
        <el-form-item label="Filters">
          <el-input v-model="form.filters"></el-input>
        </el-form-item>
        <el-form-item label="Order">
          <el-input v-model="form.ord"></el-input>
        </el-form-item>
        <el-form-item label="Remarks">
          <el-input type="textarea" v-model="form.remarks"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="clickDialog(form)">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data () {
    return {
      tableData: [],
      dialogFormVisible: false,
      form: {},
      dialogTitle: '新增路由'
    }
  },
  methods:{
    tableRowClassName(data) {
      console.log(data)
      if (data.rowIndex%2){
        return "warning-row"
      }else {
        return "success-row"
      }
    },
    handleEdit(data) {
      console.log(data);
      this.dialogTitle='编辑路由'
      this.dialogFormVisible = true
      this.form = data
    },
    handleDelete(data) {
      console.log(data);
      this.$axios.get('http://localhost:8080/route/delete', {
        params: {
          routeId: data.routeId
        }
      }).then(result=> {
        console.log(result);
        this.getList()
      })
    },
    clickDialog(data){
      console.log(data)
      this.$axios.post('http://localhost:8080/route/save', this.form).then(result=> {
        console.log(result);
        this.dialogFormVisible = false
        this.getList()
      })
    },
    refreshRoute(){
      this.$axios.get('http://localhost:8080/route/refresh').then(result => {
        console.log(result.data);
        this.getList()
      })
    },
    getList(){
      this.$axios.get('http://localhost:8080/route/list').then(result => {
        console.log(result.data);
        this.tableData = result.data
      })
    },
    addRoute(){
      this.dialogTitle='新增路由'
      this.dialogFormVisible = true
      this.form = {}
    }
  },
  created() {
    console.log(1111)
    this.getList()
  }
}
</script>

<style>
.el-table .warning-row {
  background: oldlace;
}

.el-table .success-row {
  background: #f0f9eb;
}
</style>


时间原因,代码中没做必填校验。filters暂时没用到,也没写。有空再补充吧。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值