全部开发者教程

企业级在线办公系统

首页 慕课教程 企业级在线办公系统 企业级在线办公系统 8-2 查询会议申请分页数据(后端)

在前两章我们实现了线上和线下会议申请功能,那么所有的会议申请都要在审批任务页面显示出来,然后由相关的人员执行审批工作。在审批任务页面(approval.vue),我们可以看到这个会议申请。相关人员点开这个会议申请记录,可以看到详细的申请信息,甚至说现在审批工作执行到了工作流程的哪一个步骤,都显示的清清楚楚。

图片描述
这里有个细节问题,大家需要注意。那就是审批详情信息要不要随着分页记录一起查询出来?当然是不需要的,因为审批人不一定会点开每个审批记录,然而你却把每个会议申请的详情信息都查询出来,白白增大了数据库的负担。正确的做法是用户点开申请记录的时候,再发送Ajax请求查询审批详情信息。而且Ajax必须是同步执行的,这是因为如果Ajax选择了异步执行,展开申请记录的JS回调函数不会等着Ajax执行完,导致JS回调函数执行结束,强制让Ajax也结束了。这绝对是不行的,所以我们要选择同步方式的Ajax请求。

一、查询工作流分页数据Web接口

因为审批任务页面是为用户提供审批服务的,所以页面中各种申请记录对应的都是工作流实例,我们只需要调用工作流项目就能获取到分页记录了。

接口URI:/workflow/searchTaskByPage

序号 参数名 类型 必填 说明
1 userId int 用户ID
2 role String[] 角色列表
3 page int 页数
4 length int 每页记录数量
5 type String 员工请假
6 status String 待审批
7 creatorName String 申请人
8 instanceId String 工作流实例ID
9 code String 慕课网授权码
10 tcode String 课程授权码

大家请看下面的时序图,发送HTTP请求调用工作流项目Web接口,是由ApprovalServiceImpl类做的,而不是交给异步线程任务类去做。这是因为我们必须要从工作流项目查询出来数据,然后返回给前端页面,这个过程必须是同步。如果采用异步,数据还没查询出来,Controller直接返回R对象了,这可绝对不行。

图片描述

二、编写持久层代码

TbUserDao.xml文件中,定义查询用户角色的SQL语句。

<select id="searchUserRoles" parameterType="int" resultType="String">
    SELECT
        r.role_name AS roleName
    FROM
        tb_user u
    JOIN tb_role r ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
    WHERE u.id=#{userId}
</select>

TbUserDao.java接口中,声明DAO方法。

public interface TbUserDao {
    ……
    public ArrayList<String> searchUserRoles(int userId);
}

三、编写业务层代码

UserService.java接口中,声明抽象方法。

public interface UserService {
    ……
    public ArrayList<String> searchUserRoles(int userId);
}

UserServiceImpl.java类中,实现抽象方法。

public class UserServiceImpl implements UserService {
    ……
    @Override
    public ArrayList<String> searchUserRoles(int userId) {
        ArrayList<String> list = userDao.searchUserRoles(userId);
        return list;
    }
}

创建ApprovalService.java接口,声明抽象方法。

public interface ApprovalService {
    public PageUtils searchTaskByPage(HashMap param);
}

创建ApprovalServiceImpl.java类,实现抽象方法。

@Service
@Slf4j
public class ApprovalServiceImpl implements ApprovalService {
    @Value("${workflow.url}")
    private String workflow;

    @Value("${emos.code}")
    private String code;

    @Value("${emos.tcode}")
    private String tcode;
    
    @Override
    public PageUtils searchTaskByPage(HashMap param) {
        param.put("code", code);
        param.put("tcode", tcode);
        String url = workflow + "/workflow/searchTaskByPage";
        HttpResponse resp = HttpRequest.post(url).header("Content-Type", "application/json")
                .body(JSONUtil.toJsonStr(param)).execute();
        if (resp.getStatus() == 200) {
            JSONObject json = JSONUtil.parseObj(resp.body());
            JSONObject page = json.getJSONObject("page");
            ArrayList list = page.get("list", ArrayList.class);
            Long totalCount = page.getLong("totalCount");
            Integer pageIndex = page.getInt("pageIndex");
            Integer pageSize = page.getInt("pageSize");
            PageUtils pageUtils = new PageUtils(list, totalCount, pageIndex, pageSize);
            return pageUtils;
        } else {
            log.error(resp.body());
            throw new EmosException("获取工作流数据异常");
        }
    }
}

在业务层的代码中,我们定义变量接收值注入信息,其中有一个关键点,稍不注意就会引发错误。那就是tcode状态码的注入。我们在application.yml文件中,定义tcode的时候必须要加双引号。

图片描述
如果不加双引号,SpringBoot会把001234当成是8进制的数字,然后转换成10进制数字,再转换成字符串注入给tcode变量,于是我们得到的注入值为668。但是你加上双引号,就不会有这个问题,大家切记!

四、编写Web层代码

创建SearchTaskByPageForm.java类,用于封装Ajax提交的数据。

@Data
@Schema(description = "查询任务分页列表表单")
public class SearchTaskByPageForm {

    @Pattern(regexp = "^[\\e4e00-\\u9fa5]{2,20}$", message = "creatorName内容不正确")
    private String creatorName;

    @Pattern(regexp = "^员工请假$|^会议申请$", message = "type内容不正确")
    private String type;

    @Pattern(regexp = "^[0-9a-zA-Z\\-]{36}$", message = "instanceId内容不正确")
    private String instanceId;

    @NotBlank(message = "status不能为空")
    @Pattern(regexp = "^待审批$|^已审批$|^已结束$", message = "status内容不正确")
    private String status;


    @NotNull(message = "page不能为空")
    @Min(value = 1, message = "page不能小于1")
    private Integer page;

    @NotNull(message = "length不能为空")
    @Range(min = 10, max = 100, message = "length必须在10~100之间")
    private Integer length;

}

创建ApprovalController.java类,定义Web方法。

@RestController
@RequestMapping("/approval")
@Tag(name = "ApprovalController", description = "任务审批Web接口")
@Slf4j
public class ApprovalController {

    @Value("${workflow.url}")
    private String workflow;

    @Value("${emos.code}")
    private String code;

    @Value("${emos.tcode}")
    private String tcode;

    @Autowired
    private ApprovalService approvalService;

    @Autowired
    private UserService userService;

    @PostMapping("/searchTaskByPage")
    @Operation(summary = "查询分页任务列表")
    @SaCheckPermission(value = {"WORKFLOW:APPROVAL", "FILE:ARCHIVE"}, mode = SaMode.OR)
    public R searchTaskByPage(@Valid @RequestBody SearchTaskByPageForm form) {
        HashMap param = JSONUtil.parse(form).toBean(HashMap.class);
        int userId = StpUtil.getLoginIdAsInt();
        param.put("userId", userId);
        param.put("role", userService.searchUserRoles(userId));
        PageUtils pageUtils = approvalService.searchTaskByPage(param);
        return R.ok().put("page", pageUtils);
    }
}

用Swagger测试Web方法的时候,要启动工作流项目。