服务端

目录结构

├─📂 server  //服务端根目录(管理后台、接口)
│  ├─📂 like-admin.src.main           //后台应用
│  │  ├─📂 java.com.mdd.admin         //Java包
│  │  │  ├─📂cache                    //缓存层
│  │  │  ├─📂config                   //配置层
│  │  │  ├─📂controller               //控制器
│  │  │  ├─📂service                  //服务层
│  │  │  │  ├─📂impl                  //实现层
│  │  │  ├─📂validate                 //Dto层
│  │  │  ├─📂vo                       //Vo层
│  │  │  ├─📄LikeAdminApplication     //项目入口文件
│  │  │  ├─📄LikeAdminInterceptor     //项目的拦截器
│  │  │  ├─📄LikeAdminThreadLocal     //项目本地线程
│  │  ├─📂 resources                  //资源目录
│  │  │  ├─📂META-INF                 //配置
│  │  │  ├─📂static                   //静态目录
|  |  |  ├─📄application.yml          //项目配置文件
|  |  |  ├─📄banner.txt               //启动Banner
|  |  |  ├─📄log4j2-spring.xml        //日志配置文件
│  │ 
│  ├─📂 like-front.src.main           //前端应用
│  │  ├─📂 java.com.mdd.front         //Java包
│  │ 
│  ├─📂 like-common                //公共类库
│  │  ├─📂config                   //全局配置
│  │  ├─📂core                     //核心目录
│  │  ├─📂entity                   //实体目录
│  │  ├─📂exception                //异常目录
│  │  ├─📂mapper                   //Mapper
│  │  ├─📂plugin                   //扩展插件
│  │  ├─📂utils                    //工具目录
│  │  ├─📂validator                //自定验证器
│  |
|  ├─📂 like-generator             //代码生成器

开发规范

  • cache
    • 统一存放缓存的实现类
  • controller
    • controller只做简单的调用,不做具体的逻辑实现,代码相对来说比较简介。
    • controller主要参与参数的接收,调用服务类,返回JSON数据
    • 如特殊要求不在此处编写逻辑代码
  • service
    • 主要编写功能相关逻辑,提供给controller层调用,或者其它service层调用
  • validate
    • 负责请求参数的处理和对参数的校验
  • vo
    • 负责返回前端规定的字段格式

公共状态

全局公共的响应状态码,方便根据状态码排查错误
您可以根据自己的项目需求调整或者增减都是可以的。

// 定义位置: com.mdd.common.enums => HttpEnum

SUCCESS(200, "成功"),
FAILED(300, "失败"),
PARAMS_VALID_ERROR(310, "参数校验错误"),
PARAMS_TYPE_ERROR(311, "参数类型错误"),
REQUEST_METHOD_ERROR(312, "请求方法错误"),
ASSERT_ARGUMENT_ERROR(313, "断言参数错误"),
ASSERT_MYBATIS_ERROR(314, "断言Mybatis错误"),

LOGIN_ACCOUNT_ERROR(330, "登录账号或密码错误"),
LOGIN_DISABLE_ERROR(331, "登录账号已被禁用了"),
TOKEN_EMPTY(332, "token参数为空"),
TOKEN_INVALID(333, "token参数无效"),
 CAPTCHA_ERROR(334, "验证码错误"),

NO_PERMISSION(403, "无相关权限"),
REQUEST_404_ERROR(404, "请求接口不存在"),

SYSTEM_ERROR(500, "系统错误");

请求拦截

  • 说明
    • 无论是登录拦截还是权限拦截,统一都在LikeAdminInterceptor完成。
  • 注意
    • 目前权限框架使用了 sa-token 如果对此框架没有了解,请先看下官方文档!
    • sa-token官方文档: https://sa-token.cc/doc.html
  • 拦截
    • @NotLogin:免登录注解
    • @NotPower:免权限注解
    • @NotLogin@NotPower 正常来说这两个注解不会同时出现在一个方法上。
    • 因为如果添加了免登录,则不需要登录权限
    • 配置示例:
       @NotLogin // 在方法上加上此注解,标识该接口不需要登录也能访问
       @NotPower // 加上此注解,标识该方法不需要校验权限
       @GetMapping("/config")
       @ApiOperation(value="公共配置")
       public AjaxResult<Map<String, Object>> config() {
           Map<String, Object> map = iIndexService.config();
           return AjaxResult.success(map);
       }
    

管理员

// 一、如何获取当前管理员ID
Integer adminId = LikeAdminThreadLocal.getAdminId();

// 二、如何获取当前角色ID
Integer roleId = LikeAdminThreadLocal.getRoleId();

// 三、如何获取当前管理员信息
Integer adminId = LikeAdminThreadLocal.getAdminId(); // 管理员ID
Integer roleId = LikeAdminThreadLocal.getRoleId();  // 管理员角色ID
String username = LikeAdminThreadLocal.get("username").toString(); // 账号

工具库

