懒人方案-半天搞定一个分布式后台管理系统

文章目录

  • 前言
  • 环境
    • 后台管理系统搭建
      • 前端搭建
      • 后端搭建
      • 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里面把东西嫖到手。
懒人方案-半天搞定一个分布式后台管理系统_第1张图片

下载解压,然后构建一下依赖,这样就把前端的项目构建好了,构建好之后大概是这样样子的。

懒人方案-半天搞定一个分布式后台管理系统_第2张图片
懒人方案-半天搞定一个分布式后台管理系统_第3张图片

不过验证码这里是不会有的你得把后端构建好。因为这个验证码和我们先前做的不一样还是后端给的,以前为我都是尽可能把一些东西给前端做的,验证码也是前端的,当然防君子不防小人了哈。不过也没啥,设置黑名单嘛。

后端搭建

后端的话也是类似的,首先下载代码。

idea打开,等待加载好就可以了。

懒人方案-半天搞定一个分布式后台管理系统_第4张图片

然后打开你的数据库。
执行一下对应的sql语句,比如我是mysql我就执行里面的sql。
懒人方案-半天搞定一个分布式后台管理系统_第5张图片

我在我mysql里面创建了一个数据库。
懒人方案-半天搞定一个分布式后台管理系统_第6张图片

然后执行了sql之后,你就会看到这些表
懒人方案-半天搞定一个分布式后台管理系统_第7张图片

之后在配置文件里面配置一下数据库就好了
懒人方案-半天搞定一个分布式后台管理系统_第8张图片
如果你的端口有冲突的话,换了端口那么需要在前端改一下地址。
懒人方案-半天搞定一个分布式后台管理系统_第9张图片

这里主要默认地址是 127.0.0.1:8000/renren-fast 我这个是改了网关的哈。
之后是这样的:
懒人方案-半天搞定一个分布式后台管理系统_第10张图片

到此我们就搭建好了。但是还不够,由于我们是 分布式的玩意,我们是有nacos注册中心的,之后我们是需要和我们的微服务之间调动的。

也就是这样:
懒人方案-半天搞定一个分布式后台管理系统_第11张图片

renren-fast改动

所以我们这边要做改动,首先第一点就是改依赖,现在官方给的配置是2.6.6的SpringBoot版本,然后也没有SpringCloud,所以我们要改动。

