首页 > 其他分享 >ruoyi框架学习笔记(二)

ruoyi框架学习笔记(二)

时间:2024-03-12 22:04:53浏览次数:22  
标签:notice String 框架 流程 公告 ruoyi private 笔记 oneVo

三、通知公告发布流程搭建

3.1 功能策划

在第一篇学习笔记中已经将“通知公告”拆分为两个部分,分别为

  • 全部公告:主要是实现查看所有用户已经走完发布流程且是发布状态的公告;
  • 我的公告:实现当前用户新建公告、发起审批流程并发布公告的编辑位置;

在笔记一中已经实现上述两个部分的前后端的开发,但对于发起审批流程的过程尚未开发,本次予以实现,使用户在“我的公告”中能够完成以下操作:

  • 可以新建、修改、删除公告的文稿
  • 可以发起审批流程
  • 可以对在流程中的公告文稿强制取消审批流程、删除流程、重新发起流程
  • 可以在公告中显示当前流程状态和审批流程进度

3.2 流程引擎

为实现上述功能策划,需引入流程引擎。目前与ruoyi整合在一起的floawable或activiti的开源框架有很多,本笔记学习过程中重点参考了KonBAI大佬的RuoYi-Flowable-Plus项目,开源项目地址:

https://gitee.com/KonBAI-Q/ruoyi-flowable-plus

个人感觉这个项目整合的非常好,有兴趣可以深入学习并STAR

3.3 新增SQL表并生成代码

流程开发计划在上述流程引擎的基础上搭建。故需要建立一个SQL表,用以存储通知公告表与流程表之间的关联:

sys_workflow_notice表:

使用ruoyi框架中代码生成器生成代码,本笔记学习过程中,因不涉及到此新增表的前端,主要使用生成的main代码,并设置包的位置为 com.ruoyi.workflow:

controller为统一管理,放置在了admin模块下 com.ruoyi.web.controller,以便于统一管理

3.4 flowable表单构建

为了flowable流程能够与本笔记一中改造的“我的公告”的表单关联起来,计划在flowable模块中按照“我的公告”中的新建表单仿制构建一个flowable表单,当在“我的公告”中点击“发起流程”按钮时,后端直接将“我的公告”中的表单内容自动填写到这个flowable表单中:

重点是公告标题、公告类型、公告内容三个部分,尤其注意这三个部分的字段名应该与“我的公告”中对应的表单元素的字段名保持一致,本笔记中命名为noticeTitle、noticeType、noticeContent

过程问题及解决:

问题1:flowable表单构建的公告类型中字段noticeType的类型为int类型、而“我的公告”中表单的类型为string类型,导致两个表单关联后,在flowable表单中此处显示的是个数字,而不是数字对应的字典值,解决思路为更改flowable表单这个组件的数据类型为字符型:

  • 修改前端文件 utils/generator/config.js 中下拉选择组件的value值为:
  {
    __config__: {
      label: '下拉选择',
      showLabel: true,
      labelWidth: null,
      tag: 'el-select',
      tagIcon: 'select',
      layout: 'colFormItem',
      span: 24,
      required: true,
      regList: [],
      changeTag: true,
      document: 'https://element.eleme.cn/#/zh-CN/component/select'
    },
    __slot__: {
      options: [{
        label: '选项一',
        value: "1"
      }, {
        label: '选项二',
        value: "2"
      }]
    },
    placeholder: '请选择',
    style: {width: '100%'},
    clearable: true,
    disabled: false,
    filterable: false,
    multiple: false
  },
  • 修改前端文件 views/tool/build/RightPanel.vue中的添加选项时的value默认为String(item.value),使构建表单的下拉选择组件时右侧添加时默认为字符类型数值: 
<div v-for="(item, index) in activeData.__slot__.options" :key="index" class="select-item">
    <div class="select-line-icon option-drag">
        <i class="el-icon-s-operation" />
    </div>
    <el-input v-model="item.label" placeholder="选项名" size="small" />
    <el-input placeholder="选项值" size="small" :value="String(item.value)"  @input="setOptionValue(item, $event)" />
    <div class="close-btn select-line-icon" @click="activeData.__slot__.options.splice(index, 1)">
    <i class="el-icon-remove-outline" />
    </div>
</div>

问题2:flowable表单搭建完毕后,前端浏览器不定时的报错:

