【项目总结】项目开发规范

目录

背景

后端规范像Java一般就可以参考阿里巴巴Java开发手册,前端也有其自己的规范,详细的可以参考他们。这篇文章主要定义在开发中的一些业务相关的规范,提高团队开发效率,提升代码的可读性和可维护性。

后端规范

一、接口api规范

1.接口风格接口风格统一采用restful规范

  • GET请求用于查询
  • POST请求用于新增
  • PUT请求用于修改
  • DELETE请求用于删除

ps:特殊查询/删除资源请求GET/DELETE不能使用,可使用POST请求

restful风格规范可参考阮一峰的网络日志:

2.接口api命名规范

  • 接口统一命名格式=="/api/数据库表名/业务名"==
  • 表名和业务名统一采用“-”符号连接(多单词),例如:GET、"/api/user/user-job-role"——查询用户及岗位和角色信息
  • 如果是对单表进行增删改查操作,可省略业务名,例如:POST、"/api/user"——代表新增一条用户数据

3.接口参数规范

  • GET/DELETE请求参数规范(参数在请求头携带)

    • 一般按照主键id查询或者删除,或者查询、删除条件少,选择一个参数遵循如下规范:

      • api路径:"/api/数据库表名/业务名/{参数名}",例如"/api/user/{id}"。前端请求为“/api/user/1”

      • 在路径上加的参数,添加注解@PathVariable,在swagger参数后设置paramType = "path",说明参数是在路径上拼接的,而不是写在params中。

        @GetMapping("/{id}")
            @ApiOperation(value = "查询一条用户表信息", notes = "根据主键id查询 \n author:RenShiWei")
            @ApiImplicitParam(name = "id", value = "用户表id", paramType = "path")
            public ResponseResult<User> userFindById ( @PathVariable Long id ) {
                  
                  
                User user = userService.getById(id);
                if (ObjectUtil.isNull(user)) {
                  
                  
                    log.error("【查看用户表失败");
                    return ResponseResult.ok(ResponseEnum.DATA_NOT_FOUND);
                }
                return ResponseResult.ok(user);
            }
        
  • POST/PUT请求参数规范(参数在请求体携带)

    • 对于参数是表的实体类,强烈建议封装DTO,选择需要的参数。而不是使用实体类(会显示大量不必要的参数)
  • 参数需要进行校验

    • 实体类/DTO中使用SpringMVC的参数校验规则(如:@NotBlank、@NotNull等),接口参数前添加@Validated注解
    • 基本数据类型,如有需要在业务中进行参数校验
  • 参数类型统一使用application/json,前端使用qs进行全局统一拦截解析。不强制使用@RequestParam,如果qs解析没有问题,不强制使用@RequestBody

4.接口响应数据/状态码规范

4.1响应数据结构

[
    "code":"",
    "message":"",
    "data":""
]

相应数据说明:

  • code 为自定义业务状态码

  • message 为详细响应信息

  • data 为响应数据

4.2Http状态码使用

状态码(status) 说明 备注
200 正常
401 未登录
403 权限不足
404 访问资源不存在
500 不可控的服务器异常 可控制的业务逻辑异常使用code代表