它这里的配置我改成了这样:


	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.3.2.RELEASEversion>
		<relativePath   />
	parent>

	<properties>
		<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
		<java.version>1.8java.version>
		<mybatisplus.version>3.3.1mybatisplus.version>
		<mysql.version>8.0.28mysql.version>
		<mssql.version>4.0mssql.version>
		<oracle.version>11.2.0.3oracle.version>
		<druid.version>1.1.13druid.version>
		<quartz.version>2.3.0quartz.version>
		<commons.lang.version>2.6commons.lang.version>
		<commons.fileupload.version>1.2.2commons.fileupload.version>
		<commons.io.version>2.5commons.io.version>
		<commons.codec.version>1.10commons.codec.version>
		<commons.configuration.version>1.10commons.configuration.version>
		<shiro.version>1.9.0shiro.version>
		<jwt.version>0.7.0jwt.version>
		<kaptcha.version>0.0.9kaptcha.version>
		<qiniu.version>7.2.23qiniu.version>
		<aliyun.oss.version>2.8.3aliyun.oss.version>
		<qcloud.cos.version>4.4qcloud.cos.version>
		<swagger.version>2.7.0swagger.version>
		<joda.time.version>2.9.9joda.time.version>
		<gson.version>2.8.5gson.version>
		<fastjson.version>1.2.79fastjson.version>
		<hutool.version>4.1.1hutool.version>
		<lombok.version>1.18.4lombok.version>

		
		<service-path>/work/renrenservice-path>
		<pack-name>${project.artifactId}-${project.version}.jarpack-name>
		<remote-addr>192.168.1.10:22remote-addr>
		<remote-username>rootremote-username>
		<remote-passwd>123456remote-passwd>
	properties>

	<dependencies>

		<dependency>
			<groupId>com.huterox.whitehole.commongroupId>
			<artifactId>whiteholo-commonartifactId>
			<version>0.0.1-SNAPSHOTversion>
		dependency>


		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-testartifactId>
			<scope>testscope>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-aopartifactId>
		dependency>
		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-context-supportartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-data-redisartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-validationartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-configuration-processorartifactId>
			<optional>trueoptional>
		dependency>
		
		
		
		
		
		<dependency>
			<groupId>com.baomidougroupId>
			<artifactId>mybatis-plus-boot-starterartifactId>
			<version>${mybatisplus.version}version>
			<exclusions>
				<exclusion>
					<groupId>com.baomidougroupId>
					<artifactId>mybatis-plus-generatorartifactId>
				exclusion>
			exclusions>
		dependency>
		<dependency>
			<groupId>mysqlgroupId>
			<artifactId>mysql-connector-javaartifactId>
			<version>${mysql.version}version>
		dependency>
		
		<dependency>
			<groupId>com.oraclegroupId>
			<artifactId>ojdbc6artifactId>
			<version>${oracle.version}version>
		dependency>
		
		<dependency>
			<groupId>com.microsoft.sqlservergroupId>
			<artifactId>sqljdbc4artifactId>
			<version>${mssql.version}version>
		dependency>
		
		<dependency>
			<groupId>org.postgresqlgroupId>
			<artifactId>postgresqlartifactId>
		dependency>
		<dependency>
			<groupId>com.alibabagroupId>
			<artifactId>druid-spring-boot-starterartifactId>
			<version>${druid.version}version>
		dependency>
		<dependency>
			<groupId>org.quartz-schedulergroupId>
			<artifactId>quartzartifactId>
			<version>${quartz.version}version>
			<exclusions>
				<exclusion>
					<groupId>com.mchangegroupId>
					<artifactId>c3p0artifactId>
				exclusion>
			exclusions>
		dependency>
		<dependency>
			<groupId>commons-langgroupId>
			<artifactId>commons-langartifactId>
			<version>${commons.lang.version}version>
		dependency>
		<dependency>
			<groupId>commons-fileuploadgroupId>
			<artifactId>commons-fileuploadartifactId>
			<version>${commons.fileupload.version}version>
		dependency>
		<dependency>
			<groupId>commons-iogroupId>
			<artifactId>commons-ioartifactId>
			<version>${commons.io.version}version>
		dependency>
		<dependency>
			<groupId>commons-codecgroupId>
			<artifactId>commons-codecartifactId>
			<version>${commons.codec.version}version>
		dependency>
		<dependency>
			<groupId>commons-configurationgroupId>
			<artifactId>commons-configurationartifactId>
			<version>${commons.configuration.version}version>
		dependency>
		<dependency>
			<groupId>org.apache.shirogroupId>
			<artifactId>shiro-coreartifactId>
			<version>${shiro.version}version>
		dependency>
		<dependency>
			<groupId>org.apache.shirogroupId>
			<artifactId>shiro-springartifactId>
			<version>${shiro.version}version>
		dependency>
		<dependency>
			<groupId>io.jsonwebtokengroupId>
			<artifactId>jjwtartifactId>
			<version>${jwt.version}version>
		dependency>
		<dependency>
			<groupId>com.github.axetgroupId>
			<artifactId>kaptchaartifactId>
			<version>${kaptcha.version}version>
		dependency>
		<dependency>
			<groupId>io.springfoxgroupId>
			<artifactId>springfox-swagger2artifactId>
			<version>${swagger.version}version>
		dependency>
		<dependency>
			<groupId>io.springfoxgroupId>
			<artifactId>springfox-swagger-uiartifactId>
			<version>${swagger.version}version>
		dependency>
		<dependency>
			<groupId>com.qiniugroupId>
			<artifactId>qiniu-java-sdkartifactId>
			<version>${qiniu.version}version>
		dependency>
		<dependency>
			<groupId>com.aliyun.ossgroupId>
			<artifactId>aliyun-sdk-ossartifactId>
			<version>${aliyun.oss.version}version>
		dependency>
		<dependency>
			<groupId>com.qcloudgroupId>
			<artifactId>cos_apiartifactId>
			<version>${qcloud.cos.version}version>
			<exclusions>
				<exclusion>
					<groupId>org.slf4jgroupId>
					<artifactId>slf4j-log4j12artifactId>
				exclusion>
			exclusions>
		dependency>
		<dependency>
			<groupId>joda-timegroupId>
			<artifactId>joda-timeartifactId>
			<version>${joda.time.version}version>
		dependency>
		<dependency>
			<groupId>com.google.code.gsongroupId>
			<artifactId>gsonartifactId>
			<version>${gson.version}version>
		dependency>
		<dependency>
			<groupId>com.alibabagroupId>
			<artifactId>fastjsonartifactId>
			<version>${fastjson.version}version>
		dependency>
		<dependency>
			<groupId>cn.hutoolgroupId>
			<artifactId>hutool-allartifactId>
			<version>${hutool.version}version>
		dependency>
		<dependency>
			<groupId>org.projectlombokgroupId>
			<artifactId>lombokartifactId>
			<version>${lombok.version}version>
		dependency>
	dependencies>

	<build>
		<finalName>${project.artifactId}finalName>
		<extensions>
			<extension>
				<groupId>org.apache.maven.wagongroupId>
				<artifactId>wagon-sshartifactId>
				<version>2.8version>
			extension>
		extensions>
		<plugins>
			<plugin>
				<groupId>org.springframework.bootgroupId>
				<artifactId>spring-boot-maven-pluginartifactId>
				<configuration>
					<fork>truefork>
				configuration>
			plugin>
			
			<plugin>
				<groupId>org.apache.maven.pluginsgroupId>
				<artifactId>maven-surefire-pluginartifactId>
				<configuration>
					<skipTests>trueskipTests>
				configuration>
			plugin>
			<plugin>
				<groupId>org.codehaus.mojogroupId>
				<artifactId>wagon-maven-pluginartifactId>
				<version>1.0version>
				<configuration>
					<fromFile>target/${pack-name}fromFile>
					<url>url>
					<commands>
						
						<command>kill -9 `ps -ef |grep ${project.artifactId}.jar|grep -v "grep" |awk '{print $2}'`command>
						
						<command> ${service-path}/renren.log 2>&1 & ]]>command>
						<command>command>
						<command>command>
					commands>
					
					<displayCommandOutputs>truedisplayCommandOutputs>
				configuration>
			plugin>

			<plugin>
				<groupId>com.spotifygroupId>
				<artifactId>docker-maven-pluginartifactId>
				<version>0.4.13version>
				
				
				
				
				
				
				
				
				<configuration>
					<imageName>renren/fastimageName>
					<dockerDirectory>${project.basedir}dockerDirectory>
					<resources>
						<resource>
							<targetPath>/targetPath>
							<directory>${project.build.directory}directory>
							<include>${project.build.finalName}.jarinclude>
						resource>
					resources>
				configuration>
				
			plugin>
		plugins>
	build>

	<repositories>
		<repository>
			<id>publicid>
			<name>aliyun nexusname>
			<url>https://maven.aliyun.com/repository/public/url>
			<releases>
				<enabled>trueenabled>
			releases>
		repository>
	repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>publicid>
			<name>aliyun nexusname>
			<url>https://maven.aliyun.com/repository/public/url>
			<releases>
				<enabled>trueenabled>
			releases>
			<snapshots>
				<enabled>falseenabled>
			snapshots>
		pluginRepository>
	pluginRepositories>