vue.runtime.esm.js:619  [Vue warn]: Unknown custom element: <tinymce> - did you register the component correctly? For recursive components, make sure to provide the "name" option.......

同时前端页面中的内容编辑器组件出现问题,无法正常显示:  

解决:经查主要是组件未能及时加载造成的,故将组件挂载到全局,针对根目录下 main.js修改

3.5 bpmn流程图

按“发起-审核-结束”的简易流程搭建bpmn流程图如下:

其中开始中添加构建的flowable表单,发起指定任务执行者为发起人,审核按角色指定发起人员所在部门上级,并将模式改为或签(有一人审批即可通过)

完成bpmn流程图搭建后予以部署:

部署完毕后,可在数据库中的act_re_procdef 表中查询到对应的ID号:

 需要记录下此ID号,导入“我的公告”前端vue文件中,作为“我的公告”中的数据填写至flowable表单时请求的api的参数,导入方式可参考下节。

3.6 前端代码改造

在 views/system/notice目录下新增一config.js文件,用以存放上述procdef的ID号:

export const DefinitionId = "Process_1709900320599:1:3019a4bd-dd46-11ee-89d6-7aaf089de9eb";

其中的字符串为本笔记搭建的流程对应得prodef表的ID号。

之后针对create.vue文件作如下改造:

  • 状态显示为“新建”或“流程状态”,当存在流程状态时显示流程状态,否则显示“新建” 
<el-table-column label="状态" align="center" prop="status" width="100">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.wf_process_status" :value="scope.row.processStatus" v-if="scope.row.processStatus"/>
          <dict-tag :options="dict.type.sys_notice_status" :value="scope.row.status" v-else/>
        </template>
      </el-table-column>
dicts: ['sys_notice_status', 'sys_notice_type','wf_process_status'],
  • 流程操作 中,若未发起流程则显示为“发起”按钮,否则显示“详情”和“取消”,并且当流程状态为“已取消”时,显示为“详情”和“删除流程”
<el-table-column label="流程操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">

          <el-button
            type="text"
            size="mini"
            icon="el-icon-video-play"
            @click="handleStart(scope.row)"
            v-if="!scope.row.processStatus"
            v-hasPermi="['workflow:process:start']"
          >发起</el-button>
          <template v-else>

            <el-button
            type="text"
            size="mini"
            icon="el-icon-tickets"
            @click="handleFlowRecord(scope.row)"
            v-hasPermi="['workflow:process:query']"
          >详情</el-button>

          <el-button
            type="text"
            size="mini"
            icon="el-icon-circle-close"
            v-if="!scope.row.finishTime"
            @click="handleStop(scope.row)"
            v-hasPermi="['workflow:process:cancel']"
          >取消</el-button>

          <el-button
            type="text"
            size="mini"
            icon="el-icon-delete"
            @click="handleFlowDelete(scope.row)"
            v-if="scope.row.finishTime"
            v-hasPermi="['workflow:process:remove']"
          >删除流程</el-button>

          </template>
        </template>
</el-table-column>

对应的各按钮方法改造 :

  • 文档的修改、删除按钮操作:增加限制,当存在流程时不允许修改或删除文档

/** 修改按钮操作 */
    handleUpdate(row) {
      const noticeId = row.noticeId || this.ids
      this.noticeList.forEach(element => {
        if(element.noticeId == noticeId){
            if(element.processStatus) {
              this.$modal.msgError("非新建状态(存在流程)不能修改或删除!");
            } else {
              this.reset();
              const noticeId = row.noticeId || this.ids
              getNotice(noticeId).then(response => {
                this.form = response.data;
                this.open = true;
                this.title = "修改公告";
              });        
            }
        }
      }); 
    },
