Day09——入退管理-入住-2

目录

  • [1 目标](#1 目标)
  • [2 接口分析](#2 接口分析)
    • [2.1 查询我的待办](#2.1 查询我的待办)
    • [2.2 我的申请](#2.2 我的申请)
    • [2.3 入住表单查询](#2.3 入住表单查询)
    • [2.4 护理主管-评估](#2.4 护理主管-评估)
    • [2.5 副院长-同意](#2.5 副院长-同意)
    • [2.6 副院长-拒绝](#2.6 副院长-拒绝)
  • [3 接口功能开发](#3 接口功能开发)
    • [3.1 代码结构调整](#3.1 代码结构调整)
    • [3.2 查询我的待办&我的申请](#3.2 查询我的待办&我的申请)
      • [3.2.1 思路分析](#3.2.1 思路分析)
      • [3.2.2 接口定义](#3.2.2 接口定义)
      • [3.2.3 业务层开发](#3.2.3 业务层开发)
      • [3.2.4 控制层开发](#3.2.4 控制层开发)
      • [3.2.5 测试](#3.2.5 测试)
    • [3.3 我的申请](#3.3 我的申请)
      • [3.3.1 接口定义](#3.3.1 接口定义)
      • [3.3.2 业务层](#3.3.2 业务层)
    • [3.4 入住表单查询](#3.4 入住表单查询)
      • [3.4.1 思路分析](#3.4.1 思路分析)
      • [3.4.2 接口定义](#3.4.2 接口定义)
      • [3.4.3 业务层开发](#3.4.3 业务层开发)
      • [3.4.4 控制层开发](#3.4.4 控制层开发)
      • [3.4.5 测试](#3.4.5 测试)
    • [3.5 护理主管-评估](#3.5 护理主管-评估)
      • [3.5.1 思路分析](#3.5.1 思路分析)
      • [3.5.2 接口定义](#3.5.2 接口定义)
      • [3.5.3 业务层开发](#3.5.3 业务层开发)
      • [3.5.4 控制层开发](#3.5.4 控制层开发)
      • [3.5.5 测试](#3.5.5 测试)
      • [3.5.6 补全入住表单查询](#3.5.6 补全入住表单查询)
      • [3.5.7 修复数据展示(状态控制)](#3.5.7 修复数据展示(状态控制))
    • [3.6 副院长-同意](#3.6 副院长-同意)
      • [3.6.1 思路分析](#3.6.1 思路分析)
      • [3.6.2 接口定义](#3.6.2 接口定义)
      • [3.6.3 业务层开发](#3.6.3 业务层开发)
      • [3.6.4 控制层开发](#3.6.4 控制层开发)
      • [3.6.5 测试](#3.6.5 测试)
    • [3.7 副院长-拒绝](#3.7 副院长-拒绝)
      • [3.7.1 思路分析](#3.7.1 思路分析)
      • [3.7.2 接口定义](#3.7.2 接口定义)
      • [3.7.3 业务层开发](#3.7.3 业务层开发)
      • [3.7.4 控制层开发](#3.7.4 控制层开发)
      • [3.7.5 测试](#3.7.5 测试)

1 目标

在前一天中,我们已经对入住的整体业务分析完毕了,并且创建了对应的表结构,也开发了其中的一个接口,就是创建申请。今天我们会继续开发入住相关的接口。

今日的目标:

  • 独立完成查询我的待办和我的申请接口
  • 独立完成入住表单详情查询
  • 独立完成护理主管-评估接口
  • 独立完成副院长审批中的同意和拒绝的接口开发

2 接口分析

由于接口过多,我们今天会开发5个接口,分别是

  • 查询我的待办

  • 入住表单查询

  • 护理主管-评估老人健康

  • 副院长-同意

  • 副院长-拒绝

2.1 查询我的待办

原型图效果

接口地址 :/pending_tasks/selectByPage

请求方式 :POST

请求示例:

javascript 复制代码
{
  "applicat": "",//申请人
  "applicatId": 0,//申请人id
  "applyStatus": 0,//申请状态
  "assigneeId": 0,//操作人
  "code": "",//申请单号
  "endTime": "",//结束时间
  "isHandle": 0,//是否处理完成(0:未处理,1:已处理)
  "pageNum": 0,//当前页
  "pageSize": 0,//每页条数
  "reqType": 0,//请求类型(0:待办,1:我的申请)
  "startTime": "",//开始时间
  "status": 0,//流程状态(1:申请中,2:已完成,3:已关闭)
  "type": 0//单据类别(1:退住,2:请假,3:入住)
}

响应示例:

javascript 复制代码
{
    "code": 200,
    "msg": "操作成功",
    "data": {
        "total": "1",
        "pageSize": 10,
        "pages": "1",
        "page": 1,
        "records": [
            {
                "id": "4ca81266-6f3f-11ee-94ed-5405db5be13e",
                "checkInId": "180",
                "applicat": "养老顾问",
                "applicationTime": "2023-10-20 19:53:36",
                "code": "RZ202310201953351",
                "status": 1,
                "assigneeId": "1671403256519078157",
                "title": "朱罡烈的入住申请",
                "type": 3
            }
        ]
    }
}

2.2 我的申请

接口地址 :/applications/selectByPage

请求方式 :POST

请求示例:

javascript 复制代码
{
  "code": "",//单据编号
  "endTime": "",//结束时间
  "pageNum": 0, //当前页码
  "pageSize": 0, //每页显示条数
  "startTime": "", //开始时间
  "status": 0, //单据状态(申请中、已完成、已关闭)
  "type": 0 //单据类别
}

响应示例:

javascript 复制代码
{
    "code": 200,
    "msg": "操作成功",
    "data": {
        "total": "1",
        "pageSize": 10,
        "pages": "1",
        "page": 1,
        "records": [
            {
                "id": "4ca81266-6f3f-11ee-94ed-5405db5be13e",
                "checkInId": "180",
                "applicat": "养老顾问",
                "applicationTime": "2023-10-20 19:53:36",
                "code": "RZ202310201953351",
                "status": 1,
                "assigneeId": "1671403256519078157",
                "title": "朱罡烈的入住申请",
                "type": 3
            }
        ]
    }
}

2.3 入住表单查询

接口地址 :/checkIn

请求方式 :GET

请求数据类型 :application/x-www-form-urlencoded

响应数据类型 :*/*

接口描述:

请求参数:

参数名称 参数说明 数据类型
assigneeId 处理人ID string
code 入住编码 string
flowStatus 流程状态 int
taskId 任务Id string

响应示例:

javascript 复制代码
{
    "code": 200,
    "msg": "操作成功",
    "data": {
        "checkIn": {//入住对象
            "id": "180",
            "createTime": "2023-10-20 19:53:35",
            "updateTime": "2023-10-20 19:53:35",
            "checkInCode": "RZ202310201953351",
            "title": "朱罡烈的入住申请",
            "elderDto": {
                "name": "朱罡烈",
                "idCardNo": "132123196709071234",
                "phone": "13678904567",
                "age": "56",
                "sex": "0"
            },
            "elderId": "141",
            "otherApplyInfo": "{\"education\":\"硕士\",\"idCardNo\":\"132123196709071234\",\"sex\":0,\"politicStatus\":\"群众\",\"religion\":\"佛教\",\"nationality\":\"汉族\",...}",
            "counselor": "养老顾问",
            "applicat": "养老顾问",
            "deptNo": "100001006000000",
            "applicatId": "1671403256519078161",
            "flowStatus": 1,
            "status": 1,
            "isShow": 1,
            "memberElderDtos": [
                {
                    "name": "小猪",
                    "phone": "13456655444",
                    "refName": "子女",
                    "refId": "0"
                }
            ],
            "url1": "https://itheim.oss-cn-beijing.aliyuncs.com/f0a77cf6-6c25-4b06-b170-a3d60944cfba.png",
            "url2": "https://itheim.oss-cn-beijing.aliyuncs.com/7f94f434-7557-43b2-ad78-6e15031d6625.jpg",
            "url3": "https://itheim.oss-cn-beijing.aliyuncs.com/c8d80400-433b-4227-8c1f-896df699c2ec.jpg"
          
        },
        "type": 3,
        "nextApprover": "护理组主管",
        "accraditationRecords": [//操作记录
            {
                "id": "1759",
                "createTime": "2023-10-20 19:53:36",
                "opinion": "同意",
                "type": 3,
                "approverId": "1671403256519078161",
                "approverName": "养老顾问",
                "approverNameRole": "127.0.0.1",
                "bussniessId": "180",
                "currentStep": "发起申请-申请入住",
                "nextStep": "护理组组长处理-入住评估",
                "auditStatus": 1,
                "nextApprover": "护理组主管",
                "nextApproverId": "1671403256519078157",
                "nextApproverRole": "护理组主管",
                "stepNo": "1",
                "handleType": 1
            }
        ],
        "isShow": 1
    }
}

2.4 护理主管-评估

接口地址 :/checkIn/review

请求方式 :POST

请求示例:

javascript 复制代码
{
  "id": 180,
  //健康评估
  "reviewInfo": "{'diagnoseArr':['无疾病'],'woundArr':['无'],'lookAfterArr':['无']]}",
  //能力评估
  "reviewInfo1": "{'radio1':0,'radio1Score':1,'radio2':2,'radio2Score':3,'radio3':3}",
  //评估报告
  "reviewInfo2": "{'alteration':['已诊断疾病超过3项'],'selfScore':8,'spiritScore':10,}",
  //任务ID
  "taskId": "4ca81266-6f3f-11ee-94ed-5405db5be13e"
}

响应示例:

javascript 复制代码
{
  "code": 200,
  "msg": "操作成功"
}

2.5 副院长-同意

接口地址 :/checkIn/submit

请求方式 :PUT

请求参数:

参数名称 参数说明 数据类型
id 入住Id long
message 审批意见 string
taskId 任务Id string

响应示例:

javascript 复制代码
{
  "code": 200,
  "msg": "操作成功"
}

2.6 副院长-拒绝

接口地址 :/checkIn/reject

请求方式 :PUT

请求参数:

参数名称 参数说明 数据类型
id 入住Id long
message 拒绝原因 string
taskId 任务Id string

响应示例:

javascript 复制代码
{
  "code": 200,
  "msg": "操作成功"
}

3 接口功能开发

3.1 代码结构调整

为了更方便的维护工作流的代码,我们专门创建一个业务类来管理工作流的代码逻辑

新增一个ActFlowCommService类,定义两个方法,这两个方法,就是我们之前在CheckInServiceImpl中定义的方法

java 复制代码
package com.zzyl.service;

import com.zzyl.base.PageResponse;
import com.zzyl.dto.PendingTasksDto;
import com.zzyl.entity.CheckIn;
import com.zzyl.entity.PendingTasks;
import com.zzyl.entity.User;

import java.util.Map;

/**
 * @author sjqn
 */
public interface ActFlowCommService {

    /**
     * 查询下一个审核人
     * @param processDefinitionKey   流程定义key
     * @param businessKey
     * @return
     */
    public Long getNextAssignee(String processDefinitionKey, String businessKey);

    /**
     * 启动流程实例,并且自动执行首页点
     * @param id  业务id
     * @param user  当前登录用户
     * @param processDefinitionKey    流程定义的key
     * @param variables  流程变量参数
     * @param isAuto  是否自动完成
     */
    public void start(Long id, User user, String processDefinitionKey, Map<String, Object> variables, boolean isAuto);

}

实现类:

java 复制代码
package com.zzyl.service.impl;


/**
 * @author sjqn
 */
@Service
public class ActFlowCommServiceImpl implements ActFlowCommService {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    /**
     * 查询下一个审核人
     * @param processDefinitionKey   流程定义key
     * @param businessKey
     * @return
     */
    @Override
    public Long getNextAssignee(String processDefinitionKey, String businessKey) {

        Task task = taskService.createTaskQuery()
                .processDefinitionKey(processDefinitionKey)
                .processInstanceBusinessKey(businessKey).singleResult();
        if(task != null){
            return Long.valueOf(task.getAssignee());
        }
        return null;


    }


    /**
     * 启动流程实例,并且自动执行首页点
     * @param id                   业务id
     * @param user                 当前登录用户
     * @param processDefinitionKey 流程定义的key
     * @param variables            流程变量参数
     * @param isAuto               是否自动完成
     */
    @Override
    public void start(Long id, User user, String processDefinitionKey, Map<String, Object> variables, boolean isAuto) {

        //启动流程实例
        String businessKey = processDefinitionKey +":" + id;
        variables.put("bussinessKey",businessKey);
        runtimeService.startProcessInstanceByKey(processDefinitionKey,businessKey,variables);

        //查询任务,执行任务
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(processDefinitionKey)
                .processInstanceBusinessKey(businessKey)
                .taskAssignee(user.getId().toString())
                .list();
        //判断是否是首节点
        list = list.stream().filter(t->"0".equals(t.getFormKey())).collect(Collectors.toList());
        if(!CollectionUtil.isEmpty(list) && isAuto){
            //执行任务
            for (Task task : list) {
                Map<String, Object> variables2 = new HashMap<>();
                variables2.put("processStatus",1);
                variables2.put("ops",1);
                taskService.complete(task.getId(),variables2);
            }
        }
    }

}

修改CheckInServiceImpl,注入ActFlowCommService进行方法调用

3.2 查询我的待办&我的申请

3.2.1 思路分析

3.2.2 接口定义

java 复制代码
package com.zzyl.controller;

@RestController
@RequestMapping("/pending_tasks")
@Api(tags = "待办")
public class PendingTasksController extends BaseController {

    @PostMapping("/selectByPage")
    @ApiOperation(value = "查询待办", notes = "传入退住对象")
    public ResponseResult selectByPage(@RequestBody PendingTasksDto pendingTasksDto){
        return null;
    }
}

参数DTO:PendingTasksDto

java 复制代码
package com.luckon.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.Date;

@Data
@ApiModel("待办DTO")
public class PendingTasksDto {

    /**
     * 申请单号
     */
    @ApiModelProperty(value = "申请单号")
    private String code;
    /**
     * 申请人
     */
    @ApiModelProperty(value = "申请人")
    private String applicat;
    /**
     * 申请人id
     */
    @ApiModelProperty(value = "申请人id")
    private Long applicatId;
    /**
     * 单据类别
     */
    @ApiModelProperty(value = "单据类别")
    private Integer type;
    /**
     * 状态
     */
    @ApiModelProperty(value = "流程状态")
    private Integer status;

    /**
     * 申请状态
     */
    @ApiModelProperty(value = "申请状态")
    private Integer applyStatus;

    /**
     * 开始时间
     */
    @ApiModelProperty(value = "开始时间")
    private Date startTime;
    /**
     * 结束时间
     */
    @ApiModelProperty(value = "结束时间")
    private Date endTime;

    /**
     * 当前页
     */
    @ApiModelProperty(value = "当前页")
    private Integer pageNum;

    /**
     * 每页条数
     */
    @ApiModelProperty(value = "每页条数")
    private Integer pageSize;

    /**
     * 操作人
     */
    @ApiModelProperty(value = "操作人")
    private Long assigneeId;

    /**
     * 请求类型(0:待办,1:我的申请)
     */
    @ApiModelProperty(value = "请求类型")
    private Integer reqType;

    /**
     * 是否处理完成
     * 0:未处理
     * 1:已处理
     */
    @ApiModelProperty(value = "是否处理完成(0:未处理,1:已处理)")
    private Integer isHandle;
}

返回实体:

java 复制代码
package com.luckon.entity;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;

@Data
public class PendingTasks implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
    * 主键
    */
    private String id;

    private Long checkInId;

    /**
    * 申请人
    */
    @ApiModelProperty(value = "申请人")
    private String applicat;

    /**
     * 申请人id
     */
    @ApiModelProperty(value = "申请人角色名称")
    private Long applicatId;

    /**
    * 申请时间
    */
    @ApiModelProperty(value = "申请时间")
    private LocalDateTime applicationTime;

    /**
    * 编号
    */
    @ApiModelProperty(value = "编号")
    private String code;

    /**
    * 状态(1:申请中,2:已完成,3:已关闭)
    */
    @ApiModelProperty(value = "状态")
    private Integer status;

    /**
     * 操作人ID
     */
    @ApiModelProperty(value = "操作人ID")
    private Long assigneeId;

    /**
     * 操作人
     */
    @ApiModelProperty(value = "操作人")
    private String assignee;

    /**
    * 标题
    */
    @ApiModelProperty(value = "标题")
    private String title;

    /**
    * 类型(1:退住,2:请假,3:入住)
    */
    @ApiModelProperty(value = "类型")
    private Integer type;

    /**
     * 完成时间
     */
    @ApiModelProperty(value = "完成时间")
    private LocalDateTime finishTime;

    /**
     * 是否处理完成
     * 0:未处理
     * 1:已处理
     */
    @ApiModelProperty(value = "是否处理完成(0:未处理,1:已处理)")
    private Integer isHandle;

    /**
     * 审核步骤
     */
    @ApiModelProperty(value = "审核步骤")
    private Integer stepNo;


    /**
     * 流程状态
     */
    @ApiModelProperty(value = "流程状态")
    private Integer flowStatus;


}

3.2.3 业务层开发

因为所有的数据都是从activiti的表中进行查询,在之前创建入住的时候,还需要添加几个字段,是为了方便我们进行数据的检索

需要在启动流程实例中添加三个流程变量参数

  • processTitle 标题
  • assignee0Name 申请人姓名
  • applicationTime 申请时间
java 复制代码
private Map<String, Object> setVariables(CheckIn checkIn) {
    Map<String, Object> variables = new HashMap<>();

    variables.put("processTitle", checkIn.getTitle());
    variables.put("assignee0Name", checkIn.getApplicat());
    variables.put("applicationTime", checkIn.getCreateTime());
    
    //其他代码省略....

}

在ActFlowCommService中定义新的方法,如下

java 复制代码
/**
 * 查询待办和我的申请列表
 * @param pendingTasksDto
 * @return
 */
public PageResponse getMyTaskList(PendingTasksDto pendingTasksDto);
java 复制代码
/**
     * 分页条件查询待办任务
     *
     * @param pendingTasksDto
     * @return
     */
@Override
public PageResponse<PendingTasks> getMyTaskList(PendingTasksDto pendingTasksDto) {

    //创建查询条件
    HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery();

    //是否是已处理
    if(ObjectUtil.isNotEmpty(pendingTasksDto.getIsHandle())){
        if(pendingTasksDto.getIsHandle() == 1){
            taskQuery.finished();
        }else {
            taskQuery.unfinished();
        }
    }

    //做一系列判断来进行查询
    taskQuery.taskNameLike("%处理");
    taskQuery.taskAssignee(pendingTasksDto.getAssigneeId().toString());
    //时间范围查询
    if (ObjectUtil.isNotEmpty(pendingTasksDto.getStartTime())
        && ObjectUtil.isNotEmpty(pendingTasksDto.getEndTime())) {
        taskQuery.taskCreatedAfter(pendingTasksDto.getStartTime()).taskCreatedBefore(pendingTasksDto.getEndTime());
    }
    //单据类别
    if (ObjectUtil.isNotEmpty(pendingTasksDto.getType())) {
        taskQuery.processVariableValueEquals("processType", pendingTasksDto.getType());
    }
    //单据code
    if (ObjectUtil.isNotEmpty(pendingTasksDto.getCode())) {
        taskQuery.processVariableValueEquals("processCode", pendingTasksDto.getCode());
    }
    //任务状态
    if (ObjectUtil.isNotEmpty(pendingTasksDto.getStatus())) {
        taskQuery.processVariableValueEquals("processStatus", pendingTasksDto.getStatus());
    }

    //获取总条数
    long count = taskQuery.count();

    //分页查询
    List<HistoricTaskInstance> list = taskQuery.includeProcessVariables().orderByHistoricTaskInstanceStartTime()
        .desc().listPage((pendingTasksDto.getPageNum() - 1) * pendingTasksDto.getPageSize(), pendingTasksDto.getPageSize());

    List<PendingTasks> pendingTasksList = new ArrayList<>();

    //封装返回数据
    for (HistoricTaskInstance task : list) {
        Map<String, Object> processVariables = task.getProcessVariables();
        PendingTasks pendingTasks = new PendingTasks();
        pendingTasks.setId(task.getId());
        pendingTasks.setCode(processVariables.get("processCode").toString());
        pendingTasks.setType(Integer.parseInt(processVariables.get("processType").toString()));
        pendingTasks.setTitle(processVariables.get("processTitle").toString());
        pendingTasks.setApplicat(processVariables.get("assignee0Name").toString());
        pendingTasks.setStatus(Integer.parseInt(processVariables.get("processStatus").toString()));
        pendingTasks.setAssigneeId(Long.valueOf(task.getAssignee()));
        LocalDateTime applicationTime = LocalDateTimeUtil.parse(processVariables.get("applicationTime").toString());
        pendingTasks.setApplicationTime(applicationTime);

        //TODO 完成时间

        pendingTasksList.add(pendingTasks);

    }
    return PageResponse.of(pendingTasksList, pendingTasksDto.getPageNum(), pendingTasksDto.getPageSize(),
                           (count + pendingTasksDto.getPageSize() - 1) / pendingTasksDto.getPageSize(), count);

}

3.2.4 控制层开发

java 复制代码
@RestController
@RequestMapping("/pending_tasks")
@Api(tags = "待办")
public class PendingTasksController extends BaseController {

    @Autowired
    private ActFlowCommService actFlowCommService;

    @PostMapping("/selectByPage")
    @ApiOperation(value = "查询待办", notes = "传入退住对象")
    public ResponseResult<PendingTasks> selectByPage(@RequestBody PendingTasksDto pendingTasksDto){
        //只查询有当前登录人的任务
        Long userId = UserThreadLocal.getMgtUserId();
        pendingTasksDto.setAssigneeId(userId);

        PageResponse<PendingTasks> pendingTasksPageResponse = actFlowCommService.myTaskInfoList(pendingTasksDto);
        return success(pendingTasksPageResponse);
    }
}

3.2.5 测试

可以在页面中直接查看待办的数据

3.3 我的申请

3.3.1 接口定义

新增ApplicationsController类,直接调用actFlowCommService中myTaskInfoList方法即可

java 复制代码
package com.zzyl.controller;


import cn.hutool.core.bean.BeanUtil;
import com.zzyl.base.PageResponse;
import com.zzyl.base.ResponseResult;
import com.zzyl.dto.ApplicationsDto;
import com.zzyl.dto.PendingTasksDto;
import com.zzyl.entity.PendingTasks;
import com.zzyl.service.ActFlowCommService;
import com.zzyl.utils.UserThreadLocal;
import com.zzyl.vo.ApplicationsVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* <p>
* applications 控制器实现
* </p>
*
* @author itheima
*/
@RestController
@RequestMapping("/applications")
@Api(tags = "我的申请")
public class ApplicationsController {

    @Autowired
    private ActFlowCommService actFlowCommService;

    @PostMapping("/selectByPage")
    @ApiOperation(value = "查询我的申请")
    public ResponseResult<ApplicationsVo> selectByPage(@RequestBody ApplicationsDto applicationsDto){

        Long mgtUserId = UserThreadLocal.getMgtUserId();
        applicationsDto.setApplicatId(mgtUserId);

        PendingTasksDto pendingTasksDto = BeanUtil.toBean(applicationsDto, PendingTasksDto.class);
        PageResponse<PendingTasks> pendingTasksPageResponse = actFlowCommService.getMyTaskList(pendingTasksDto);
        return ResponseResult.success(pendingTasksPageResponse);
    }

}

3.3.2 业务层

在ActFlowCommServiceImpl类中的myTaskInfoList方法,修改代码,如果存在申请人id,则查询申请人,不然就是待办数据

3.4 入住表单查询

3.4.1 思路分析

参数说明:

  • db-flowStatus 数据库中存储的入住流程状态
  • flowStatus 前端传递过来的流程状态
  • taskId 当前登录人的任务id

3.4.2 接口定义

java 复制代码
@GetMapping
@ApiOperation(value = "入住表单查询")
public ResponseResult<TasVo> getCheckIn(
        @RequestParam @ApiParam(value = "入住编码") String code,
        @RequestParam @ApiParam(value = "处理人ID") String assigneeId,
        @RequestParam @ApiParam(value = "流程状态") Integer flowStatus,
        @RequestParam(required = false) @ApiParam(value = "任务Id") String taskId) {
    return null;
}

TasVo

java 复制代码
package com.luckon.vo.retreat;

import com.luckon.entity.*;
import com.luckon.vo.CheckInVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

/**
 * @author sjqn
 * @date 2023/6/20
 */
@Data
public class TasVo {

    /**
     * 入住信息
     */
    private CheckInVo checkIn;

    /**
     * 类型 1退住 2请假 3入住
     */
    private Integer type;

    private String nextApprover;

    /**
     * 审批记录
     */
    private List<AccraditationRecord> accraditationRecords;

    /**
     * 是否展示退住数据
     * 0:其他用户,审核中
     * 1:当前为审核人,可以正常查看数据
     */
    @ApiModelProperty(value = "是否展示入住数据")
    private Integer isShow;

}

3.4.3 业务层开发

在CheckInService中新增方法,如下:

java 复制代码
/**
     * 查询入住信息
     * @param      * @param status
     * @param code
     * @return
     */
ResponseResult<TasVo> getCheckIn(String code, String assigneeId, Integer flowStatus, String taskId);

业务层代码:

java 复制代码
/**
     * 查询入住信息
     *
     * @param code
     * @param assigneeId
     * @param flowStatus
     * @param taskId
     * @return
     */
@Override
public ResponseResult<TasVo> getCheckIn(String code, String assigneeId, Integer flowStatus, String taskId) {

    //根据code查询入住单
    CheckIn checkIn = checkInMapper.selectByCheckInCode(code);
    CheckInVo checkInVo = BeanUtil.toBean(checkIn, CheckInVo.class);

    //封装数据,方便前端展示
    JSONObject jsonObject = JSON.parseObject(checkInVo.getOtherApplyInfo(), JSONObject.class);
    if (ObjectUtil.isNotEmpty(jsonObject)) {
        JSONObject otherApplyInfo = JSON.parseObject(jsonObject.getString("otherApplyInfo"), JSONObject.class);
        checkInVo.setOtherApplyInfo(otherApplyInfo.toString());

        List<MemberElderDto> memberElderDtos = JSON.parseArray(jsonObject.getString("memberElderDtos"), MemberElderDto.class);
        checkInVo.setMemberElderDtos(memberElderDtos);

        ElderDto elderDto1 = JSON.parseObject(jsonObject.getString("elderDto"), ElderDto.class);
        checkInVo.setElderDto(elderDto1);

        //取出url信息
        checkInVo.setUrl1(jsonObject.getString("url1"));
        checkInVo.setUrl2(jsonObject.getString("url2"));
        checkInVo.setUrl3(jsonObject.getString("url3"));
    }

    //如果flowStatus小于0,重新赋值
    if (flowStatus < 0) {
        flowStatus = checkIn.getFlowStatus();
    }
    //isShow字段:0 只展示操作记录,1:展示详细数据集操作记录
    Integer isShow = 1;
    int step = 1;
    if (ObjectUtil.isNotEmpty(taskId)) {
        //查询当前流程在第几步
        isShow = actFlowCommService.isCurrentUserAndStep(taskId, flowStatus, checkIn.getFlowStatus());
    }

    TasVo tasVo = new TasVo();

    // 默认显示入住申请基本信息数据
    checkInVo.setIsShow(isShow);
    tasVo.setCheckIn(checkInVo);
    tasVo.setIsShow(isShow);
    //流程类型:入住
    tasVo.setType(3);

    //审批记录数据
    List<AccraditationRecord> accraditationRecordList
        = accraditationRecordMapper.getAccraditationRecordByBuisId(checkIn.getId(), PendingTasksConstant.TASK_TYPE_CHECK_IN);
    tasVo.setAccraditationRecords(accraditationRecordList);

    return ResponseResult.success(tasVo);
}

为了方便封装老人的数据,我们可以在新增新增退住的时候,把老人的数据封装到其他信息字符串中保存到数据库中,修改申请入住代码,如下:

java 复制代码
/**
     * 判断当前操作的是第几步
     * @param taskId
     * @param flowStatus
     * @param dbFlowStatus
     * @return
     */
@Override
public Integer isCurrentUserAndStep(String taskId, Integer flowStatus, Integer dbFlowStatus) {

    //当前任务人的节点
    HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
    String formKey = historicTaskInstance.getFormKey();

    //如果前端传递的流程状态跟数据库一致,当前操作人的任务节点与状态一致
    if (dbFlowStatus.equals(flowStatus) && dbFlowStatus.equals(CheckIn.Status.APPLICATION.getCode())
        && formKey.equals(dbFlowStatus.toString())) {
        return 1;
    }
    return 0;
}

3.4.4 控制层开发

java 复制代码
@GetMapping
@ApiOperation(value = "入住表单查询")
public ResponseResult<TasVo> getCheckIn(
        @RequestParam @ApiParam(value = "入住编码") String code,
        @RequestParam @ApiParam(value = "处理人ID") String assigneeId,
        @RequestParam @ApiParam(value = "流程状态") Integer flowStatus,
        @RequestParam(required = false) @ApiParam(value = "任务Id") String taskId) {
    return checkInService.getCheckIn(code, assigneeId, flowStatus, taskId);
}

3.4.5 测试

护理组长登录之后,查看待办列表,点击"处理"按钮后,可以查看之前录入的数据

3.5 护理主管-评估

3.5.1 思路分析

3.5.2 接口定义

在CheckInController中新增接口,如下:

java 复制代码
@PostMapping("/review")
@ApiOperation(value = "评估", notes = "传入入住对象")
public ResponseResult review(
        @RequestBody @ApiParam(value = "入住对象", required = true) CheckInDto checkInDto) {
    return null;
}

3.5.3 业务层开发

在CheckInService中新增方法,如下:

java 复制代码
/**
 * 评估
 * @param checkInDto
 * @return
 */
ResponseResult review(CheckInDto checkInDto);

实现类:

java 复制代码
/**
     * 评估
     * @param checkInDto
     * @return
     */
@Override
public ResponseResult review(CheckInDto checkInDto) {
    CheckIn checkIn = checkInMapper.selectByPrimaryKey(checkInDto.getId());
    checkIn.setFlowStatus(CheckIn.FlowStatus.APPROVAL.getCode());
    //保存健康评估数据
    checkIn.setReviewInfo(JSON.toJSONString(checkInDto));
    checkInMapper.updateByPrimaryKeySelective(checkIn);

    //  操作记录
    //从当前线程中获取用户数据
    String subject = UserThreadLocal.getSubject();
    User user = JSON.parseObject(subject, User.class);

    //完成流程
    actFlowCommService.completeProcess("", checkInDto.getTaskId(), user.getId().toString(), 1, null);

    //记录操作记录
    Long nextAssignee = actFlowCommService.getNextAssignee("checkIn-new", "checkIn-new:" + checkIn.getId());

    RecordVo recoreVo = getRecordVo(checkIn, user, AccraditationRecordConstant.AUDIT_STATUS_PASS,
                                    "同意", "护理部组长处理-入住评估",
                                    "院长处理-入住审批", nextAssignee
                                    , AccraditationRecordConstant.RECORD_HANDLE_TYPE_PROCESSED);
    accraditationRecordService.insert(recoreVo);

    return ResponseResult.success();
}

在ActFlowCommService中定义新的方法来完成任务

java 复制代码
/**
     * 完成任务
     * @param title  标题
     * @param taskId  任务id
     * @param userId  用户id
     * @param code   流程变量ops的值  1为同意,2为拒绝,3为驳回
     * @param status  审核状态  1,申请中  2 已完成   3  已关闭
     */
void completeProcess(String title, String taskId, String userId, Integer code, Integer status);

实现方法

java 复制代码
/**
     * 完成任务
     * @param title  标题
     * @param taskId  任务id
     * @param userId  用户id
     * @param code   流程变量ops的值  1为同意,2为拒绝,3为驳回
     * @param status  审核状态  1,申请中  2 已完成   3  已关闭
     */
@Override
public void completeProcess(String title, String taskId, String userId, Integer code, Integer status) {
    //任务Id 查询任务对象
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();

    if (task == null) {
        return;
    }

    //完成办理
    Map<String, Object> variables = new HashMap<>();
    if (ObjectUtil.isNotEmpty(status)) {
        variables.put("processStatus", status);
        variables.put("finishTime",LocalDateTime.now().toString());
    }
    if (ObjectUtil.isNotEmpty(title)) {
        variables.put("processTitle", title);
    }

    variables.put("ops", code);
    taskService.complete(taskId, variables);
}

3.5.4 控制层开发

补全完善控制层代码:

java 复制代码
@PostMapping("/review")
@ApiOperation(value = "评估", notes = "传入入住对象")
public ResponseResult<CheckInVo> review(
        @RequestBody @ApiParam(value = "入住对象", required = true) CheckInDto checkInDto) {
    return checkInService.review(checkInDto);
}

3.5.5 测试

使用护理组长账号登录,处理待办,提交表单,在数据库中查看是否保存成功

3.5.6 补全入住表单查询

因为现在我们在入住表中新增了评估的内容,那么当用户会看之前的数据,比如评估的内容,我们就需要在表单中进行展示这部分内容,如下图

如果想要回显这些数据,我们就需要修改刚才开发的入住表单查询的这个业务逻辑

修改CheckInServiceImpl的getCheckIn方法,添加如下代码

java 复制代码
//查询入住评估内容
JSONObject reviewInfoJsonObj = JSON.parseObject(checkInVo.getReviewInfo());
if(ObjectUtil.isNotEmpty(reviewInfoJsonObj)){
    String reviewInfo = reviewInfoJsonObj.getString("reviewInfo");
    String reviewInfo1 = reviewInfoJsonObj.getString("reviewInfo1");
    String reviewInfo2 = reviewInfoJsonObj.getString("reviewInfo2");
    checkInVo.setReviewInfo(reviewInfo);
    checkInVo.setReviewInfo1(reviewInfo1);
    checkInVo.setReviewInfo2(reviewInfo2);
}

测试:我们在回看入住评估信息的时候,可以正常显示评估的数据

3.5.7 修复数据展示(状态控制)

参数说明:

  • taskId 从前端传递过来,当前登录人的任务,可能是历史任务(执行过的),也可能是未执行的任务

  • flowStatus 从前端传递过来,用户在页面点击的流程节点

  • dbFlowStatus 后端存储的流程状态,指的是当前待执行的节点

举例:当前数据库中待执行的节点为2(院长审批)

  • 院长查看表单

  • 点击入住审批,可以查看表单数据,可以编辑数据,进行审核 taskId对应的formKey等于dbFlowStatus ,返回的isShow为1

  • 点击入住评估或者申请入住,可以查看表单数据,但是不能编辑,因为: dbFlowStatus不等于flowStatus,返回的isShow为1

  • 护理主管查看表单:

  • 点击入住审批,只能查看操作记录,不能编辑数据 taskId对应的formKey不等于dbFlowStatus,返回的isShow为0

  • 点击入住评估或者申请入住,可以查看表单数据,但是不能编辑,因为: dbFlowStatus不等于flowStatus,返回的isShow为1

  • 养老顾问查看表单:

  • 点击入住审批,只能查看操作记录,不能编辑数据 taskId对应的formKey不等于dbFlowStatus,返回的isShow为0

  • 点击入住评估或者申请入住,可以查看表单数据,但是不能编辑,因为: dbFlowStatus不等于flowStatus,返回的isShow为1

在getCheckIn方法中添加如下逻辑

java 复制代码
if(flowStatus < 0){
    flowStatus = checkIn.getFlowStatus();
}

if(ObjectUtil.isNotEmpty(taskId)){
    isShow = actFlowCommService.isCurrentUserAndStep(taskId,flowStatus,checkIn.getFlowStatus());
}

修改isCurrentUserAndStep方法,添加参数、添加如下逻辑

java 复制代码
@Override
public Integer isCurrentUserAndStep(String taskId,Integer flowStatus, Integer dbFlowStatus) {
    HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
    String formKey = historicTaskInstance.getFormKey();
    //前端传递的流程状态与数据库中一致,有两种情况,是不是当前人的任务,如果是,则返回1,不是返回0
    if (flowStatus.equals(dbFlowStatus)) {
        if (formKey.equals(dbFlowStatus.toString())) {
            return 1;
        }
        return 0;
    }
    return 1;
}

3.6 副院长-同意

当护理组长提交了数据之后,现在使用副院长账号登录,在待办列表中可以查看需要待办的数据

副院长的主要职责就是审核单子,有三种情况,分别是:同意、拒绝、驳回

这三种情况,分别对应了不同的接口,处理逻辑也是不一样的,我们先来实现第一个:审批通过(同意)

3.6.1 思路分析

3.6.2 接口定义

在CheckInController中新增接口,如下:

java 复制代码
@PutMapping("/submit")
@ApiOperation(value = "同意")
public ResponseResult submitCheckIn(
        @RequestParam @ApiParam(value = "入住Id") Long id,
        @RequestParam @ApiParam(value = "审批意见") String message,
        @RequestParam @ApiParam(value = "任务Id") String taskId) {
    return null;
}

3.6.3 业务层开发

在CheckInService中新增方法,如下:

java 复制代码
/**
 * 同意入住申请
 * @param id
 * @return
 */
ResponseResult submitCheckIn(Long id, String info, String taskId);

实现类:

java 复制代码
/**
     * 同意入住申请
     * @param id
     * @param message
     * @param taskId
     * @return
     */
@Override
public ResponseResult submitCheckIn(Long id, String message, String taskId) {
    // 流程状态 操作记录
    CheckIn checkIn = checkInMapper.selectByPrimaryKey(id);
    //设置流程状态
    checkIn.setFlowStatus(CheckIn.FlowStatus.CONFIG.getCode());
    checkInMapper.updateByPrimaryKeySelective(checkIn);
    //  操作记录
    //从当前线程中获取用户数据
    String subject = UserThreadLocal.getSubject();
    User user = JSON.parseObject(subject, User.class);
    //完成任务
    actFlowCommService.completeProcess("", taskId, user.getId().toString(), 1, null);

    // 养老顾问
    CheckIn checkIn1 = checkInMapper.selectByPrimaryKey(checkIn.getId());
    Long userId = checkIn1.getApplicatId();
    RecordVo recoreVo = getRecordVo(checkIn,
                                    user,
                                    AccraditationRecordConstant.AUDIT_STATUS_PASS,
                                    message,
                                    "院长处理-入住审批",
                                    "养老顾问处理-入住配置",
                                    userId,
                                    AccraditationRecordConstant.RECORD_HANDLE_TYPE_AUDIT);
    accraditationRecordService.insert(recoreVo);
    return ResponseResult.success();
}

3.6.4 控制层开发

补全完善控制层代码:

java 复制代码
@PutMapping("/submit")
@ApiOperation(value = "同意")
public ResponseResult submitCheckIn(
        @RequestParam @ApiParam(value = "入住Id") Long id,
        @RequestParam @ApiParam(value = "审批意见") String message,
        @RequestParam @ApiParam(value = "任务Id") String taskId) {
    return checkInService.submitCheckIn(id, message, taskId);
}

3.6.5 测试

当审核成功以后,副院长可以在已处理列表中进行查看,分配给下一个处理人为:申请人(养老顾问)

3.7 副院长-拒绝

在副院长审核的时候,假如副院长感觉数据有问题,也可以拒绝审批,拒绝审批的是另外的一个接口

3.7.1 思路分析

先打开,我们之前定义的流程,里面定义了两个网关,当拒绝的时候,ops为2

流程是:先走第一个网关,然后走第二个网关,最后结束流程即可

3.7.2 接口定义

在CheckInController中新增接口,如下:

java 复制代码
@PutMapping("/reject")
@ApiOperation(value = "审核拒绝")
public ResponseResult auditReject(
        @RequestParam @ApiParam(value = "入住Id") Long id,
        @RequestParam @ApiParam(value = "拒绝原因") String message,
        @RequestParam @ApiParam(value = "任务Id") String taskId) {
    return null;
}

3.7.3 业务层开发

在CheckInService中新增方法,如下:

java 复制代码
/**
 * 审核拒绝
 * @param id  入住单code
 * @param reject   拒绝原因
 * @return
 */
ResponseResult auditReject(Long id, String reject, String taskId);

实现类:

java 复制代码
/**
     * 拒绝
     * @param id
     * @param message
     * @param taskId
     * @return
     */
@Override
public ResponseResult auditReject(Long id, String message, String taskId) {
    //查询入住数据
    CheckIn checkIn = checkInMapper.selectByPrimaryKey(id);
    //设置流程状态
    checkIn.setFlowStatus(CheckIn.FlowStatus.CONFIG.getCode());
    checkIn.setStatus(CheckIn.Status.CLOSED.getCode());
    checkInMapper.updateByPrimaryKey(checkIn);
    //删除老人数据
    close(checkIn);

    String subject = UserThreadLocal.getSubject();
    User user = JSON.parseObject(subject, User.class);

    actFlowCommService.completeProcess("", taskId, user.getId().toString(), 2, CheckIn.Status.CLOSED.getCode());

    //记录操作记录
    RecordVo recoreVo = getRecordVo(checkIn,
                                    user,
                                    AccraditationRecordConstant.AUDIT_STATUS_REJECT,
                                    message,
                                    "院长处理-入住审批",
                                    "",
                                    null,
                                    AccraditationRecordConstant.RECORD_HANDLE_TYPE_PROCESSED);
    accraditationRecordService.insert(recoreVo);

    return ResponseResult.success();
}

private void close(CheckIn checkIn){
    elderService.deleteByPrimaryKey(checkIn.getElderId());
}

为了方便展示任务列表(我的待办和我的申请),在任务已关闭或者已完成之后需要返回完成时间

第一,修改ActFlowCommServiceImpl中的completeProcess方法,如果审核状态不为空,则需要设置完成时间到流程变量中

java 复制代码
if (ObjectUtil.isNotEmpty(status)) {
    variables.put("processStatus", status);
    variables.put("finishTime",LocalDateTime.now().toString());
}

第二,修改ActFlowCommServiceImpl中的getMyTaskList方法,在返回数据中添加如下代码

java 复制代码
//如果审核状态为已关闭或已完成,则需要返回完成时间
if(pendingTasks.getStatus().equals(PendingTasksConstant.TASK_STATUS_CLOSED) 
|| pendingTasks.getStatus().equals(PendingTasksConstant.TASK_STATUS_FINISHED)){
    LocalDateTime finishTime = LocalDateTimeUtil.parse(processVariables.get("finishTime").toString());
    pendingTasks.setFinishTime(finishTime);
}

3.7.4 控制层开发

补全完善控制层代码:

java 复制代码
@PutMapping("/reject")
@ApiOperation(value = "审核拒绝")
public ResponseResult auditReject(
        @RequestParam @ApiParam(value = "入住Id") Long id,
        @RequestParam @ApiParam(value = "拒绝原因") String message,
        @RequestParam @ApiParam(value = "任务Id") String taskId) {
    return checkInService.auditReject(id, message, taskId);
}

3.7.5 测试

当拒绝之后,申请人查看数据,当前入住单已经结束,老人数据清空。

相关推荐
MAGICIAN...2 小时前
【java-软件设计原则】
java·开发语言
JH30732 小时前
为什么switch不支持long
java
gpfyyds6662 小时前
Python代码练习
开发语言·python
盐真卿2 小时前
python第八部分:高级特性(二)
java·开发语言
茉莉玫瑰花茶2 小时前
C++ 17 详细特性解析(5)
开发语言·c++·算法
上海合宙LuatOS2 小时前
LuatOS核心库API——【audio 】
java·网络·单片机·嵌入式硬件·物联网·音视频·硬件工程
lly2024062 小时前
《堆的 shift down》
开发语言
汤姆yu2 小时前
基于springboot的尿毒症健康管理系统
java·spring boot·后端
TT哇2 小时前
【实习】银行经理端线下领取扫码功能实现方案
java