从绫开始的后台管理系统(四)

我们开始正式写代码。

这一章主要讲前后端的工程结构设计和搭建。

后端

工程结构

工程结构这里我们使用pom管理的方式,项目结构我们采用DDD模型。

parent工程

我们创建一个parent用来管理子项目,依赖,属性以及打包方式。我们先预置三个子工程,core包负责核心配置,common包负责工具管理,system包负责对外提供服务。

parent的packaging为pom结构,它本身不对外提供功能,而是作为管理工程的工程。

依赖工程版本需要用properties维护起来,并用${}的格式引用,这样改版本就可以做到统一修改,还有一些全局配置也可以放在properties中,供其他项目引用。

构建配置build这里我们会构建两个包执行包源码包方便在其他子工程中查看源码,子工程可直接进行构建,不需要单独配置build。

<?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.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.lm</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>parent</name>
    <description>parent</description>
    <packaging>pom</packaging>

    <modules>
        <module>0moe-core</module>
        <module>0moe-common</module>
        <module>0moe-system</module>
    </modules>

    <properties>
        <java.version>1.8</java.version>
        <redis-starter.version>2.4.3</redis-starter.version>
        <security-starter.version>2.4.3</security-starter.version>
        <web-starter.version>2.4.3</web-starter.version>
        <mybatis-starter.version>2.1.4</mybatis-starter.version>
        <mysql-driver.version>8.0.23</mysql-driver.version>
        <lombok.version>1.18.18</lombok.version>
        <hutool.version>5.5.7</hutool.version>
        <servlet-api.version>4.0.1</servlet-api.version>
        <multi-redis-starter.version>1.0.0-SNAPSHOT</multi-redis-starter.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
                <version>${redis-starter.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
                <version>${security-starter.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis-starter.version}</version>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
                <version>${mysql-driver.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <scope>provided</scope>
                <version>${lombok.version}</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>
            <!-- servlet包 -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>${servlet-api.version}</version>
            </dependency>
                <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>${web-starter.version}</version>
            </dependency>
            <dependency>
                <groupId>cn.lm</groupId>
                <artifactId>0moe-multi-redis-starter</artifactId>
                <version>${multi-redis-starter.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <testSource>${java.version}</testSource>
                    <testTarget>${java.version}</testTarget>
                </configuration>
            </plugin>
            <!--配置生成源码包-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.0.1</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

core工程

core工程负责各种核心组件的配置以及管理组件,以starter的形式向外部提供服务。仅允许api服务引入一次

<?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>cn.lm</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>cn.lm</groupId>
    <artifactId>core</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>core</name>
    <description>core</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>cn.lm</groupId>
            <artifactId>0moe-multi-redis-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.lm</groupId>
            <artifactId>common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

我们每个核心组件都会放在一个包中,并且在CoreAutoConfiguration中使用@Import进行统一引入。这样我们在增删组件的时候直接修改@Import就可以,无需每个组件修改一次。

image-20210222113005820

@Import(SecurityConfig.class)
@Configuration
@Enable0moeMultiDbRedis
public class CoreAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public UserInfoService userInfoService() {
        return new UserInfoServiceImpl();
    }

    @Bean
    public TokenAuthenticationFilter tokenAuthenticationFilter() {
        return new TokenAuthenticationFilter();
    }
}

要记得在spring.factories引入自动配置类。

# spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.lm.core.CoreAutoConfiguration

####common工程

common工程会集成一些标准工具类jar(如hutool)和项目通用的utils,方便其他项目使用。允许多工程重复引入

<?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>cn.lm</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>cn.lm</groupId>
    <artifactId>common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>common</name>
    <description>common</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
    </dependencies>
</project>

system工程

system工程作为我们对外提供服务的工程,使用DDD模型驱动。

<?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>cn.lm</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>cn.lm</groupId>
    <artifactId>system</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>system</name>
    <description>system</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.lm</groupId>
            <artifactId>core</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

工程结构如下:

image-20210222114540527

其他

lombok

lombok是一把双刃剑,我们使用lombok来简化开发的同时应谨慎一些使用。值得注意的是,lombok应仅用在类pojo文件的编写简化上,可以使用Getter、Setter,log以及Builder等,禁止使用@Data。其他地方酌情按照项目需要,使用lombok一些特性,比如自动注入简化等。

前端

前端没有后端那么复杂,但是仍需要区分各个模块,以及遵守原则:core模块仅允许单次引入,shared模块允许多次引入

工程创建

# 创建admin-ui工程, 使用严格模式,css使用scss,使用路由
ng new admin-ui --strict --style scss --routing
# 引入material-ui, 主题选择custom,应用全局排版样式,应用浏览器动画
ng add @angular/material

模块划分

core

core模块负责工程所有犬儒引入的模块和全局配置,比如BrowserModuleBrowserAnimationsModuleServiceModule等,这些都仅需要在整个工程中引入一次即可,不需要重复引用,都由core包管理起来,然后将core包放在appModule中引入。勇士appModule应只引入core包

@NgModule({
  declarations: [],
  imports: [
    SharedModule,
    BrowserModule,
    RoutesModule,
    BrowserAnimationsModule,
    ServiceModule,
    LayoutModule,
  ],
  exports: [
    SharedModule,
    RoutesModule,
  ]
})
export class CoreModule {
  constructor(@SkipSelf() @Optional() parentModule: CoreModule) {
    if (parentModule){
      throw new Error('core只能在appModule引入');
    }
  }
}

appModule

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    CoreModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
}

shared

shared模块类似于后端的common工程,本质上属于组件包,可在各个模块中引入。他存在的意义是为了方便一方组件和三方组件的管理,在使用第三方组件时应直接引入shared包。

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    RouterModule,
    MatIconModule,
  ],
  exports: [
    CommonModule,
    RouterModule,
    MatIconModule,
  ]
})
export class SharedModule { }

service

service包用于资源管理。他的绝大部分作用时管理api,当然有些兄弟组件的联动也可以通过service(或ngrx)来驱动,他也是放在core包中一次性引入。

@NgModule({
  declarations: [],
  imports: [
  ]
})
export class ServiceModule { }

routes

routes负责业务路由视图的管理。我们以后的业务代码都会放到routes包中。

image-20210222155959126

@NgModule({
  declarations: [],
  imports: [
    RoutesRoutingModule,
    SharedModule
  ]
})
export class RoutesModule { }
const routes: Routes = [
  {
    path: 'passport',
    component: PassportComponent,
    loadChildren: () => import('./passport/passport.module').then(m => m.PassportModule)
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class RoutesRoutingModule { }

layout

layout负责模块布局。比如在这个passport页面,外部的背景、copyright都属于layout的一部分,登录路由(routesModule)渲染的部分仅包括红框内image-20210222160142778

在比如这里,这个就进入了业务布局,外部包括菜单等都是layout的一步分,只有红框内才是业务视图(routesModule)真正渲染的地方。

image-20210222160516595

全局配置

ng的组件生成需要改动一些全局配置。以下配置放在projects.admin-ui.schematics

"@schematics/angular:component": {
    "style": "scss",
    "changeDetection": "OnPush"
},
"@schematics/angular:module": {
    "commonModule": false
}

从绫开始的后台管理系统(四)
https://note.0moe.cn/后台管理系统/2021/02/22/从绫开始的后台管理系统(四)/
作者
Dawn_南风
发布于
2021年2月22日
许可协议