/** 删除按钮操作 */
    handleDelete(row) {

      const noticeId = row.noticeId || this.ids
      this.noticeList.forEach(element => {
        if(element.noticeId == noticeId){
            if(element.processStatus) {
              this.$modal.msgError("非新建状态(存在流程)不能修改或删除!");
            } else {

              this.$modal.confirm('是否确认删除公告编号为"' + noticeId + '"的数据项?').then(function() {
                return delNotice(noticeId);
              }).then(() => {
                this.getList();
                this.$modal.msgSuccess("删除成功");
              }).catch(() => {});

            }
          }
        });
    },
  • 流程的发起、详情、取消、删除操作:流程取消可显示删除 
 handleStart(row){
        // 启动流程并将表单数据加入流程变量
        startProcess(DefinitionId, JSON.stringify(row)).then(res => {
        this.$modal.msgSuccess(res.msg);
        this.getList();
      })
      // console.log(row);
    },
    /** 流程流转记录 */
    handleFlowRecord(row) {
      this.$router.push({
        path: '/workflow/process/detail/' + row.procInsId,
        query: {
          processed: false
        }
      })
    },
    /**  取消流程申请 */
    handleStop(row){
      const params = {
        procInsId: row.procInsId
      }
      const noticeIds = row.noticeId || this.ids
      this.$modal.confirm('是否取消公告编号为"' + noticeIds + '"的流程?').then(function() {
        return stopProcess(params);
      })
      .then( res => {
        this.$modal.msgSuccess(res.msg);
        this.getList();
      }).catch(() => {});
    },
    /** 删除流程按钮操作 */
    handleFlowDelete(row) {
      const ids = row.procInsId || this.ids;
      this.$confirm('是否确认删除流程定义编号为"' + ids + '"的数据项?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(function() {
        return delProcess(ids);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      })
    },

其中的流程发起操作中的DefinitionId变量,即为导入的procdef的ID号

import { DefinitionId } from './config'

 导入的api信息如下

import { listCurrUserNotice,getNotice, delNotice, addNotice, updateNotice } from "@/api/system/notice"
import { startProcess , stopProcess, delProcess } from '@/api/workflow/process'

3.7 后端代码改造

 改造思路主要是两大部分,第一是查询全部已发布公告的方法改造,需要考虑公告对应的流程状态,即需要关联查询3.3中新增的sys_workflow_notice关联表;第二就是查询当前用户的所有公告并关联流程状态。为此,新增一NoticeFlowService业务逻辑类和相关视图返回数据的实体类

 

其中的NoticeFlowVo视图实体类为流程相关信息和通知公告相关信息的联合体:

@Data
public class NoticeFlowVo extends BaseEntity implements Serializable {
    /**
     * 任务编号
     */
    private String taskId;
    /**
     * 任务名称
     */
    private String taskName;
    /**
     * 任务Key
     */
    private String taskDefKey;
    /**
     * 任务执行人Id
     */
    private Long assigneeId;
    /**
     * 部门名称
     */
    @Deprecated
    private String deptName;
    /**
     * 流程发起人部门名称
     */
    @Deprecated
    private String startDeptName;
    /**
     * 任务执行人名称
     */
    private String assigneeName;
    /**
     * 流程发起人Id
     */
    private Long startUserId;
    /**
     * 流程发起人名称
     */
    private String startUserName;
    /**
     * 流程类型
     */
    private String category;
    /**
     * 流程变量信息
     */
    private Object procVars;
    /**
     * 局部变量信息
     */
    private Object taskLocalVars;
    /**
     * 流程部署编号
     */
    private String deployId;
    /**
     * 流程ID
     */
    private String procDefId;
    /**
     * 流程key
     */
    private String procDefKey;
    /**
     * 流程定义名称
     */
    private String procDefName;
    /**
     * 流程定义内置使用版本
     */
    private int procDefVersion;
    /**
     * 流程实例ID
     */
    private String procInsId;
    /**
     * 历史流程实例ID
     */
    private String hisProcInsId;
    /**
     * 任务耗时
     */
    private String duration;
    /**
     * 任务意见
     */
    private WfCommentDto comment;
    /**
     * 任务意见
     */
    private List<Comment> commentList;
    /**
     * 候选执行人
     */
    private String candidate;
    /**
     * 任务创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * 任务完成时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date finishTime;

    /**
     * 流程状态
     */
    private String processStatus;


    /**
     * 数据表的顺序号
     */

    private Long noId;

    /**
     * 公告ID
     */

    private Long noticeId;

    /**
     * 公告标题
     */

    private String noticeTitle;

    /**
     * 公告类型(1通知 2公告)
     */
    private String noticeType;

    /**
     * 公告内容
     */
    private String noticeContent;

    /**
     * 公告状态(0正常 1关闭)
     */
    private String status;

    /**
     * 备注
     */
    private String remark;


    private Long isRead;
}

NoticeFlowService的业务逻辑重点处理上述2种情况的:

  • 所有流程状态为“已完成”的通知公告数据的查询功能:
