懒人方案-半天搞定一个分布式后台管理系统
老规矩,冒个泡,不知道为啥最近也是懒,一点点动力都没有了,可能是由于几个星星导致的精神萎靡吧,也可能是财富岛太迷人了。那么今天也是带来第二个part,也就是如何快速基于renren-fast 完成后台管理项目的构建。那么今天的内容呢,有一下两点,第一是如何打通分布式微服务与前端之间的交互,第二个就是如何完成后台页面的搭建。当然最主要的就是如何完成后台的页面搭建嘛,第一个谁不会呀,无非是跨越嘛。今天
文章目录
前言
老规矩,冒个泡,不知道为啥最近也是懒,一点点动力都没有了,可能是由于几个星星导致的精神萎靡吧,也可能是财富岛太迷人了。那么今天也是带来第二个part,也就是如何快速基于renren-fast 完成后台管理项目的构建。那么今天的内容呢,有一下两点,第一是如何打通分布式微服务与前端之间的交互,第二个就是如何完成后台页面的搭建。当然最主要的就是如何完成后台的页面搭建嘛,第一个谁不会呀,无非是跨越嘛。今天的内容很简单也不多,但是混个期末作业绰绰有余。
环境
首先是咱们的环境,这个环境包括了我一些组件的版本,然后就是我所使用的工具。
SpringBoot:2.3.2.RELEASE
SpringCloud:Hoxton.SR9
SpringCloudAlibaba:2.2.6.RELEASE
nacos:1.14
使用的开源项目是:
renren-fast
renren-fast-vue
renren-generation
这个renren-generation前面的博文有说道:
懒人方案–半天搞定一个SpringBoot单体项目
不过这里由于我们这边是分布式的一个项目,所以我们需要把renren-fast注册到我们的nacos里面,最新的renren-fast的版本呢和我们上面给的环境版本是不一样的,所以需要降低版本。不过这个是后话了,待会再说,现在先把对应的环境搭建起来。
后台管理系统搭建
我们先把对应的前端代码搞到手,打开项目地址,上次给的是github的一个玩意,现在发现在gitee也有,毕竟也是国人发起的项目嘛。其实你也可以直接试一试人家的renren-security的,当然有时间再体验了,都一样的。
前端搭建
我们先把前端搭建好,我们去gitee里面把东西嫖到手。
下载解压,然后构建一下依赖,这样就把前端的项目构建好了,构建好之后大概是这样样子的。
不过验证码这里是不会有的你得把后端构建好。因为这个验证码和我们先前做的不一样还是后端给的,以前为我都是尽可能把一些东西给前端做的,验证码也是前端的,当然防君子不防小人了哈。不过也没啥,设置黑名单嘛。
后端搭建
后端的话也是类似的,首先下载代码。
idea打开,等待加载好就可以了。
然后打开你的数据库。
执行一下对应的sql语句,比如我是mysql我就执行里面的sql。
我在我mysql里面创建了一个数据库。
然后执行了sql之后,你就会看到这些表
之后在配置文件里面配置一下数据库就好了
如果你的端口有冲突的话,换了端口那么需要在前端改一下地址。
这里主要默认地址是 127.0.0.1:8000/renren-fast 我这个是改了网关的哈。
之后是这样的:
到此我们就搭建好了。但是还不够,由于我们是 分布式的玩意,我们是有nacos注册中心的,之后我们是需要和我们的微服务之间调动的。
也就是这样:
renren-fast改动
所以我们这边要做改动,首先第一点就是改依赖,现在官方给的配置是2.6.6的SpringBoot版本,然后也没有SpringCloud,所以我们要改动。
它这里的配置我改成了这样:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<mybatisplus.version>3.3.1</mybatisplus.version>
<mysql.version>8.0.28</mysql.version>
<mssql.version>4.0</mssql.version>
<oracle.version>11.2.0.3</oracle.version>
<druid.version>1.1.13</druid.version>
<quartz.version>2.3.0</quartz.version>
<commons.lang.version>2.6</commons.lang.version>
<commons.fileupload.version>1.2.2</commons.fileupload.version>
<commons.io.version>2.5</commons.io.version>
<commons.codec.version>1.10</commons.codec.version>
<commons.configuration.version>1.10</commons.configuration.version>
<shiro.version>1.9.0</shiro.version>
<jwt.version>0.7.0</jwt.version>
<kaptcha.version>0.0.9</kaptcha.version>
<qiniu.version>7.2.23</qiniu.version>
<aliyun.oss.version>2.8.3</aliyun.oss.version>
<qcloud.cos.version>4.4</qcloud.cos.version>
<swagger.version>2.7.0</swagger.version>
<joda.time.version>2.9.9</joda.time.version>
<gson.version>2.8.5</gson.version>
<fastjson.version>1.2.79</fastjson.version>
<hutool.version>4.1.1</hutool.version>
<lombok.version>1.18.4</lombok.version>
<!--wagon plugin 配置-->
<service-path>/work/renren</service-path>
<pack-name>${project.artifactId}-${project.version}.jar</pack-name>
<remote-addr>192.168.1.10:22</remote-addr>
<remote-username>root</remote-username>
<remote-passwd>123456</remote-passwd>
</properties>
<dependencies>
<dependency>
<groupId>com.huterox.whitehole.common</groupId>
<artifactId>whiteholo-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-devtools</artifactId>-->
<!--<optional>true</optional>-->
<!--</dependency>-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.version}</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--oracle驱动-->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
<!--mssql驱动-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>${mssql.version}</version>
</dependency>
<!--postgresql驱动-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
<exclusions>
<exclusion>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons.lang.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons.fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons.codec.version}</version>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>${commons.configuration.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>${qiniu.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun.oss.version}</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>${qcloud.cos.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda.time.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.8</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
<!-- 跳过单元测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<fromFile>target/${pack-name}</fromFile>
<url><![CDATA[scp://${remote-username}:${remote-passwd}@${remote-addr}${service-path}]]></url>
<commands>
<!-- Kill Old Process -->
<command>kill -9 `ps -ef |grep ${project.artifactId}.jar|grep -v "grep" |awk '{print $2}'`</command>
<!-- Restart jar package,write result into renren.log -->
<command><![CDATA[nohup java -jar ${service-path}/${pack-name} --spring.profiles.active=test > ${service-path}/renren.log 2>&1 & ]]></command>
<command><![CDATA[netstat -nptl]]></command>
<command><![CDATA[ps -ef | grep java | grep -v grep]]></command>
</commands>
<!-- 运行命令 mvn clean package wagon:upload-single wagon:sshexec-->
<displayCommandOutputs>true</displayCommandOutputs>
</configuration>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<!--<executions>-->
<!--<execution>-->
<!--<phase>package</phase>-->
<!--<goals>-->
<!--<goal>build</goal>-->
<!--</goals>-->
<!--</execution>-->
<!--</executions>-->
<configuration>
<imageName>renren/fast</imageName>
<dockerDirectory>${project.basedir}</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
<!-- 运行命令 mvn clean package docker:build 打包并生成docker镜像 -->
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
这里的那个common依赖其实是上次的那篇博客里面的可以去看看,这个是我的需求,你自己看着提取出来。
之后就是把这个代码注释一下:
原因有两个:
- allowedOrigings和当前的2.26的SpringBoot有冲突,人家名字改了。
- 接入微服务集群后,要用网关统一处理,这里不需要额外的跨越。
接入微服务集群
配置
首先是老规矩嘛,由于我导入了common包,这个包里面我是已经有nacos的服务注册发现对应的依赖的,所以我就不用导入了。
那么这里开启注解
然后去配置地址:
然后重启服务就好了。
网关
现在我们要做的是前后端分离,而且需要统一转发在前端。这个跨越的话,咱们以前也做过在前端也可以做,但是现在的话试一试在后端玩玩。不过不管是哪一个端咱们都需要统一api接口。
所以我们这里也是规定,所有的请求都需要带上api才转发,当然这个也是网关配置的一些需要嘛。
所以我这样做如下配置:
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
service: gateway
gateway:
discovery:
locator:
enabled: true
routes:
#这里先做一个基本的服务转发
- id: activiy8000
uri: lb://activiy
predicates:
- Path=/api/activiy/**
filters:
- RewritePath=/api/activiy/(?<segment>.*),/$\{segment}
- id: blog8050
uri: lb://blog
predicates:
- Path=/api/blog/**
filters:
- RewritePath=/api/blog/(?<segment>.*),/$\{segment}
- id: community8100
uri: lb://community
predicates:
- Path=/api/community/**
filters:
- RewritePath=/api/community/(?<segment>.*),/$\{segment}
- id: hole8150
uri: lb://hole
predicates:
- Path=/api/hole/**
filters:
- RewritePath=/api/hole/(?<segment>.*),/$\{segment}
- id: quiz8200
uri: lb://quiz
predicates:
- Path=/api/quiz/**
filters:
- RewritePath=/api/quiz/(?<segment>.*),/$\{segment}
- id: user8250
uri: lb://user
predicates:
- Path=/api/user/**
filters:
- RewritePath=/api/user/(?<segment>.*),/$\{segment}
- id: admin_route
uri: lb://renren-fast # 网关负载均衡的发送到renren-fast
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment} #实现路径重写
这里有6个微服务嘛,然后转发。
之后是咱们的前端,也就是这里改一下:
跨越
这部分的跨越咱们就在网关做了,记住注释掉renren-fast里面的跨越。
@Configuration
public class WhiteHoleCorsConfig {
@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1.配置跨域
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
编写后台管理
个性化处理
现在我们把基本的玩意都准备好了,在开始之前我们在做一个个性化处理。
首先是把这个换了
看你自己,反正我要换。
把这个换了就好了
然后是标题
然后是首页的侧边栏
之后是详情描述页面
也就是这个:
这个页面在这:
之后我的页面就变成了这样(这里面我后面添加了一些菜单):
ok,我们完成了基本的个性化处理,那么接下来我们来点实战。
这里我已经做好了两个模块,现在我再为文章管理做一个模块。
文章管理(案例)
首先说明一下,咱们的这个代码也是通过renren-generation 生成的,这个在咱们之前有说过。在这篇博文:
懒人方案–半天搞定一个SpringBoot单体项目
在咱们的代码是生成了代码和vue文件已经sql的,然后我当时是暂时放在了这个地方:
第一个是sql语句,这个是用来生成菜单的,但是这个的话一般我们可能用不上,当然也可以直接用,那么是干嘛的呢,我们待会说。
创建菜单
我们先来创建一个菜单。
之后刷新一下:
然后就创建好了,那么我们来说一下刚刚的sql语句有什么用,我们打开我们的后台数据库。
你会发现这个菜单其实是写在了数据库里面的,是动态渲染出来的,所以那个sql就是做这个事情的,把菜单写在了表里面,但是为什么不直接用那个sql要自己手动创建呢,很简单,我们看一下那个sql语句你就明白了。
它生成的一些菜单名字是按照字段来的。这个肯定是不能直接用的。
我们在生成一下菜单,这里注意我填写的菜单路由。
然后刷新一下,页面会显示,然后数据库里面也会有对应的记录。
数据库显示:
创建页面
之后我们创建页面,我们刚刚填写的路由是blog/blog 所以我们找到/views/modules然后创建blog文件夹blog.vue。
这个vue里面不用填写name,也就是这样
<template>
<div>
我是博客查看
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
然后你再看看页面:
使用自动生成页面
这个时候你以为要自己写页面了嘛?有些确实是的,不过还记得我们先前生成的vue文件嘛。
每次,我们把这两个文件copy过来:
记住要对得到名字,也就是你的blog.vue的名字要对上,另一个弹窗的就无所谓了。
然后效果出来了:
页面修改
然后咱们有两个点要做,第一个是列表的名字,然后是对应的后端请求地址。
现在美化一下:
label的修改,没有注释就没有。
之后是请求地址修改,我这里的话按照网关的配置需要加上/blog前缀
这里的话,两个文件都要改一下。
之后把服务打开,然后刷新页面就是这样的,咱们这块还没有数据:
后端搜索实现
之后是后端的搜索实现。
这里的话,我们主要一下前端的代码对应的逻辑是怎么写的,
所以我们回到对应的Blog对应的Service在后端。
所以我们只需要拿到key然后判断一下是不是空,如果不是的话就进行复杂查询就好了。
@Override
public PageUtils queryPage(Map<String, Object> params) {
String key = (String) params.get("key");
IPage<BlogEntity> page_params = new Query<BlogEntity>().getPage(params);
QueryWrapper<BlogEntity> blogEntityQueryWrapper = new QueryWrapper<>();
if(key!=null){
blogEntityQueryWrapper.like("userid",key).or().
like("blogid",key).or().
like("user_nickname",key).or().
like("blog_title",key);
}
IPage<BlogEntity> page = this.page(
page_params,
blogEntityQueryWrapper
);
return new PageUtils(page);
}
这里按照你的业务来哈。
然后我们验证一下,由于我这边是没有数据的,所以我用用户的这个模块来演示一下。
然后后端输出了sql日志:
当然我这里是配置了一下,你要看日志自己配置一下。
总结
又水了一篇博客儿~
当然那个开始页面的那个也能改
然后在这儿
更多推荐
所有评论(0)