4.3自定义code的使用(自定义状态码暂定,需完善和确定

自定义code 说明 备注
0 正常 无特殊含义
401 未登录 通用遵从http
403 权限不足,认证失败 通用遵从http
404 访问资源不存在 通用遵从http
500 不可控的服务器异常 通用遵从http
1xxx 通用业务状态 以1开头代表通用业务状态
2xxx 具体项目中的业务定义状态 以2开头代表具体项目中的业务定义状态
3xxx 第三方依赖状态,如微信等 以3开头代表第三方依赖状态

例如:


	/**
     * 成功(默认返回状态码)
     */
    SUCCESS(0, "SUCCESS"),

    /**
     * 全局未知异常
     */
    SEVER_ERROR(500, "服务器异常,请重试"),

    /**
     * 请求失败(一般前端处理,不常用)
     */
    BAD_REQUEST(400, "请求失败"),

    /**
     * 请求资源不存在(静态资源不存在,不常用)
     */
    DATA_NOT_FOUND(404, "没有数据了"),

    /*
     * 登录、权限认证异常
     */
    LOGIN_EXPIRE(401, "未登录"),
    IDENTITY_NOT_POW(403, "您的用户权限不足"),


    /*
       ====通用异常====
     */

    /*
        1001-1010 通用操作相关
     */
    OPERATION_FAIL(1001, "操作失败!"),
    SELECT_OPERATION_FAIL(1002, "查询操作失败!"),
    UPDATE_OPERATION_FAIL(1003, "更新操作失败!"),
    DELETE_OPERATION_FAIL(1004, "删除操作失败!"),
    INSERT_OPERATION_FAIL(1005, "新增操作失败!"),

    /*
        1011-1050 登录注册相关
     */
    LOGIN_FAIL(1011, "登录失败,账号或者密码错误"),
    LOGIN_FAIL_RELOGIN(1012, "登录失败,请重试"),
    LOGIN_FAIL_CODE(1013, "验证码错误"),
    NO_USER(1014, "用户不存在"),
    REGISTER_FAIL(1015, "注册失败,手机号已经存在"),
    NO_USER_PHONE(1016, "认证失败,手机号不存在"),
    PARAMS_NOT_NULL(1017, "请求参数不能为空"),

    /*
        1051-1070 短信业务相关
     */
    SMS_NOT_SEND(1051, "短信发送失败"),
    SMS_CODE_EXPIRE(1052, "短信验证码失效"),
    SMS_CODE_VERITY_FAIL(1053, "短信验证码验证失败"),

    /*
        1071-1100 文件、资源相关
     */
    FILE_OVERSTEP_SIZE(1071, "文件超出规定大小"),
    FILE_UPLOAD_FAIL(1072, "文件上传失败"),
    FILE_LOADING_FAIL(1073, "文件不存在,加载失败"),
    FILE_REQUEST_FAIL(1074, "文件类型不支持查看"),
    FILE_TYPE_IMAGE_FAIL(1075, "请上传图片类型的文件"),

    /*
        1101-1199 请求参数相关
     */
    PARAM_IS_INVALID(1101, "参数无效"),
    PARAM_IS_BLANK(1102, "参数为空"),
    PARAM_TYPE_BIND_ERROR(1003, "参数类型错误"),
    PARAM_NOT_COMPLETE(1004, "参数缺失"),

    /*
        -----------平安科院 业务相关(2xxx)------------
     */
    PAKY_VISITED_NOT_EXIT(2024, "被访人不存在"),
    APPOINTMENT_NOT_FIND(2100, "预约id不存在"),
    VISITOR_VALUE_FORMAT(2101, "访客链接value格式不对"),
    APPOINTMENT_QUERY_TIME_ERROR(2102, "查询时间有误"),
    APPOINTMENT_TIME_OUT(2103, "预约时间过期,自动签为过期"),
    REIDS_ADD(2200, "redis 服务添加异常"),
    REIDS_GET(2201, "redis 服务无此信息"),
    USER_ROLE_ERROR(2204, "用户角色异常"),
    NO_ROLE(2203, "无此角色id"),
    HIK_ADD_ORDER(2202, "海康 添加失败"),

    /*
        第三方相关(3xxx)
     */
    /*
        3001-3020 微信公众号
     */
    WX_GZH_ACCESS_TOKEN_FAIL(3001, "微信公众号JSSDK获取access_token失败"),
    WX_GZH_JS_API_TICKET_FAIL(3002, "微信公众号JSSDK获取jsapi_ticket失败"),
    WX_GZH_SIGN_FAIL(3003, "微信公众号JSSDK获取SIGN失败"),
    WX_CODE_EMPTY(3004, "微信wxCode为空"),
    WX_CODE_OUTTIME(3005, "微信wxCode失效或不正确请重新获取"),


4.4如何使用Http状态码和自定义code

  • 在出现Http状态码使用的情况时,推荐使用Http状态码,表述业务状态。自定义code如果没有特殊含义,同时遵循http状态(200除外)。
  • 业务状态码统一使用自定义code表述,http状态码使用200

5.接口访问权限

  • 开发阶段接口不明确其访问权限,将接口设置为匿名接口。即接口添加注解@AnonymousAccess
  • 在得知接口的访问权限时,添加权限注解——@PreAuthorize("@permissions.check('admin')")
  • 项目测试/上线前,审查所有接口的访问权限是否对应。尤其是去掉不必要的匿名接口标识@AnonymousAccess

二、异常处理规范

1.使用异常处理的方式(暂定)

throw new BadRequestException(String msg);
throw new BadRequestException(HttpStatus status,String msg);

2.什么是使用异常处理?

接口业务逻辑,有出错的风险的都建议进行异常处理。比如查询返回集合数据为空,异常的入参方式…

总的来说,只要有出错风险或者是不符合要求的情况下,提前做好业务的异常处理

三、事务规范

1.什么时候使用事务?

  • 只要有多条(大于等于2条)对数据库增删改操作的接口强制添加数据库事务处理
  • 事务控制在Service层的方法添加@Transactional(rollbackFor = Exception.class)
    • MybatisPlus如果直接使用service的数据库操作方法,在controller也需要添加@Transactional(rollbackFor = Exception.class)

四、日志规范

1.什么时候使用日志?

  • 一般在使用异常处理的使用,同时记录日志
    • 日志级别warn/error
  • 在进行接口操作(业务处理)时使用日志记录
    • info/warn

2.如何使用日志记录?

  • 使用lombok提供的快速日志操作。在类上添加@Slfj注解,在业务中直接使用log.info/warn/error(“记录日志”)

  • 日志记录格式:log.日志级别("【业务名】详细业务操作信息"),例如:

    log.info("【修改用户】userId:" + userId);
    log.error("【修改用户失败】userId:" + userId);
    

3.日志文件生成

  • 日志文件在项目根目录下生成,跟项目走,以logs命名
  • 以每天每小时生成一个日志文件命名为——server.log.%d{yyyy-MM-dd-HH}

五、文件夹结构规范

1.在指定的package下开发,业务逻辑代码一般放在system模块的modules下

2.common模块尽量封装在任何项目,任何模块都有可能使用的通用方法和工具类。

  • 如果代码在不同的项目/模块可能不一样,尽量不要封装在common模块中

3.文件夹结构

-common 通用模块
-system 核心业务模块
-tool 第三方工具模块

4.通用文件夹结构

-modules
--业务模块名
---api
----controller
----service
-----impl(service实现类的包)
----mapper(mybatis统一使用)/dao
----entity(统一使用)/domain
----bo
----vo
----dto
-config
-utils

六、Mybatis/MybatisPlus规范

1.联表查询使用注解

2.条件构造器的使用

  • 在使用条件构造器Wrapper时,强烈推荐使用其Lambda语法(这样使用的好处是,不用以数据库字段为条件,而是以JavaBean的getter、setter方法为条件,与数据库解耦,增强其可读性和可维护性
    • Lambda语法使用方式一:使用LambdaQueryWrapper、LambdaUpdateWrapper,直接使用Lambda语法
    • Lambda语法使用方式二:使用QueryWrapper、UpdateWrapper的lambda()方法,使用其Lambda语法

3.自定义属性注入

  • 使用自定义属性注入维护createTime、updateTime、createBy、updateBy等,需要注意在使用MybatisPlus提供的方法会维护,但是使用注解手撸sql时并不能维护。所以在使用注解手写sql时,不要忘记了维护createTime、updateTime、createBy、updateBy等数据

4.逻辑删除

  • 逻辑删除字段在yml文件中配置,数据库统一好逻辑删除字段,推荐使用is_deleted(不能使用is_delete,转Javabean去掉is,delete为mysql关键字)
  • 逻辑删除推荐使用0为未删除,1为逻辑删除,并且数据库设置默认值为0
  • 手写sql,即在mapper类中写的sql语句,在做SELECTUPDATE操作时需要维护is_deleted
  • 统一使用逻辑删除(暂定包括中间表),所有删除操作,手写sql全部使用UPDATE,将is_deleted改为1.

5.MybatisPlus代码生成

  • 代码生成时间类型默认为Java8数据格式LocalDateTime
  • 代码生成推荐开放ActiveRecord模式(setActiveRecord(true)),实体类会继承Model接口
  • 推荐JavaBean支持链式操作(setChainModel(true)),并且移除is前缀(setEntityBooleanColumnRemoveIsPrefix(true))

6.业务逻辑写在service层,还是写在controller层

因为MybatisPlus支持service直接操作数据库,而且比mapper层提供的方法更加丰富,所以业务逻辑写在service层,还是写在controller层,是个值得考虑的问题。推荐根据以下情况决定,业务逻辑写在哪里:

  • 如果业务逻辑比较简单,只有很少的代码量,推荐业务逻辑写在controller层
  • 如果业务逻辑比较复杂,有大量的逻辑判断和代码,推荐将业务逻辑写在service层。并将方法拆分进行封装,暴露给controller的方法声明为public,其余方法声明为private,只提供给本service类使用
  • 如果需要在mapper层手写sql,调用其mapper方法,则==强制==使其业务逻辑方法写在service层

七、Java开发业务规范

1.阿里巴巴Java开发手册和IDEA阿里巴巴代码检查插件

推荐开发前看阿里巴巴Java开发手册,并在IDEA中下载阿里巴巴代码检查插件(养成习惯,写出及规范又优美的代码)

2.推荐枚举类enum的使用

  • 数据库tinyint类型数据的判断,在Java中推荐封装枚举类进行判断
  • 业务逻辑if判断,如果判断条件比较多,推荐使用枚举类判断

3.文件上传/下载规范

  • 文件上传位置跟项目走,在项目根目录下建立upload文件夹
  • 文件命名推荐添加uuid作为内容之一,防止文件命名重复导致异常
  • 文件、上传都要走安全框架,需要做权限控制
    • 文件浏览/下载不能直接访问,需要走接口,进行权限控制

4.工具类封装

  • 工具类位置,推荐封装在utils下
    • 通用工具类封装在common模块下
    • 和某个模块相关业务的工具类,封装在相关模块下
  • 工具类推荐封装成static静态方法(有的不能不强求,比如需要bean注册)

5.配置类

  • 配置类位置,推荐封装在config下

    • 通用配置类封装在common模块下
    • 和某个模块相关业务的配置类,封装在相关模块下
  • 配置类使用配置方式

    • 推荐使用Java配置类

    • 不推荐使用xml配置(日志配置除外)

    • 推荐配置参数写在yml中进行读取

      • 大量的配置读取,推荐写Properties类。可以省去大量属性的@Value读取
      @Data
      @Configuration  //表示为配置类,注册到spring bean容器中
      @ConfigurationProperties(prefix = "jwt") //读取的yml配置的公共前缀
      public class SecurityProperties {
              
              
      
      }
      

6.SpringBoot

  • SpringBoot推荐使用2.1.0.RELEASE版本,多次使用稳定版本,暂未发现异常

  • AppRun推荐放置在根包下,一般要进行各种扫描,如果不这样防止,可能会出现扫描不到的错误(主要由@SpringBootApplication注解引起)

  • 推荐配置类使用yml文件,更好的层级结构

  • 推荐配置开发环境、测试环境、生成环境的配置文件。在不同环境下使用不同的配置文件

    image-20200912220158381

7.注释规范

  • 所有class、interface、enum等强制在类头部加注释

    • 注释方式:javadoc注释

    • 注释内容

      • 功能描述(description)
      • 作者(@author)
      • 日期(@Date)
    • 注释模板

      /**
       * description:对返回前端数据进行封装
       *
       * @author RenShiWei
       * Date: 2020/7/9 22:09
       **/
      @Data
      public class ResponseResult<T> {
              
              
          
      }
      
  • 所有成员变量,推荐添加注释

    • 注释方式:javadoc注释

    • 注释模板

      /**
      * 方式一:
      * 状态码
      */
      private Integer code;
      
      /** 方式二:状态信息说明 */
      private String message;
      
  • 所有方法,强制添加注释

    • 注释内容:

      • 功能描述(description)
      • 参数信息(@param)
      • 返回值信息(@return)
      • 作者(@author)(推荐,可知道方法谁写的,方便维护)
      • 日期(@Date)(推荐,可知道方法大致是在什么时候写的)
    • 注释模板

      /**
       * description: 接口调用成功,返回枚举中自定义的状态码及数据
       *
       * @param responseEnum 自定义枚举 状态码和信息
       * @param data         返回数据
       * @return 枚举中自定义的状态码及数据
       * @author RenShiWei
       * Date: 2020/7/10 19:57
       */
      public static <E> ResponseResult<E> ok ( ResponseEnum responseEnum, E data ) {
              
              
          return new ResponseResult<>(responseEnum, data);
      }
      
  • swagger注释(一般在controller),如果有swagger,可不写javadoc注释

    • 注释内容

      • 参数
    • 注释模板

      /**
       * 根据主键id查询一条部门表信息
       *
       * @param id 部门表ID
       * @return 部门表信息
       * @author RenShiWei
       * @since 2020-08-06
       */
      @GetMapping("/{id}")
      @ApiOperation(value = "查询一条部门表信息", notes = "根据主键id查询 \n author:RenShiWei")
      @ApiImplicitParam(name = "id", value = "部门表id", paramType = "path")
      public ResponseResult<Dept> deptFindById ( @PathVariable Long id ) {
              
              
          Dept dept = iDeptService.getById(id);
          if (ObjectUtil.isNull(dept)) {
              
              
              log.error("【查看部门表失败");
              return ResponseResult.ok(ResponseEnum.DATA_NOT_FOUND);
          }
          return ResponseResult.ok(dept);
      }
      
    • 注释规范

      • 如果路径中有==“/{id}”类似这样的参数,并且在参数前使用@PathVariable注解,那么在swagger中@ApiImplicitParam,需要将paramType设置为"path"==。
      • 参数都必须加@ApiImplicitParam注解,包含name和value,paramType选填
      • 接口方法加@ApiOperation注解,包含value和notes。note写上作者信息,方便在swagger中得知接口是谁写的
  • 业务注释

    • 业务中多写注释,方便开发和维护,养成良好习惯
    • 一块业务使用块级注释
    • 一行代码使用行级注释

八、第三方依赖规范

1.第三方依赖的引入规范

  • 强制不推荐随意引入第三方依赖。引入依赖前需要经过对比和调研,并且知晓其优缺点
  • 同一项技术,强烈建议统一使用同一项技术。保持规范和一致,提高代码的可读性和可维护性;同时减少依赖的引入,降低项目的冗余。
  • 引入第三方依赖,推荐引入其稳定版本。防止第三方依赖出现未知异常。大多数时候,最新版本,并不一定是最好的。

2.Java工具包推荐使用依赖

  • Java第三方工具包推荐使用——hutool。轻量级,基本涵盖Java开发80%以上的工具类。官方文档https://hutool.cn/docs/#/
  • JSON序列化也推荐使用hutool下的json处理

九、Maven规范

1.pom文件规范

  • SpingBoot提前规定好父版本

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>
    
  • jar引入规范

    • jar包版本统一在下定义,使用时${lombok.version}。方便统一管理所有jar包版本
    • 下定义<project.build.sourceEncoding>和<project.reporting.outputEncoding>为UTF-8;<java.version>为1.8
    • 如果是分模块开发在父工程的pom文件中先使用锁定jar包版本,在需要的时候引入jar包。防止jar包在不需要的模块中引入,造成冗余。
      • 如果不想某个引来会发生依赖传递,设置当前依赖true
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <hutool.version>5.2.5</hutool.version>
        <lombok.version>1.18.8</lombok.version>
    </properties>
    
    	<!-- 锁定jar包版本 -->
        <dependencyManagement>
            <dependencies>
                <!--    hutool的java开发工具包    -->
                <dependency>
                    <groupId>cn.hutool</groupId>
                    <artifactId>hutool-all</artifactId>
                    <version>${
          
          hutool.version}</version>
                </dependency>
    
                <!--lombok插件-->
                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <version>${
          
          lombok.version}</version>
                    <optional>true</optional>
                </dependency>
             </dependencies>
        </dependencyManagement>
    
  • 在要打jar的模块下添加如下插件(最好不要在父工程添加,可能造成打包异常)

    <build>
        <plugins>
        	<!-- spring-boot插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
                </configuration>
            </plugin>
            <!-- 跳过单元测试 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

十、Java数据对象使用规范

1.各种对象的定义

1.1PO(Persistant Object) 持久对象

  • 在 o/r 映射的时候出现的概念,如果没有 o/r 映射,没有这个概念存在了。通常对应数据模型 ( 数据库 ), 本身还有部分业务逻辑的处理。可以看成是与数据库中的表相映射的 java 对象。
  • 最简单的 PO 就是对应数据库中某个表中的一条记录,多个记录可以用 PO 的集合。 PO 中应该不包含任何对数据库的操作。
  • 一般/暂时不使用

1.2DO(Domain Object)领域对象

  • 从现实世界中抽象出来的有形或无形的业务实体。一般和数据中的表结构对应。
  • Java实体类与数据库对应,一般放在entity/domain包下
  • 常用

1.3TO(Transfer Object) ,数据传输对象

  • 在应用程序不同 tie( 关系 ) 之间传输的对象
  • 一般/暂时不使用

1.4DTO(Data Transfer Object)数据传输对象

  • 这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。
  • 数据传输对象:xxxDTO,xxx 为业务领域相关的名称
  • 常用

1.5VO(view object) 值对象

  • 视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。
  • 展示对象:xxxVO,xxx 一般为网页名称
  • 少用

1.6BO(business object) 业务对象

  • 从业务模型的角度看 , 见 UML 元件领域模型中的领域对象。封装业务逻辑的 java 对象 , 通过调用 DAO 方法 , 结合 PO,VO 进行业务操作。 business object: 业务对象 主要作用是把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。 比如一个简历,有教育经历、工作经历、社会关系等等。 我们可以把教育经历对应一个 PO ,工作经历对应一个 PO ,社会关系对应一个 PO 。 建立一个对应简历的 BO 对象处理简历,每个 BO 包含这些 PO 。 这样处理业务逻辑时,我们就可以针对 BO 去处理。
  • 使用场景
    • 主要用于一对一、一对多、多对多关系的实现,在dao/mapper层查询数据库数据返回给前端
  • 常用

1.7DAO(data access object) 数据访问对象

  • 是一个 sun 的一个标准 j2ee 设计模式, 这个模式中有个接口就是 DAO ,它负持久层的操作。为业务层提供接口。此对象用于访问数据库。通常和 PO 结合使用, DAO 中包含了各种数据库的操作方法。通过它的方法 , 结合 PO 对数据库进行相关的操作。夹在业务逻辑与数据库资源中间。配合 VO, 提供数据库的 CRUD 操作
  • 使用场景
    • 在使用mybatis技术时,暂不使用,常用mapper
  • 在使用mybatis时,一般不使用

1.8POJO(plain ordinary java object)

  • 是 DO/DTO/BO/VO等 的统称,禁止命名成 xxxPOJO

2.各种对象使用的注意事项

2.1常用的数据对象:

DO、BO、DTO

2.2.JavaBean对象的文件夹结构

与entity平级,详情参看文件夹结构规范

十一、基本数据类型与包装数据类型规范

  • POJO类属性的数据类型强制使用包装数据类型
  • 方法形参、方法返回值推荐统一使用包装数据类型
  • 方法体基本数据类型与包装数据类型都可使用,视具体情况定

MySQL规范

一、用户及权限规范

1.mysql用户命名规范

  • 账号名根据项目数据库命名(可取其简写)
  • 密码数据库名+@年份

以新生报名系统为例:

数据库:electronic_registration
账号:elec_reg
密码:ElecReg@2020

2.数据库权限

  • select
  • insert
  • delete
  • update
  • create
  • index(索引权限)

3.执行语句

# 创建用户可以在任意主机登录,(@'%'代表任意主机)
create user 'elec_reg' @'%' identified by 'ElecReg@2020';

# 授予用户权限,(@'%'代表任意主机,electronic_registration.*代表electronic_registration数据库下所有的表都具有这样的权限)
grant select,insert,delete,update,create,index on electronic_registration.* to elec_reg @'%';

前端规范

一、文件夹结构规范

1.Vue-cli项目文件夹结构

-node_modules		依赖安装文件夹(要进行git忽略)
-dist				build后的文件夹(要进行git忽略)
-public 			主要放置入口index.html文件和项目LOGO
-src
--api 				**请求api封装(封装请求-常用)
--assets			静态资源
--components		**自定义组件封装(封装所需要的组件-常用)
--router			**路由(路由跳转-常用)
--store				vuex配置
--utils				通用工具封装
--views				**页面开发(主要的页面开发-常用)
-App.vue			vue根页面
-main.js			vue全局配置
-settings.js		项目配置
-.env.development	开发环境配置
-.env.production	生产环境配置
-package.json		依赖配置
-vue.config.js      vue项目环境配置文件

标记“******”,代表日常业务开发经常使用的目录

命名规范

一、Java命名规范

1.Java常用命名

  • class、interface、enum使用大驼峰,例如:“WxUser”
  • interface命名以“I”为前缀,代表接口,例如:“IUserService”
    • 接口实现类命名统一使用后缀impl,例如:”UserImpl“
  • 包命名使用全小写
  • 变量、方法、参数名等使用小驼峰,例如:“getUserInfo”
  • 常量统一使用大写,不同单词间使用“_”连接,例如:“MAX_VALUE”
  • JavaBean命名,统一后缀使用大写。例如:“UserInfoBO、PageVO、UserDTO”等。
  • MVC各层命名示例
    • entity——User
    • mapper/dao——UserMapper/UserDao
    • service——IUserService
      • 实现类——UserServiceImpl
    • controller——UserController

二、HTML/CSS命名

  • 统一使用小写,单词间使用“-“连接。例如:”user-p“
  • 自定义标签强制统一使用“-”连接,不能出现单一单词,区别html标签。例如:“icon-select”

三、MySQL命名

1.用户及密码

参看:mysql用户命名规范

环境要求

一、后端Java环境

环境/技术 版本 备注
java 1.8
mysql 8.x 统一使用8.x。特殊情况下也可以使用5.7版本
Springboot 2.x 常用2.1.0.RELEASE版本。比较稳定,暂未非发现问题
hutool 5.x Java开发工具包
MybatisPlus 3.3.x
redis 使用springdata redis 遵从springboot的父版本

上述只是罗列Java后端的主要环境版本,如需引入其他依赖,请引入稳定版本。第三方依赖请参看上文八、第三方依赖规范

二、前端环境

环境/技术 版本 备注
Element UI PC Web组件库
Vant Mobile H5页面组件库
Vant-weapp 微信小程序组件
uniapp 小程序开发框架

团队协作git规范

一、基本概念/规范

1.主从仓库的概念

  • 主仓库(upstream)
    • 所有人不能直接提交(push)代码到主仓库,只能提交代码到从仓库,然后提PR到主仓库。由主仓库管理员审核代码,决定代码是否要合进主仓库。
    • 所有拉取代码(clone和pull),要对主仓库进行操作,保证代码同步。
    • 所有代码提PR至主仓库的develop分支
  • 从仓库(origin)
    • 所有人对从仓库进行开发,push代码到从仓库,然后提PR至主仓库进行审核。
    • push代码,最好每个阶段(可以以天/业务分)都提交到新的分支,项目结束在删除不必要的分支
      • 方便进行回退,和看历史代码

2.仓库分支

  • 主仓库分支
    • 所有开发均在develop分支开发
  • 从仓库分支
    • 每个阶段代码提交到新的分支
    • 分支命名推荐“业务+日期”,例如:env9.13——环境搭建9月13日
      • 方便知道什么业务,在那天提交的代码

二、本地分支和远程分支规范

1.分支名命名

  • 分支名称建议为:“业务+日期”,例如:env9.13——环境搭建9月13日
    • 方便知道什么业务,在那天提交的代码

2.什么时候新建分支

  • 每天或者每个业务完成阶段,建议新建立分支。待项目开发完毕,删除不必要的分支
    • 方便代码回退
    • 方便查看历史代码

三、pull代码规范

1.什么时候pull代码?

  • 每日早上上班开始开发前pull代码
  • push代码到从仓库时,必须先pull主仓库代码

2.怎么pull代码?

  • 查看git状态,没有问题再pull代码
git status
  • 将本地代码存进缓存区
git stash save "备注信息"
  • 查看缓存区内容,判断是否存进缓存区
git stash list
  • pull主仓库代码
git pull upstream develop
  • 将缓存区代码取出merge(git stash pop取出并删除缓存区代码,只取出为git stash apply
git stash pop
  • 查看git状态,如果没有继续开发
git status

四、commit/push代码规范

1.pull主仓库代码(可能主仓库代码出现更新,参看上文pull代码规范

2.查看git状态

git status

3.查看这次修改了什么,那些妥当,那些不妥当,按q可以退出

git diff

4.选择全部修改的文件(也可以自行选择)

git add .

5.提交(commit)到本地仓库

git commit -m "feat:add UserManagement"

6.上传到远程从仓库

  • 这里的HEAD指当前分支,冒号后面指要push的分支,如果远程仓库没有,会自动在远程仓库创建该分支。(虽然HEAD:分支名称可以省掉,用默认的,但还是建议加上)

  • 分支名称建议为:“业务+日期”

  • 每天或者每个阶段,可以新建一个远程分支,上传代码。方便回退和查看历史代码

git push origin HEAD:分支名称

7.提pr至主仓库(create request merge),等待主仓库管理员审核代码

五、git status使用规范

在执行git敏感操作如git stashgit commitgit push等操作前,强制推荐先使用git status查看当前git状态是否有问题。

六、拉取(clone)代码

拉取代码步骤:

1.添加本机公钥到gitlab

2.fork主仓库,生成自己的从仓库

  • 如果没有建立主仓库,请联系项目负责人

3.clone从仓库代码到本地代码指定位置(clone操作,推荐使用ssh方式,更加安全可靠)

  • clone代码

    • 这样clone会将仓库所有的分支的代码都clone下来,然后可以选择分支开发
    git clone ssh://xxx.git
    
  • clone单分支代码

    • 很多时候没必要clone所有分支,而是指定分支去clone
    git clone -b 分支名 ssh://xxx.git
    

4.关联远程主仓库

  • 查看当前关联远程仓库的分支

    git remote -v
    
    • 一般会显示有两条记录(关联的是远程从仓库)
    $ git remote -v
    origin  ssh://[email protected]:8022/aaa/xxx.git (fetch)
    origin  ssh://[email protected]:8022/aaa/xxx.git (push)
    
  • 关联远程主仓库

    $ git remote add upstream ssh://主仓库地址
    
    $ git remote -v
    origin  ssh://[email protected]:8022/aaa/xxx.git (fetch)   #自己的
    origin  ssh://[email protected]:8022/aaa/xxx.git (push)    #自己的
    upstream        ssh://[email protected]:8022/aaa/xxx.git (fetch)    #项目组长的
    upstream        ssh://[email protected]:8022/aaa/xxx.git (push)     #项目组长的
    

此时拉取仓库代码,和初始设置完毕。

七、初始化上传本地代码至主仓库

上述操作说的如何拉取代码是在主仓库建立好的前提下,直接拉取,然后进行开发的操作。此时还没有开发,本地没有代码的情况,可使用直接建立主仓库,拉取(clone)代码进行开发的情况。

但是如果是你在本地已经写了很多的代码,在写之前还没有建立主仓库,或者建立主仓库,你并没有关联主仓库,或者没有使用git。那么上述clone代码的方式就够用了。总结下来有以下情况:

  • 在本地已经写了代码
  • 想要上传本地代码并同步到主仓库

可按照如下方式解决:

方式一:

1.按照上述clone仓库代码的方式clone

2.将本地项目的.git文件删除,复制到项目根路径

3.将项目上传到从仓库

4.提PR至主仓库

方式二:

1.联系项目负责人建立主仓库

2.fork主仓库,生成自己的从仓库

3.将本地代码上传到从仓库

  • 如果当前本地项目有.git文件夹,删除

  • 右键点击git bush here打开git控制台

  • 依次执行如下代码

    #1.初始化git环境,建立.git文件夹
    git init
    
    #2.在gitlab上,将对应的项目从仓库的克隆/下载地址进行复制(例如:ssh://xxx.git),并执行如下代码,关联远程从仓库
    git remote add origin ssh://xxx.git
    
    #3.在gitlab上,将对应的项目主仓库的克隆/下载地址进行复制(例如:ssh://xxx.git),并执行如下代码,关联远程主仓库
    git remote add upstream ssh://xxx.git
    
    #4.将本地代码放进git缓存区
    git stash save "备注信息"
    
    #5.查看缓存区内容,判断是否存进缓存区
    git stash list
    
    #6.更新主仓库代码
    git pull upstream develop
    
    #7.将缓存区代码取出并删除,git stash pop相当于取出并删除,也可分别执行git stash apply和git stash drop stash@{$num}
    git stash pop
    
    # 执行到这里基本已经同步,可以直接将代码同步到主仓库,看看是否有问题
    
    #8.选择当前目录下所有文件,准备commit
    git add .
    
    #9.commit提交代码到本地仓库
    git commit -m "备注信息"
    
    #10.push代码到从仓库
    git push origin HEAD:分支名称
    
    #11.如果push使用强制提交代码到远程从仓库,可将master换成执行分支(最好提前建好分支)
    git push -u origin master -f
    
    #此时可查看gitlab从仓库上即有对应的本地代码,然后提PR到主仓库
    

八、日常开发——早上上班操作

日常开发,每天早上上班执行的操作:

1.切换本地分支。分支名:“业务+日期”,例如:env9.13

git checkout -b env9.13

2.pull主仓库代码

参看上文pull代码规范

3.查看git状态,如果没有继续开发

git status

九、日常开发——晚上下班前操作

日常开发,每天晚上下班执行的操作:

1.pull主仓库代码(可能主仓库代码出现更新,参看上文pull代码规范

2.查看git状态

git status

3.查看这次修改了什么,那些妥当,那些不妥当,按q可以退出

git diff

4.选择全部修改的文件(也可以自行选择)

git add .

5.提交(commit)到本地仓库

git commit -m "feat:add UserManagement"

6.上传到远程从仓库

  • 这里的HEAD指当前分支,冒号后面指要push的分支,如果远程仓库没有,会自动在远程仓库创建该分支。(虽然HEAD:分支名称可以省掉,用默认的,但还是建议加上)

  • 分支名称建议为:“业务+日期”

  • 每天或者每个阶段,可以新建一个远程分支,上传代码。方便回退和查看历史代码

git push origin HEAD:分支名称

7.提pr至主仓库(create request merge),等待主仓库管理员审核代码

服务器部署规范

一、docker

服务器运维时,可以使用docker完成的,统一使用docker的方式。

1.docker安装

参考博客:docker安装及docker常用命令

2.镜像(images)

命名

根据所使用的技术+"_"命名。例如镜像使用centos、git、java8、maven,命名为centos_git_java8_mvn

3.容器

  • 运行容器最好挂载宿主机相应的目录
  • 运行容器可以设置时区-e TZ="Asia/Shanghai"

二、nginx

1.docker安装nginx(推荐使用软连接将conf.d文件夹挂载到宿主机)

参考博客:docker安装nginx规范所有项目的反向代理(一个项目一个反向代理的conf配置文件)

2.推荐的重启nginx方式

如果是nginx的docker容器,重启可以使用docker restart nginx,但是这样的启动方式有很大的缺点,如果nginx启动有问题,不能很清楚的知道问题在哪,而且不能正常访问nginx。

推荐nginx启动方式:

  1. 还是先进入容器
  2. 执行nginx -t命令,测试配置文件是否有问题
    下图这样,说明没有问题:
    在这里插入图片描述
    如果配置文件问题(尤其是conf.d下的文件),会在这里显示异常
  3. 执行nginx -s reload重启nginx服务
    成功如下图
    在这里插入图片描述
    如果遇到线程问题,启动失败,可参看:docker 中使用nginx容器无法正常启动,报错signal process started和kili(3255,1) failed (3: No such process)

如果没有问题,就可以进行访问测试了

3.nginx统一管理项目的反向代理

  1. 项目下放置 “项目名.conf” 文件方便nginx统一反向代理
  2. 使用软连接的方式,将项目下的conf文件与nginx的conf.d的文件夹同步

将server配置的conf文件放在conf.d下,nginx运行后会将其添加到nginx.conf文件,从而实现反向代理。(个人推测)。

项目conf文件参考示例:

server {
    
    
    listen       9021;
    server_name  localhost;
    location / {
    
    
      root   /var/www/html/项目名/dist;
      index  index.html;
      try_files $uri $uri/ /index.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
    
    
      root   /usr/share/nginx/html;
    }
}

如果是直接复制进nginx的conf.d文件现在是确实可使用,但是如果项目的conf文件出现改动,那么并不能与nginx的conf.d的conf文件同步。

可以进入nginx的项目容器,使用软连接的方式将conf文件与nginx的conf.d目录关联,实现同步。具体操作如下:

  • 进入nginx容器,确定项目的conf路径(例如 /var/www/html/项目名/项目名的conf
  • 项目.conf 关联进 /nginx_conf/conf.d (这个目录曾经与 /etc/nginx/conf.d 建立过反向软连接,即/etc/nginx/conf.d移动到/nginx_conf,/nginx_conf/conf.d建立/etc/nginx的软连接,否则无法在宿主机操作。详细参看上文的前提下的nginx配置)
 ln -s /var/www/html/项目名/项目名的conf /nginx_conf/conf.d
  • 建立软连接后,或者修改conf后需要重启nginx服务

三、服务器部署前端vue项目

参考博客:docker 构建centos7+git+nvm镜像,实现自主切换node版本统一部署前端vue项目

四、服务器后端Springboot项目

参考博客:docker 构建git+maven+jdk8的centos7环境,实现轻量级的springboot项目的自动化部署

猜你喜欢

转载自blog.csdn.net/qq_45696377/article/details/121881821