@Override
    public TableDataInfo<SysNotice> selectPageNoticeFinishedList(SysNotice notice, PageQuery pageQuery, Long currentUserId) {
        LambdaQueryWrapper<SysNotice> lqw = new LambdaQueryWrapper<SysNotice>()
            .like(StringUtils.isNotBlank(notice.getNoticeTitle()), SysNotice::getNoticeTitle, notice.getNoticeTitle())
            .eq(StringUtils.isNotBlank(notice.getNoticeType()), SysNotice::getNoticeType, notice.getNoticeType())
            .like(StringUtils.isNotBlank(notice.getCreateBy()), SysNotice::getCreateBy, notice.getCreateBy());
        // 查询所有通知公告及其对应的流程实例
        List<SysNotice> noticeList = sysNoticeBaseMapper.selectList(lqw);
        List<SysNotice> records = new ArrayList<>();
        int i = PageQuery.DEFAULT_PAGE_NUM;
        for (SysNotice one : noticeList) {
            SysWorkflowNoticeVo sysWorkflowNoticeVo = sysWorkflowNoticeService.queryOneByNoticeId(one.getNoticeId());
            if (sysWorkflowNoticeVo != null) {
                HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(sysWorkflowNoticeVo.getProcinstId());
                List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.list();
                HistoricProcessInstance hisIns = historicProcessInstances.get(0);
                HistoricVariableInstance processStatusVariable = historyService.createHistoricVariableInstanceQuery()
                    .processInstanceId(sysWorkflowNoticeVo.getProcinstId())
                    .variableName(ProcessConstants.PROCESS_STATUS_KEY)
                    .singleResult();
                //获取流程状态
                String processStatus = null;
                if (ObjectUtil.isNotNull(processStatusVariable)) {
                    // 获取流程节点信息
                    List<Comment> comments = wfProcessService.historyProcNodeList(hisIns).get(1).getCommentList();
                    //流程取消时,系统记录的流程状态也为已完成,此时与实际正常完成的流程无法区分,暂时按增加一条备注信息来处理,实际查询过程中查询此备注信息进行状态区分
                    if(!(comments.isEmpty())) {
                        System.out.println(comments.get(0).getType());
                        System.out.println(comments.get(0).getFullMessage());
                        if(comments.get(0).getType().contains("7") && comments.get(0).getFullMessage().contains("取消申请")){
                            processStatus = ProcessStatus.CANCELED.getStatus();
                            System.out.println(processStatus);
                        }else{
                            processStatus = Convert.toStr(processStatusVariable.getValue());
                        }
                    }
                }
                // 兼容旧流程
                if (processStatus == null) {
                    processStatus = ObjectUtil.isNull(hisIns.getEndTime()) ? ProcessStatus.RUNNING.getStatus() : ProcessStatus.COMPLETED.getStatus();
                }
                //增加序号的显示
                if (ProcessStatus.COMPLETED.getStatus().equals(processStatus)) {
                    one.setNoId((long) i);
                    one.setCreateBy(String.valueOf(sysUserService.selectUserByUserName(one.getCreateBy()).getNickName()));
                    SysUserNoticeVo isReadResult = sysUserNoticeService.queryByIdAndNoticeId(currentUserId, one.getNoticeId());
                    if(isReadResult != null){
                        one.setIsRead(Long.valueOf(dictDataService.selectDictValue("sys_notice_isread", "已读")));
                    } else {
                        one.setIsRead(Long.valueOf(dictDataService.selectDictValue("sys_notice_isread", "未读")));
                    }
                    records.add(one);
                    i++;
                }
            }

        }
        //分页
        Page<SysNotice> page = new Page<>(pageQuery.getPageNum() + 1, pageQuery.getPageSize());
        page.setTotal(records.size());
        int start = (pageQuery.getPageNum() - 1) * pageQuery.getPageSize();
        int end = pageQuery.getPageNum() * pageQuery.getPageSize();
        page.setRecords(records.stream().skip(start).limit(end).collect(Collectors.toList()));
        return TableDataInfo.build(page);
    }
  • 当前用户所有通知及流程状态的查询:
    @Override
    public TableDataInfo<NoticeFlowVo> selectPageCurrUserNoticeFlowList(SysNotice notice, PageQuery pageQuery, Long userId) {
        LambdaQueryWrapper<SysNotice> lqw = new LambdaQueryWrapper<SysNotice>()
            .like(StringUtils.isNotBlank(notice.getNoticeTitle()), SysNotice::getNoticeTitle, notice.getNoticeTitle())
            .eq(StringUtils.isNotBlank(notice.getNoticeType()), SysNotice::getNoticeType, notice.getNoticeType())
            .eq(SysNotice::getCreateBy, sysUserService.selectUserById(userId).getUserName());
        Page<SysNotice> page = sysNoticeBaseMapper.selectPage(pageQuery.build(), lqw);
        Page<NoticeFlowVo> result = new Page<>();
        result.setTotal(page.getTotal());
        int i = PageQuery.DEFAULT_PAGE_NUM;
        //所有当前用户的通知公告
        List<NoticeFlowVo> records = new ArrayList<>();
        for( SysNotice one : page.getRecords()) {
            NoticeFlowVo oneVo = new NoticeFlowVo();
            oneVo.setNoticeId(one.getNoticeId());
            oneVo.setNoticeTitle(one.getNoticeTitle());
            oneVo.setNoticeType(one.getNoticeType());
            oneVo.setNoticeContent(one.getNoticeContent());
            oneVo.setStatus(one.getStatus());
            oneVo.setCreateTime(one.getCreateTime());
            oneVo.setNoId(Long.valueOf((pageQuery.getPageNum()-1)*pageQuery.getPageSize()+i));
            i++;

            //查询相关流程的内容
            SysWorkflowNoticeVo sysWorkflowNoticeVo = sysWorkflowNoticeService.queryOneByNoticeId(one.getNoticeId());
            if(sysWorkflowNoticeVo != null) {
                HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(sysWorkflowNoticeVo.getProcinstId());
                List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.list();
                HistoricProcessInstance hisIns = historicProcessInstances.get(0);
                HistoricVariableInstance processStatusVariable =  historyService.createHistoricVariableInstanceQuery()
                    .processInstanceId(sysWorkflowNoticeVo.getProcinstId())
                    .variableName(ProcessConstants.PROCESS_STATUS_KEY)
                    .singleResult();
                String processStatus = null;
                if (ObjectUtil.isNotNull(processStatusVariable)) {
                    // 获取流程节点信息
                    List<Comment> comments = wfProcessService.historyProcNodeList(hisIns).get(1).getCommentList();
                    //流程取消时,系统记录的流程状态也为已完成,此时与实际正常完成的流程无法区分,暂时按增加一条备注信息来处理,实际查询过程中查询此备注信息进行状态区分
                    if(!(comments.isEmpty())) {
                        System.out.println(comments.get(0).getType());
                        System.out.println(comments.get(0).getFullMessage());
                        if(comments.get(0).getType().contains("7") && comments.get(0).getFullMessage().contains("取消申请")){
                            processStatus = ProcessStatus.CANCELED.getStatus();
                            System.out.println(processStatus);
                        }else{
                            processStatus = Convert.toStr(processStatusVariable.getValue());
                        }
                    }
                }
                // 兼容旧流程
                if (processStatus == null) {
                    processStatus = ObjectUtil.isNull(hisIns.getEndTime()) ? ProcessStatus.RUNNING.getStatus() : ProcessStatus.COMPLETED.getStatus();
                }
                oneVo.setProcessStatus(processStatus);
                oneVo.setCreateTime(hisIns.getStartTime());
                oneVo.setFinishTime(hisIns.getEndTime());
                oneVo.setProcInsId(hisIns.getId());
                // 计算耗时
                if (Objects.nonNull(hisIns.getEndTime())) {
                    oneVo.setDuration(DateUtils.getDatePoor(hisIns.getEndTime(), hisIns.getStartTime()));
                } else {
                    oneVo.setDuration(DateUtils.getDatePoor(DateUtils.getNowDate(), hisIns.getStartTime()));
                }
                // 流程部署实例信息
                Deployment deployment = repositoryService.createDeploymentQuery()
                    .deploymentId(hisIns.getDeploymentId()).singleResult();
                oneVo.setDeployId(hisIns.getDeploymentId());
                oneVo.setProcDefId(hisIns.getProcessDefinitionId());
                oneVo.setProcDefName(hisIns.getProcessDefinitionName());
                oneVo.setProcDefVersion(hisIns.getProcessDefinitionVersion());
                oneVo.setCategory(deployment.getCategory());
                // 当前所处流程
                List<Task> taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).includeIdentityLinks().list();
                if (CollUtil.isNotEmpty(taskList)) {
                    oneVo.setTaskName(taskList.stream().map(Task::getName).filter(StringUtils::isNotEmpty).collect(Collectors.joining(",")));
                }
            }
            records.add(oneVo);
        }
        result.setRecords(records);
        return  TableDataInfo.build(result);
    }

