全部开发者教程

企业级在线办公系统

上个小节我们让折叠面板显示了审批任务的详情信息的文字部分,现在只差BPMN实时进度图了,这幅图是通过调用工作流项目获得的。但是禁止前端VUE页面直接调用工作流项目的Web方法,而是由emos-api充当中介,来调用工作流项目。

说到这里,我得跟你讲讲分布式项目的设计原则,不应该把所有的子项目都直接暴露给外网。如果我们要在每个子项目的Web方法都要写权限验证和判断,系统也不太好维护,所以最好的办法就是有专门对接外网的Web方法,其他子项目的Web方法只提供内网调用。

图片描述
为什么不在Service层发出HTTP请求调用工作流的Web方法?原因很简单,我不想让emos-api项目在服务器上保存BPMN图片。如果是在Service层发出HTTP请求,我们势必要在Service层提取响应中的BPMN图片文件,然后把文件对象返回给Web层;如果直接在Web层发出HTTP请求,我们可以不用从工作流返回的响应里面提取出图片文件,直接通过IO流对拷,把工作流响应中的图片用IO流拷贝到Web方法的响应对象中。有的人可能觉得,通过IO流把数据读取到Byte数组里面,把Byte数组返回给Web层也没有在本地保存文件啊。你这种做法在Service层写代码操作了IO流,然后到Web层又写代码操作了一遍IO流,你不觉得很麻烦吗?一会儿你看看IO流对拷有多方便。

一、编写Web层代码

ApprovalController.java类中定义Web方法,获取BPMN图片。

public class ApprovalController {
    ……
    @GetMapping("/searchApprovalBpmn")
    @Operation(summary = "获取BPMN图形")
    @SaCheckPermission(value = {"WORKFLOW:APPROVAL", "FILE:ARCHIVE"}, mode = SaMode.OR)
    public void searchApprovalBpmn(String instanceId, HttpServletResponse response) {
        if (StrUtil.isBlankIfStr(instanceId)) {
            throw new EmosException("instanceId不能为空");
        }
        HashMap param = new HashMap() {{
            put("code", code);
            put("tcode", tcode);
            put("instanceId", instanceId);
        }};
        String url = workflow + "/workflow/searchApprovalBpmn";
        HttpResponse resp = HttpRequest.post(url).header("content-type", "application/json")
                .body(JSONUtil.toJsonStr(param)).execute();
        if (resp.getStatus() == 200) {
            try (InputStream in = resp.bodyStream();
                 BufferedInputStream bin = new BufferedInputStream(in);
                 OutputStream out = response.getOutputStream();
                 BufferedOutputStream bout = new BufferedOutputStream(out)) {
                IOUtils.copy(bin, bout);
            } catch (Exception e) {
                log.error("执行异常", e);
            }
        } else {
            log.error("获取工作流BPMN失败");
            throw new EmosException("获取工作流BPMN失败");
        }

    }
}

很多同学注意到了,Web方法接受GET请求,为什么不用POST呢?这是因为前端页面的<img>标签调用Web方法加载图片的时候,它只能发出GET请求,所以Web方法我们要配合前端<img>标签。

二、编写前端代码

因为有些工作流比较复杂,页面上又没有太大的空间放置BPMN图片,所以我们要引入ElementUI-PLUS的预览图功能。用户点击BPMN图片,将以幻灯片的形式观看图片,而且还可以放大缩小和旋转。默认情况下,预览图功能要求你不管显示多少张图片,都要用数组传入图片的地址。

图片描述

<el-image class="bpmn" :src="bpmnUrl" :preview-src-list="bpmnList"></el-image>

expand函数里面添加一段JavaScript代码,为了避免浏览器缓存图片,我们还要给URL路径上面添加一个的毫秒值。

expand: function(row, expandedRows) {
    ……
    if (expandedRows.length>0) {
        that.bpmnUrl = this.$baseUrl +'approval/searchApprovalBpmn' +
                       '?instanceId='+row.processId + "&token="+ localStorage.getItem("token")+
                       '&time=' + new Date().getTime();

        that.bpmnList = [that.bpmnUrl];
}