工具类

  • ArithUtil : 算术运算工具
  • ListUtil : 列表数组工具
  • MapUtil : Map对象工具
  • ConfigUtil : 配置管理工具
  • HttpUtil : Http请求工具
  • IpUtil : Ip获取工具
  • RedisUtil : Redis工具
  • RequestUtil : 请求信息工具
  • SpringUtil : Spring容器工具
  • TimeUtil : 时间日期工具
  • ToolsUtil : 通用工具类
  • UrlUtil : 资源路径处理工具
  • YmlUtil : application配置获取工具

搜索器

为了更方便的实现搜索功能,为此设计了一个基本的搜索器工具
此工具可以实现一些常见的搜索条件,这样就可以省略很多if语句

// 使用示例
systemAdminMapper.setSearch(queryWrapper, params, new String[]{
        "like:username:str",
        "like:nickname:str",
        "like:email@t.eamil:str",
        "=:role:int",
        "datetime:startTime-endTime@create_time:str"
});

// 参数说明:
    systemAdminMapper:是Mapper,因为此工具定义在了Mapper基类,所以它的子类可以直接使用
    queryWrapper: 此参数是条件构造器
    params: 是前端传递过来的参数: Map<String, String> params
    new String[]{} : 里面的是搜索条件规则,满足条件就会实现搜索

// 条件说明: like:username:str
      like: 标识模糊搜索 %username%
      username: 表示参数的字段,需和数据库字段一致
      str: 表示是字符串类型的 其它类型有: [str, long, int]: "like:email@t.eamil:str",
    这里的: email@youxiang 分别是什么意思呢?
    email: 表示前端传递过来的参数名称
    youxiang: 表示数据库中的字段名
    为什么这样做?: 因为前端传递的字段名 可能  和 数据库中的不一致!

// 特别的时间查询: datetime:startTime-endTime@create_time:str
    表示时间范围查询: 开始时间 ~ 结束时间 查询字段是 create_time

  如: datetime:startTime@create_time:str
    表示时间范围查询: 开始时间 ,不限制结束时间 查询字段是 create_time

  如: datetime:startTime@create_time:long
    表示前端需要传递时间戳去查询, long=时间戳, str=日期事件

// 【提供的条件有】
=
<>
>=
>
<=
<
between
notBetween
like
notLike
likeLeft
likeRight
in
notIn
datetime

验证器

  • 验证器可以理解为参数接收的dto, 每一个方法对应一个实体类
  • 旧版本采用了分组验证的方式, 但个人觉得不太好维护,故而改成单一得实体类
// 1、以下是示例代码
@Data
public class ArticleCreateValidate implements Serializable {

    private static final long serialVersionUID = 1L;

    @IDMust(message = "cid参数必传且需大于0")
    private Integer cid;
}

// 2、自定义验证器
// 验证主键ID
@IDMust(message = "cid参数必传且需大于0")

// 验证整数类型得数组
@IntegerContains(values = {0, 1}, message = "isShow不是合法值")

// 验证字符串类型得数组
@StringContains(values = {"add", "edit"}, message = "isShow不是合法值")

// 3、实现自己的参数验证器
// 你可以把它写在此路径下: like-common/src/main/java/com.mdd.commpn/validator

权限拦截

注意

后台端已接入了sa-token来管理登录和权限拦截
权限拦截处理函数位置: like-admin/src/java/com.mdd.admin/config/stp/StpInterConfig
如果你想修改权限拦截规则 可以在此文件调整, 具体请参考sa-token的文档

IDEA注释

开启IDEA的目录注释,增加源码的阅读效率 treeinfotip
安装操作: File -> Settings -> Plugins -> Marketplace

Swagger3配置

  • swagger默认是开启状态, 如果你需要关闭可以在 application.yml 中进行配置
  • 注意: 在生产环境中, 最好把swagger关闭
  • 访问地址: http://localhost:8084/swagger-ui/index.html
  • PS: 地址中的 http://localhost:8084 改成你自己的项目地址
like:
  # 上传目录
  upload-directory: /www/uploads/likeadmin-java/
  # Swagger配置
  swagger:
    # 是否开启swagger
    enabled: true
    # 请求前缀
    pathMapping: /dev-api

短信发送

NoticeSmsVo params = new NoticeSmsVo()
    .setScene(smsValidate.getScene()) // 场景码
    .setMobile(smsValidate.getMobile()) // 接收的手机号
    .setExpire(900) // 设置验证码失效时长, 可不设置
    .setParams(new String[] { // 短信模板附带的参数
            "code:" + ToolUtils.randomInt(4)
    });
    
NoticeDriver.handle(params);

验证【验证码】

// 导入验证的类
import com.mdd.common.plugin.notice.NoticeCheck;

// 需验证的场景码
int sceneCode = NoticeEnum.LOGIN_CODE.getCode();
// 进行验证判断
if (!NoticeCheck.verify(sceneCode, code)) {
    throw new OperateException("验证码错误!");
}
上次更新:
贡献者: TinyAnts, lr