修改controller中getLlist对应的公告查询方法为以上方法。至此主要后端的改造已完成。

其他的后端改造:

  • WfTaskServiceImpl中的stopProcess方法中,增加两行取消后的备注功能
taskService.addComment(task.get(0).getId(), processInstance.getProcessInstanceId(), FlowComment.REVOKE.getType(),
StringUtils.isBlank(bo.getComment()) ? "取消申请" : bo.getComment());
  •  WfProcessServiceImpl中的deletProcessByIds方法,增加删除流程后同时删除sys_workfow_notice表中的相关流程数据的功能
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteProcessByIds(String[] instanceIds) {
        List<String> ids = Arrays.asList(instanceIds);
        // 校验流程是否结束
        long activeInsCount = runtimeService.createProcessInstanceQuery()
            .processInstanceIds(new HashSet<>(ids)).active().count();
        if (activeInsCount > 0) {
            throw new ServiceException("不允许删除进行中的流程实例");
        }
        //删除流程实例的同时,需要删除sys_workflow_notice表中的数据
        List<String>  sysWorkflowNoticeId = new ArrayList<>();
        for (String instanceId : instanceIds) {
            SysWorkflowNoticeVo one = sysWorkflowNoticeService.queryOneByProcinsId(instanceId);
            if(one != null){
                sysWorkflowNoticeId.add(instanceId);
            }
        }
        sysWorkflowNoticeService.deleteWithValidByIds(sysWorkflowNoticeId, !sysWorkflowNoticeId.isEmpty());
        // 删除历史流程实例
        historyService.bulkDeleteHistoricProcessInstances(ids);
    }
  • WfProcessServiceImpl中的startProcess方法,增加发起流程后的在sys_workflow_notice中添加关联信息的功能