这里的那个common依赖其实是上次的那篇博客里面的可以去看看,这个是我的需求,你自己看着提取出来。

之后就是把这个代码注释一下:
懒人方案-半天搞定一个分布式后台管理系统_第12张图片

原因有两个:

  1. allowedOrigings和当前的2.26的SpringBoot有冲突,人家名字改了。
  2. 接入微服务集群后,要用网关统一处理,这里不需要额外的跨越。

接入微服务集群

配置

首先是老规矩嘛,由于我导入了common包,这个包里面我是已经有nacos的服务注册发现对应的依赖的,所以我就不用导入了。

那么这里开启注解
懒人方案-半天搞定一个分布式后台管理系统_第13张图片
然后去配置地址:
懒人方案-半天搞定一个分布式后台管理系统_第14张图片

然后重启服务就好了。

网关

现在我们要做的是前后端分离,而且需要统一转发在前端。这个跨越的话,咱们以前也做过在前端也可以做,但是现在的话试一试在后端玩玩。不过不管是哪一个端咱们都需要统一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}

        - id: blog8050
          uri: lb://blog
          predicates:
            - Path=/api/blog/**
          filters:
            - RewritePath=/api/blog/(?>.*),/$\{segment}

        - id: community8100
          uri: lb://community
          predicates:
            - Path=/api/community/**
          filters:
            - RewritePath=/api/community/(?>.*),/$\{segment}

        - id: hole8150
          uri: lb://hole
          predicates:
            - Path=/api/hole/**
          filters:
            - RewritePath=/api/hole/(?>.*),/$\{segment}


        - id: quiz8200
          uri: lb://quiz
          predicates:
            - Path=/api/quiz/**
          filters:
            - RewritePath=/api/quiz/(?>.*),/$\{segment}

        - id: user8250
          uri: lb://user
          predicates:
            - Path=/api/user/**
          filters:
            - RewritePath=/api/user/(?>.*),/$\{segment}


        - id: admin_route
          uri: lb://renren-fast  # 网关负载均衡的发送到renren-fast
          predicates:
            - Path=/api/**
          filters:
            - RewritePath=/api/(?>.*),/renren-fast/$\{segment}  #实现路径重写

这里有6个微服务嘛,然后转发。

之后是咱们的前端,也就是这里改一下:
懒人方案-半天搞定一个分布式后台管理系统_第15张图片

跨越

这部分的跨越咱们就在网关做了,记住注释掉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);
    }
}

懒人方案-半天搞定一个分布式后台管理系统_第16张图片

编写后台管理

个性化处理

现在我们把基本的玩意都准备好了,在开始之前我们在做一个个性化处理。

首先是把这个换了
懒人方案-半天搞定一个分布式后台管理系统_第17张图片
看你自己,反正我要换。
把这个换了就好了
懒人方案-半天搞定一个分布式后台管理系统_第18张图片

然后是标题
懒人方案-半天搞定一个分布式后台管理系统_第19张图片

然后是首页的侧边栏
懒人方案-半天搞定一个分布式后台管理系统_第20张图片

之后是详情描述页面
也就是这个:
懒人方案-半天搞定一个分布式后台管理系统_第21张图片
这个页面在这:
懒人方案-半天搞定一个分布式后台管理系统_第22张图片

之后我的页面就变成了这样(这里面我后面添加了一些菜单):
懒人方案-半天搞定一个分布式后台管理系统_第23张图片

ok,我们完成了基本的个性化处理,那么接下来我们来点实战。

这里我已经做好了两个模块,现在我再为文章管理做一个模块。

文章管理(案例)

首先说明一下,咱们的这个代码也是通过renren-generation 生成的,这个在咱们之前有说过。在这篇博文:
懒人方案–半天搞定一个SpringBoot单体项目

在咱们的代码是生成了代码和vue文件已经sql的,然后我当时是暂时放在了这个地方:
懒人方案-半天搞定一个分布式后台管理系统_第24张图片

第一个是sql语句,这个是用来生成菜单的,但是这个的话一般我们可能用不上,当然也可以直接用,那么是干嘛的呢,我们待会说。

创建菜单

我们先来创建一个菜单。
懒人方案-半天搞定一个分布式后台管理系统_第25张图片
懒人方案-半天搞定一个分布式后台管理系统_第26张图片
之后刷新一下:
懒人方案-半天搞定一个分布式后台管理系统_第27张图片

然后就创建好了,那么我们来说一下刚刚的sql语句有什么用,我们打开我们的后台数据库。
懒人方案-半天搞定一个分布式后台管理系统_第28张图片
你会发现这个菜单其实是写在了数据库里面的,是动态渲染出来的,所以那个sql就是做这个事情的,把菜单写在了表里面,但是为什么不直接用那个sql要自己手动创建呢,很简单,我们看一下那个sql语句你就明白了。
懒人方案-半天搞定一个分布式后台管理系统_第29张图片
它生成的一些菜单名字是按照字段来的。这个肯定是不能直接用的。

我们在生成一下菜单,这里注意我填写的菜单路由。
懒人方案-半天搞定一个分布式后台管理系统_第30张图片
然后刷新一下,页面会显示,然后数据库里面也会有对应的记录。
懒人方案-半天搞定一个分布式后台管理系统_第31张图片

数据库显示:
懒人方案-半天搞定一个分布式后台管理系统_第32张图片

创建页面

之后我们创建页面,我们刚刚填写的路由是blog/blog 所以我们找到/views/modules然后创建blog文件夹blog.vue。
懒人方案-半天搞定一个分布式后台管理系统_第33张图片

这个vue里面不用填写name,也就是这样

<template>
<div>
  我是博客查看
div>
template>

<script>
export default {

}
script>

<style scoped>

style>

然后你再看看页面:
懒人方案-半天搞定一个分布式后台管理系统_第34张图片

使用自动生成页面

这个时候你以为要自己写页面了嘛?有些确实是的,不过还记得我们先前生成的vue文件嘛。
懒人方案-半天搞定一个分布式后台管理系统_第35张图片
每次,我们把这两个文件copy过来:
懒人方案-半天搞定一个分布式后台管理系统_第36张图片

记住要对得到名字,也就是你的blog.vue的名字要对上,另一个弹窗的就无所谓了。

然后效果出来了:
懒人方案-半天搞定一个分布式后台管理系统_第37张图片

懒人方案-半天搞定一个分布式后台管理系统_第38张图片

页面修改

然后咱们有两个点要做,第一个是列表的名字,然后是对应的后端请求地址。

现在美化一下:
懒人方案-半天搞定一个分布式后台管理系统_第39张图片

label的修改,没有注释就没有。
懒人方案-半天搞定一个分布式后台管理系统_第40张图片
之后是请求地址修改,我这里的话按照网关的配置需要加上/blog前缀
懒人方案-半天搞定一个分布式后台管理系统_第41张图片
这里的话,两个文件都要改一下。
之后把服务打开,然后刷新页面就是这样的,咱们这块还没有数据:
懒人方案-半天搞定一个分布式后台管理系统_第42张图片

后端搜索实现

之后是后端的搜索实现。

这里的话,我们主要一下前端的代码对应的逻辑是怎么写的,
懒人方案-半天搞定一个分布式后台管理系统_第43张图片

所以我们回到对应的Blog对应的Service在后端。
懒人方案-半天搞定一个分布式后台管理系统_第44张图片
所以我们只需要拿到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);
    }

这里按照你的业务来哈。

然后我们验证一下,由于我这边是没有数据的,所以我用用户的这个模块来演示一下。
懒人方案-半天搞定一个分布式后台管理系统_第45张图片
懒人方案-半天搞定一个分布式后台管理系统_第46张图片
然后后端输出了sql日志:
懒人方案-半天搞定一个分布式后台管理系统_第47张图片
当然我这里是配置了一下,你要看日志自己配置一下。

总结

又水了一篇博客儿~
当然那个开始页面的那个也能改
懒人方案-半天搞定一个分布式后台管理系统_第48张图片

然后在这儿
懒人方案-半天搞定一个分布式后台管理系统_第49张图片

你可能感兴趣的:(JAVA后端,分布式,spring,boot,java)