如何在RuoYi-Vue项目中整合积木报表

在本篇博客中,我们将介绍如何在RuoYi-Vue项目中整合积木报表来实现数据可视化和报表功能。

本文以之前介绍的SQLServer版的RuoYi系统RuoYi-SQLServer为例。

先给出修改后的完整代码:https://github.com/elnujuw/RuoYi-SQLServer/tree/jimureport

  1. 参考官方文档完成1-7步;

  2. 创建报表设计器页面 src/views/report/jimu/design.vue

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <template>
    <i-frame :src="openUrl" id="jimuReportFrame" />
    </template>

    <script>
    import { getToken } from '@/utils/auth'
    import iFrame from "@/components/iFrame/index";

    export default {
    name: 'JimuReportDesign',
    components: { iFrame },
    data() {
    return {
    openUrl: process.env.VUE_APP_BASE_API + '/jmreport/list?token=Bearer ' + getToken()
    }
    },
    }
    </script>

    <style scoped>

    </style>
  3. 添加Token校验ruoyi-framework\src\main\java\com\ruoyi\framework\jimu\JimuReportTokenService.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    package com.ruoyi.framework.jimu;

    import com.ruoyi.common.core.domain.model.LoginUser;
    import com.ruoyi.common.utils.StringUtils;
    import com.ruoyi.framework.web.service.TokenService;
    import com.ruoyi.system.service.ISysUserService;
    import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpHeaders;
    import org.springframework.stereotype.Component;

    import javax.servlet.http.HttpServletRequest;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;


    @Component
    public class JimuReportTokenService implements JmReportTokenServiceI {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ISysUserService iSysUserService;


    @Override
    public String getUsername(String token) {
    LoginUser loginUser = tokenService.getLoginUser(token);
    return loginUser.getUsername();
    }

    @Override
    public String[] getRoles(String s) {
    return new String[0];
    }

    // 校验token
    @Override
    public Boolean verifyToken(String token) {
    LoginUser loginUser = tokenService.getLoginUser(token);
    if (StringUtils.isNotNull(loginUser)) {
    // 刷新token有效期
    tokenService.refreshToken(loginUser);
    // 超管不需要鉴权
    if (loginUser.getUser() != null && loginUser.getUser().isAdmin()) {
    return true;
    } else {
    // 校验菜单权限
    Set<String> permissions = loginUser.getPermissions();
    return permissions != null &&
    (permissions.contains("report:jimu:design")
    || permissions.contains("report:jimu:view"));
    }
    }
    return false;
    }

    @Override
    public String getToken(HttpServletRequest request) {
    String token = request.getParameter("token");
    if (StringUtils.isEmpty(token)) {
    token = request.getHeader("token");
    }
    LoginUser loginUser = tokenService.getLoginUser(token);
    if (loginUser != null) {
    return token;
    }
    return "";
    }

    @Override
    public String getToken() {
    return JmReportTokenServiceI.super.getToken();
    }

    @Override
    public Map<String, Object> getUserInfo(String token) {
    Map<String, Object> map = new HashMap(5);
    LoginUser loginUser = tokenService.getLoginUser(token);
    //设置用户名
    map.put(SYS_USER_CODE, loginUser.getUsername());
    //设置部门编码
    map.put(SYS_ORG_CODE, loginUser.getDeptId());
    // 将所有信息存放至map 解析sql/api会根据map的键值解析
    return map;
    }

    @Override
    public HttpHeaders customApiHeader() {
    HttpHeaders header = new HttpHeaders();
    // 主要用于API数据源。默认给API数据源的header中携带上Token
    // 如使用当前项目的API,则需要再header中携带Authorization头
    header.add("token", getToken());
    header.add("X-Access-Token", getToken());
    return header;
    }

    @Override
    public String getTenantId() {
    return JmReportTokenServiceI.super.getTenantId();
    }

    }
  4. 修改tokenService,添加方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    /**
    * 通过token获取用户身份信息
    * @param token
    * @return
    */
    public LoginUser getLoginUser(String token) {
    if (StringUtils.isNotEmpty(token)) {
    if (token.startsWith(Constants.TOKEN_PREFIX)) {
    token = token.replace(Constants.TOKEN_PREFIX, "");
    }
    try {
    Claims claims = parseToken(token);
    String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
    String userKey = getTokenKey(uuid);
    LoginUser user = redisCache.getCacheObject(userKey);
    return user;
    } catch (Exception e) {}
    }
    return null;
    }
  5. 添加自定义拦截器ruoyi-framework\src\main\java\com\ruoyi\framework\jimu\JimuInterceptor.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    package com.ruoyi.framework.jimu;

    import com.alibaba.fastjson2.JSONObject;
    import com.ruoyi.common.core.domain.AjaxResult;
    import com.ruoyi.common.core.domain.model.LoginUser;
    import com.ruoyi.common.utils.ServletUtils;
    import com.ruoyi.common.utils.StringUtils;
    import com.ruoyi.framework.web.service.TokenService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.Set;

    @Component
    public class JimuInterceptor implements HandlerInterceptor {

    @Autowired
    private TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String token = request.getParameter("token");
    if (StringUtils.isEmpty(token)) {
    token = request.getHeader("Token");
    }
    LoginUser loginUser = tokenService.getLoginUser(token);
    if (loginUser != null) {
    // 超级管理员无需鉴权
    if (loginUser.getUser() != null && loginUser.getUser().isAdmin()) {
    return true;
    } else {
    // 获取权限集合
    Set<String> permissions = loginUser.getPermissions();
    // 如果拥有设计器的权限,则无需view权限也可以通过校验
    if (permissions != null && permissions.contains("report:jimu:design")) {
    return true;
    }
    // 其余情况,一般是通过报表菜单点击进来的,校验对应报表的权限:report:jimu:view:{reportId}
    // http://.../jmreport/view/1234567890,则reportId = 1234567890
    String reportId = StringUtils.substringAfterLast(request.getRequestURI(), "/");
    String viewPerm = "report:jimu:view:" + reportId;
    if (permissions != null && permissions.contains(viewPerm)) {
    return true;
    }
    }
    }
    AjaxResult ajaxResult = AjaxResult.error("参数错误或没有改报表的访问权限!");
    ServletUtils.renderString(response, JSONObject.toJSONString(ajaxResult));
    return false;
    }
    }
  6. ResourcesConfig中注册自定义拦截器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /**
    * 自定义拦截规则
    */
    @Override
    public void addInterceptors(InterceptorRegistry registry)
    {
    registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
    // 添加下面一行
    registry.addInterceptor(jimuInterceptor).addPathPatterns("/jmreport/view/*");
    }
  7. 添加菜单

    报表系统菜单

    报表设计器菜单

  8. 效果

    报表设计器界面

作者

Junle

发布于

2024-03-25

更新于

2024-03-26

许可协议

评论