//同时记录到sys_workflow_notice表中
if(variables.containsKey("noticeId")){
            Long noticeId =Long.valueOf(String.valueOf(variables.get("noticeId")));
            String procInstId = processInstance.getId();
            SysWorkflowNoticeBo workflowNoticeBo = new  SysWorkflowNoticeBo();
            workflowNoticeBo.setProcinstId(procInstId);
            workflowNoticeBo.setNoticeId(noticeId);
            workflowNoticeBo.setDelFlag("0");
            sysWorkflowNoticeService.updateByBo(workflowNoticeBo);
        }
  • 同时改造代码生成器生成的SysWorkflowNoticeServiceImpl中的updateByBo方法,以支持上述的添加功能
    /**
     * 修改流程和通知关联
     */
    @Override
    public Boolean updateByBo(SysWorkflowNoticeBo bo) {
        SysWorkflowNotice update = BeanUtil.toBean(bo, SysWorkflowNotice.class);
        validEntityBeforeSave(update);
        SysWorkflowNoticeVo sysWorkflowNoticeVo = baseMapper.selectVoOne(new LambdaQueryWrapper<SysWorkflowNotice>().eq(SysWorkflowNotice::getProcinstId, bo.getProcinstId())
            .eq(SysWorkflowNotice::getNoticeId, bo.getNoticeId()));
        if (sysWorkflowNoticeVo != null) {
            return baseMapper.update(update, new LambdaUpdateWrapper<SysWorkflowNotice>().eq(SysWorkflowNotice::getProcinstId, bo.getProcinstId())) > 0 ;
        } else {
            return baseMapper.insert(update) > 0;
        }
    }

3.8 最终效果

最终实现的通知公告发布流程操作效果如下:

  • 新增公告:

 

  • 发起发布审批流程

 

  • 流程详情查看

 

  • 流程审批

  • 公告发布成功!

 

3.9 遗留问题 

改造完毕过程中,仍有些问题可以进一步改进,后期可以持续改善:

  •  流程强制取消后的状态标记使用的是注释,而没有直接写入流程状态,增加了一次查询过程,数据量大时影响效率,后期需考虑改进
  • 流程的procdefId号是建立完毕后在数据库手工查找的,再记录到config.js文件,这样等于是写死了,不利于流程模型的更新,后期考虑通过前端的对话框等方式予以配置
  • 流程到达审批者的时候,可以考虑增加一条即时的提醒弹出窗口,提醒审批者及时审批,后期考虑增加即时提醒弹窗功能

标签:notice,String,框架,流程,公告,ruoyi,private,笔记,oneVo
From: https://blog.csdn.net/m0_46461077/article/details/136653568

相关文章

  • C语言学习笔记day3
    1.逗号运算符           逗号运算符连接的表达式,从左至右依次执行,最后一个逗号后面的表达式结果作为   整体的逗号表达式的结果2.sizeof运算符        sizeof(数据类型/变量名)        获得一个数据类型或者变量在内存中所占的......
  • 回文自动机学习笔记
    回文自动机学习笔记定义所谓自动机,是一个对信号序列进行判定的数学模型。即对一连串有顺序的信号关于某一个判定给出或真或假的判定。所谓回文自动机,就是对一个字符串进行其是否为回文串的判定。也就是存储字符串\(s\)中的所有的回文串。与\(\text{SA}\)不同的是,\(\text{SA......
  • 计算机三级网络技术之IP地址规划技术与路由设计技术基础 笔记
    IP地址规划技术NAT的工作原理:当内部网络的一个专用地址需要访问外网时,NAT将其转换为Internet上唯一的外部公用地址+端口号。而当外部网络响应这个访问请求时只能是响应给外部公用IP地址+端口号,此时NAT技术再将外部公用地址+端口号转换为内部地址+端口号以成功访问。IPv6......
  • Python入门学习笔记(1)Python&VS code下载与配置
    去年夏天,笔者拿到EricMatthes所著的蟒蛇书,一番学习下,为其细致与条理所触动。作为曾经学过C++的NOIP退役选手,笔者深知一个好的语言基础对于后续学习的巨大作用。费曼提到,把新知识、复杂概念解释给完全不懂的人听,是最好的提升知识质量、把知识点融入自己的知识体系的方法。因此......
  • 代码随想录刷题笔记
    代码随想录刷题数组二分查找思路:有序数组,数组中无重复元素移除元素思路:数组在内存地址中是连续的,不能单独删除某个数组中的某个元素,只能覆盖快慢指针法,用于数组、链表、字符串等的操作双向指针法,更优,移动更少的元素注意:补充快慢指针法的代码交换时候......
  • 动态链表学习笔记:查找,插入与删除
    目录情境引入:一、数据的查找1.要求:2.思路:3.程序:4.运行:二、数据的插入 1.要求:2.思路: 3.程序: 4.运行:三、数据的删除1.要求:2.思路:3.程序:4.运行四、调整与小结:优化:运行情境引入:        学习了动态链表的输入输出后,若还需要对其进行进一步的操作,......
  • Vue2.x笔记:组件通信
    一、插槽slot插槽(slot)是一种Vue中组件通信的方式,主要用于父组件向子组件传递自定义内容。有三种插槽:默认插槽:最基本的插槽,没有任何标识,每个子组件只能定义一个具名插槽:具有name属性的默认插槽,每个子组件可以定义多个作用域插槽:子组件提供数据,由父组件决定其渲染方式1.默......
  • 基于Vue(提供Vue2/Vue3版本)和.Net Core前后端分离、跨平台的快速开发框架
    前言今天大姚给大家推荐一款基于Vue(提供Vue2/Vue3版本)和.NetCore前后端分离、开源免费(MITLicense)、强大、跨平台的快速开发框架,并且框架内置代码生成器(解决重复性工作,提高开发效率),支持移动端(iOS/Android/H5/微信小程序):Vue.NetCore。提高开发生产效率、避免996可以考虑试试这......
  • 叮!请查收昇思人工智能框架峰会2024邀请函
    昇思MindSpore人工智能框架峰会,北京国家会议中心,2024年3月21闭门会议,3月22日主论坛和开发者嘉年华,人工智能产学研用专家齐聚,诚邀各位开发者参加~~......
  • go语言笔记
    学golang,我需要阅读一本go语言的书籍,也需要浏览和go相关的社区网站。有一个问题是,为什么需要阅读一本编程书籍?直接从网上搜索是可以找到很多快餐资料的,似乎比书籍更有效?答案是全面。通常,书的质量比博客高多了,我现在写的就是博客,算不上书籍。书籍的质量也体现在它的内容比较系统......