1
0
Fork 0

主线合并代码v0.0.1版本

dev_zl
UP管理员 2024-07-14 00:43:04 +08:00
parent ba1418ea9b
commit 5424267bf7
49 changed files with 19611 additions and 133 deletions

View File

@ -67,7 +67,8 @@ public class SysOssController extends BaseController {
*
* @param file
*/
@SaCheckPermission("system:oss:upload")
// @SaCheckPermission("system:oss:upload")
// zqjia:这个权限校验打开的话普通用户无法上传文件,导致无法上传指南和申报书
@Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Map<String, String>> upload(@RequestPart("file") MultipartFile file) {
@ -87,7 +88,8 @@ public class SysOssController extends BaseController {
*
* @param ossId OSSID
*/
@SaCheckPermission("system:oss:download")
// @SaCheckPermission("system:oss:download")
// zqjia:这个权限校验打开的话普通用户无法下载文件,导致无法下载指南
@GetMapping("/download/{ossId}")
public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException {
iSysOssService.download(ossId,response);

View File

@ -17,13 +17,17 @@ import com.ruoyi.workflow.service.IWfCopyService;
import com.ruoyi.workflow.service.IWfProcessService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
*
@ -51,7 +55,7 @@ public class WfProcessController extends BaseController {
}
/**
*
* :
*/
@SaCheckPermission("workflow:process:ownList")
@GetMapping(value = "/ownList")
@ -59,6 +63,23 @@ public class WfProcessController extends BaseController {
return processService.selectPageOwnProcessList(processQuery, pageQuery);
}
/**
* handbook
* zqjia:
*/
@SaCheckPermission("workflow:process:handbookList")
@GetMapping(value = "/handbookList")
public TableDataInfo<WfTaskVo> handbookList(ProcessQuery processQuery, PageQuery pageQuery) {
return processService.selectPageHandbookList(processQuery, pageQuery);
}
@SaCheckPermission("workflow:process:ownList")
@GetMapping(value = "/ownInfoList")
public TableDataInfo<WfTaskInfoVo> ownProcessInfoList(ProcessQuery processQuery, PageQuery pageQuery) {
return processService.selectPageOwnProcessInfoList(processQuery, pageQuery);
}
/**
*
*/
@ -183,9 +204,10 @@ public class WfProcessController extends BaseController {
*
* @param definitionId id
* @param deployId id
* @param procInsId
*/
@GetMapping("/getProcessForm")
@SaCheckPermission("workflow:process:start")
@GetMapping("/getProcessForm")
public R<?> getForm(@RequestParam(value = "definitionId") String definitionId,
@RequestParam(value = "deployId") String deployId,
@RequestParam(value = "procInsId", required = false) String procInsId) {
@ -203,7 +225,6 @@ public class WfProcessController extends BaseController {
public R<Void> start(@PathVariable(value = "processDefId") String processDefId, @RequestBody Map<String, Object> variables) {
processService.startProcessByDefId(processDefId, variables);
return R.ok("流程启动成功");
}
/**
@ -236,4 +257,15 @@ public class WfProcessController extends BaseController {
public R detail(String procInsId, String taskId) {
return R.ok(processService.queryProcessDetail(procInsId, taskId));
}
@PostMapping("/details")
public TableDataInfo<WfDetailVo> details(@RequestBody List<String> procInsIds) {
List<WfDetailVo> processDetails = new ArrayList<>();
for (int i = 0; i < procInsIds.size(); i++) {
String procInsId = procInsIds.get(i);
WfDetailVo detailVo = processService.queryProcessDetail(procInsId, null);
processDetails.add(detailVo);
}
return TableDataInfo.build(processDetails);
}
}

View File

@ -44,6 +44,16 @@ public class PageQuery implements Serializable {
*/
private String isAsc;
/**
*
*/
private String detailTitleName;
/**
*
*/
private String detailDirectorName;
/**
*
*/

View File

@ -22,5 +22,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
SELECT * FROM test_demo ${ew.customSqlSegment}
</select>
</mapper>

View File

@ -59,7 +59,7 @@ public class FormConf {
*/
private Boolean formBtns = true;
/**
*
* , fieldslist
*/
private List<Map<String, Object>> fields;
}

View File

@ -8,7 +8,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* flowable
* flowable ,
* @author XuanXuan
* @date 2021-04-03
*/

View File

@ -0,0 +1,108 @@
package com.ruoyi.project.controller;
import java.util.List;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.core.validate.QueryGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.project.domain.vo.ProjectApplicationVo;
import com.ruoyi.project.domain.bo.ProjectApplicationBo;
import com.ruoyi.project.service.IProjectApplicationService;
import com.ruoyi.common.core.page.TableDataInfo;
/**
*
*
* @author ruoyi
* @date 2024-06-14
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/project/application")
public class ProjectApplicationController extends BaseController {
private final IProjectApplicationService iProjectApplicationService;
/**
*
*/
@SaCheckPermission("project:application:list")
@GetMapping("/list")
public TableDataInfo<ProjectApplicationVo> list(ProjectApplicationBo bo, PageQuery pageQuery) {
return iProjectApplicationService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("project:application:export")
@Log(title = "项目申报", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ProjectApplicationBo bo, HttpServletResponse response) {
List<ProjectApplicationVo> list = iProjectApplicationService.queryList(bo);
ExcelUtil.exportExcel(list, "项目申报", ProjectApplicationVo.class, response);
}
/**
*
*
* @param projectId
*/
@SaCheckPermission("project:application:query")
@GetMapping("/{projectId}")
public R<ProjectApplicationVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long projectId) {
return R.ok(iProjectApplicationService.queryById(projectId));
}
/**
*
*/
@SaCheckPermission("project:application:add")
@Log(title = "项目申报", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ProjectApplicationBo bo) {
return toAjax(iProjectApplicationService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("project:application:edit")
@Log(title = "项目申报", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ProjectApplicationBo bo) {
return toAjax(iProjectApplicationService.updateByBo(bo));
}
/**
*
*
* @param projectIds
*/
@SaCheckPermission("project:application:remove")
@Log(title = "项目申报", businessType = BusinessType.DELETE)
@DeleteMapping("/{projectIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] projectIds) {
return toAjax(iProjectApplicationService.deleteWithValidByIds(Arrays.asList(projectIds), true));
}
}

View File

@ -0,0 +1,61 @@
package com.ruoyi.project.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* project_application
*
* @author ruoyi
* @date 2024-06-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("project_application")
public class ProjectApplication extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* ID
*/
@TableId(value = "project_id")
private Long projectId;
/**
*
*/
private String projectName;
/**
* 0 1
*/
private String projectStatus;
/**
*
*/
private Date projectAppStTime;
/**
*
*/
private Date projectAppEndTime;
/**
*
*/
private String projectLeader;
/**
* ()
*/
private Long projectBudget;
/**
*
*/
private String projectLeaderPhone;
}

View File

@ -0,0 +1,76 @@
package com.ruoyi.project.domain.bo;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* project_application
*
* @author ruoyi
* @date 2024-06-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
/* 这个地方继承了BaseEntity, 实际可以认为就是包含了一个特定成员变量而已。*/
public class ProjectApplicationBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "项目ID不能为空", groups = { EditGroup.class })
private Long projectId;
/**
*
*/
@NotBlank(message = "项目名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String projectName;
/**
* 0 1
*/
@NotBlank(message = "状态0正常 1停用不能为空", groups = { AddGroup.class, EditGroup.class })
private String projectStatus;
/**
*
*/
@NotNull(message = "申报开始日期不能为空", groups = { AddGroup.class, EditGroup.class })
private Date projectAppStTime;
/**
*
*/
@NotNull(message = "申报结束日期不能为空", groups = { AddGroup.class, EditGroup.class })
private Date projectAppEndTime;
/**
*
*/
@NotBlank(message = "项目负责人不能为空", groups = { AddGroup.class, EditGroup.class })
private String projectLeader;
/**
* ()
*/
@NotNull(message = "项目预算(万)不能为空", groups = { AddGroup.class, EditGroup.class })
private Long projectBudget;
/**
*
*/
@NotBlank(message = "项目负责人联系电话不能为空", groups = { AddGroup.class, EditGroup.class })
private String projectLeaderPhone;
}

View File

@ -0,0 +1,76 @@
package com.ruoyi.project.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import lombok.Data;
import java.util.Date;
/**
* project_application
*
* @author ruoyi
* @date 2024-06-14
*/
@Data
@ExcelIgnoreUnannotated
public class ProjectApplicationVo {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "项目名称")
private String projectName;
/**
* 0 1
*/
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0=正常,1=停用")
private String projectStatus;
/**
*
*/
@ExcelProperty(value = "申报开始日期")
private Date projectAppStTime;
/**
*
*/
@ExcelProperty(value = "申报结束日期")
private Date projectAppEndTime;
/**
*
*/
@ExcelProperty(value = "项目负责人")
private String projectLeader;
/**
* ()
*/
@ExcelProperty(value = "项目预算(万)")
private Long projectBudget;
/**
*
*/
@ExcelProperty(value = "项目负责人联系电话")
private String projectLeaderPhone;
}

View File

@ -0,0 +1,15 @@
package com.ruoyi.project.mapper;
import com.ruoyi.project.domain.ProjectApplication;
import com.ruoyi.project.domain.vo.ProjectApplicationVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author ruoyi
* @date 2024-06-14
*/
public interface ProjectApplicationMapper extends BaseMapperPlus<ProjectApplicationMapper, ProjectApplication, ProjectApplicationVo> {
}

View File

@ -0,0 +1,49 @@
package com.ruoyi.project.service;
import com.ruoyi.project.domain.ProjectApplication;
import com.ruoyi.project.domain.vo.ProjectApplicationVo;
import com.ruoyi.project.domain.bo.ProjectApplicationBo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* Service
*
* @author ruoyi
* @date 2024-06-14
*/
public interface IProjectApplicationService {
/**
*
*/
ProjectApplicationVo queryById(Long projectId);
/**
*
*/
TableDataInfo<ProjectApplicationVo> queryPageList(ProjectApplicationBo bo, PageQuery pageQuery);
/**
*
*/
List<ProjectApplicationVo> queryList(ProjectApplicationBo bo);
/**
*
*/
Boolean insertByBo(ProjectApplicationBo bo);
/**
*
*/
Boolean updateByBo(ProjectApplicationBo bo);
/**
*
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@ -0,0 +1,115 @@
package com.ruoyi.project.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.project.domain.bo.ProjectApplicationBo;
import com.ruoyi.project.domain.vo.ProjectApplicationVo;
import com.ruoyi.project.domain.ProjectApplication;
import com.ruoyi.project.mapper.ProjectApplicationMapper;
import com.ruoyi.project.service.IProjectApplicationService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* Service
*
* @author ruoyi
* @date 2024-06-14
*/
@RequiredArgsConstructor
@Service
public class ProjectApplicationServiceImpl implements IProjectApplicationService {
private final ProjectApplicationMapper baseMapper;
/**
*
*/
@Override
public ProjectApplicationVo queryById(Long projectId){
return baseMapper.selectVoById(projectId);
}
/**
*
*/
@Override
public TableDataInfo<ProjectApplicationVo> queryPageList(ProjectApplicationBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ProjectApplication> lqw = buildQueryWrapper(bo);
Page<ProjectApplicationVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*/
@Override
public List<ProjectApplicationVo> queryList(ProjectApplicationBo bo) {
LambdaQueryWrapper<ProjectApplication> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ProjectApplication> buildQueryWrapper(ProjectApplicationBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<ProjectApplication> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getProjectName()), ProjectApplication::getProjectName, bo.getProjectName());
lqw.eq(StringUtils.isNotBlank(bo.getProjectStatus()), ProjectApplication::getProjectStatus, bo.getProjectStatus());
lqw.eq(bo.getProjectAppStTime() != null, ProjectApplication::getProjectAppStTime, bo.getProjectAppStTime());
lqw.eq(bo.getProjectAppEndTime() != null, ProjectApplication::getProjectAppEndTime, bo.getProjectAppEndTime());
lqw.eq(StringUtils.isNotBlank(bo.getProjectLeader()), ProjectApplication::getProjectLeader, bo.getProjectLeader());
lqw.eq(bo.getProjectBudget() != null, ProjectApplication::getProjectBudget, bo.getProjectBudget());
lqw.eq(StringUtils.isNotBlank(bo.getProjectLeaderPhone()), ProjectApplication::getProjectLeaderPhone, bo.getProjectLeaderPhone());
return lqw;
}
/**
*
*/
@Override
public Boolean insertByBo(ProjectApplicationBo bo) {
ProjectApplication add = BeanUtil.toBean(bo, ProjectApplication.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setProjectId(add.getProjectId());
}
return flag;
}
/**
*
*/
@Override
public Boolean updateByBo(ProjectApplicationBo bo) {
ProjectApplication update = BeanUtil.toBean(bo, ProjectApplication.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
*
*/
private void validEntityBeforeSave(ProjectApplication entity){
//TODO 做一些数据校验,如唯一约束
}
/**
*
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@ -26,7 +26,7 @@ public class WfDetailVo {
private List<WfProcNodeVo> historyProcNodeList;
/**
*
* ,
*/
private List<FormConf> processFormList;
@ -37,6 +37,11 @@ public class WfDetailVo {
private WfViewerVo flowViewer;
/**
* zqjia: ID
*/
private String procInsId;
/**
*
* @return true:false:

View File

@ -0,0 +1,31 @@
package com.ruoyi.workflow.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.workflow.domain.dto.WfCommentDto;
import lombok.Data;
import org.flowable.engine.task.Comment;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
*
*
* @author logzhan
* @createTime 2022/3/10 00:12
*/
@Data
@ExcelIgnoreUnannotated
public class WfTaskInfoVo extends WfTaskVo {
/**
*
*/
private String processTitle;
/**
*
*/
private String director;
}

View File

@ -6,6 +6,7 @@ import com.ruoyi.flowable.core.FormConf;
import com.ruoyi.flowable.core.domain.ProcessQuery;
import com.ruoyi.workflow.domain.vo.WfDefinitionVo;
import com.ruoyi.workflow.domain.vo.WfDetailVo;
import com.ruoyi.workflow.domain.vo.WfTaskInfoVo;
import com.ruoyi.workflow.domain.vo.WfTaskVo;
import java.util.List;
@ -35,6 +36,12 @@ public interface IWfProcessService {
*/
TableDataInfo<WfTaskVo> selectPageOwnProcessList(ProcessQuery processQuery, PageQuery pageQuery);
/**
*
* @param pageQuery
*/
TableDataInfo<WfTaskVo> selectPageHandbookList(ProcessQuery processQuery, PageQuery pageQuery);
/**
*
*/
@ -113,4 +120,7 @@ public interface IWfProcessService {
* @param taskId ID
*/
WfDetailVo queryProcessDetail(String procInsId, String taskId);
TableDataInfo<WfTaskInfoVo> selectPageOwnProcessInfoList(ProcessQuery processQuery, PageQuery pageQuery);
}

View File

@ -198,13 +198,22 @@ public class WfModelServiceImpl extends FlowServiceFactory implements IWfModelSe
return StrUtil.utf8Str(bpmnBytes);
}
/**
* repositoryServiceWfModel
*
*/
@Override
public void insertModel(WfModelBo modelBo) {
Model model = repositoryService.newModel();
model.setName(modelBo.getModelName());
model.setKey(modelBo.getModelKey());
// 这里只是设置一个字符串(分类信息)
model.setCategory(modelBo.getCategory());
// 这个地方非常关键, 这里把WorkFlow的一些额外信息转换为Json
// 后续能否扩展一些信息非常依靠这个metaInfo
// 值得注意的是这里的WfMetaInfoDto是新构建的说明是空的, 用于后续的改进扩展东西
String metaInfo = buildMetaInfo(new WfMetaInfoDto(), modelBo.getDescription());
// workflow库模型保存扩展元信息
model.setMetaInfo(metaInfo);
// 保存流程模型
repositoryService.saveModel(model);
@ -354,6 +363,7 @@ public class WfModelServiceImpl extends FlowServiceFactory implements IWfModelSe
if (StringUtils.isNotEmpty(metaInfo.getCreateUser())) {
metaInfo.setCreateUser(LoginHelper.getUsername());
}
// 把结构体转成字符串保存
return JsonUtils.toJsonString(metaInfo);
}
}

View File

@ -37,6 +37,7 @@ import com.ruoyi.workflow.domain.vo.*;
import com.ruoyi.workflow.mapper.WfDeployFormMapper;
import com.ruoyi.workflow.service.IWfProcessService;
import com.ruoyi.workflow.service.IWfTaskService;
import liquibase.pro.packaged.W;
import lombok.RequiredArgsConstructor;
import org.flowable.bpmn.constants.BpmnXMLConstants;
import org.flowable.bpmn.model.Process;
@ -153,12 +154,79 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
}
return definitionVoList;
}
/**
*
* @author : zhanli
*/
@Override
public TableDataInfo<WfTaskVo> selectPageOwnProcessList(ProcessQuery processQuery, PageQuery pageQuery) {
Page<WfTaskVo> page = new Page<>();
// 创建历史信息查询对象
// 利用流程历史服务查询信息
HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
.startedBy(TaskUtils.getUserId()) // 数据必须是指定用户信息开头的
.orderByProcessInstanceStartTime() // 按照流程实例开始的时间排序
.desc();
// 构建搜索条件
ProcessUtils.buildProcessSearch(historicProcessInstanceQuery, processQuery);
int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1);
// 按照给定的页面的信息进行数据的过滤
List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery
.listPage(offset, pageQuery.getPageSize());
// historicProcessInstances是返回信息的合集,一共3条项目, 对应我的流程(ownProcessList)
page.setTotal(historicProcessInstanceQuery.count());
List<WfTaskVo> taskVoList = new ArrayList<>();
for (HistoricProcessInstance hisIns : historicProcessInstances) {
WfTaskVo taskVo = new WfTaskVo();
// 获取流程状态
HistoricVariableInstance processStatusVariable = historyService.createHistoricVariableInstanceQuery()
.processInstanceId(hisIns.getId())
.variableName(ProcessConstants.PROCESS_STATUS_KEY)
.singleResult();
String processStatus = null;
if (ObjectUtil.isNotNull(processStatusVariable)) {
processStatus = Convert.toStr(processStatusVariable.getValue());
}
// 兼容旧流程
if (processStatus == null) {
processStatus = ObjectUtil.isNull(hisIns.getEndTime()) ? ProcessStatus.RUNNING.getStatus() : ProcessStatus.COMPLETED.getStatus();
}
taskVo.setProcessStatus(processStatus);
taskVo.setCreateTime(hisIns.getStartTime());
taskVo.setFinishTime(hisIns.getEndTime());
taskVo.setProcInsId(hisIns.getId());
// 计算耗时
if (Objects.nonNull(hisIns.getEndTime())) {
taskVo.setDuration(DateUtils.getDatePoor(hisIns.getEndTime(), hisIns.getStartTime()));
} else {
taskVo.setDuration(DateUtils.getDatePoor(DateUtils.getNowDate(), hisIns.getStartTime()));
}
// 流程部署实例信息
Deployment deployment = repositoryService.createDeploymentQuery()
.deploymentId(hisIns.getDeploymentId()).singleResult();
taskVo.setDeployId(hisIns.getDeploymentId());
taskVo.setProcDefId(hisIns.getProcessDefinitionId());
taskVo.setProcDefName(hisIns.getProcessDefinitionName());
taskVo.setProcDefVersion(hisIns.getProcessDefinitionVersion());
taskVo.setCategory(deployment.getCategory());
// 当前所处流程
List<Task> taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).includeIdentityLinks().list();
if (CollUtil.isNotEmpty(taskList)) {
taskVo.setTaskName(taskList.stream().map(Task::getName).filter(StringUtils::isNotEmpty).collect(Collectors.joining(",")));
}
taskVoList.add(taskVo);
}
page.setRecords(taskVoList);
return TableDataInfo.build(page);
}
public TableDataInfo<WfTaskVo> selectPageHandbookList(ProcessQuery processQuery, PageQuery pageQuery) {
Page<WfTaskVo> page = new Page<>();
HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
.startedBy(TaskUtils.getUserId())
.orderByProcessInstanceStartTime()
.desc();
// 构建搜索条件
@ -183,6 +251,10 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
if (processStatus == null) {
processStatus = ObjectUtil.isNull(hisIns.getEndTime()) ? ProcessStatus.RUNNING.getStatus() : ProcessStatus.COMPLETED.getStatus();
}
// zqjia:只返回完成的指南
if (!"completed".equals(processStatus)) {
continue;
}
taskVo.setProcessStatus(processStatus);
taskVo.setCreateTime(hisIns.getStartTime());
taskVo.setFinishTime(hisIns.getEndTime());
@ -643,36 +715,46 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
*
* @param procInsId ID
* @param taskId ID
* @return
* @return WfDetailVo
*/
@Override
public WfDetailVo queryProcessDetail(String procInsId, String taskId) {
WfDetailVo detailVo = new WfDetailVo();
// 获取流程实例
// historyService这个服务非常的关键
HistoricProcessInstance historicProcIns = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(procInsId)
.includeProcessVariables()
.singleResult();
// 判断taskID是否为空
if (StringUtils.isNotBlank(taskId)) {
// 创建历史信息查询
HistoricTaskInstance taskIns = historyService.createHistoricTaskInstanceQuery()
.taskId(taskId)
.includeIdentityLinks()
.includeProcessVariables()
.includeTaskLocalVariables()
.singleResult();
// 如果查询的信息为null
if (taskIns == null) {
throw new ServiceException("没有可办理的任务!");
}
detailVo.setTaskFormData(currTaskFormData(historicProcIns.getDeploymentId(), taskIns));
}
// 获取Bpmn模型信息
InputStream inputStream = repositoryService.getProcessModel(historicProcIns.getProcessDefinitionId());
String bpmnXmlStr = StrUtil.utf8Str(IoUtil.readBytes(inputStream, false));
BpmnModel bpmnModel = ModelUtils.getBpmnModel(bpmnXmlStr);
// 把BpmXml信息存放到detailVo中
detailVo.setBpmnXml(bpmnXmlStr);
// 下面的是干什么的?
detailVo.setHistoryProcNodeList(historyProcNodeList(historicProcIns));
// /* 设置流程表单列表, 这个地方的信息非常的关键,核心的标题的各种信息都传递在这里 */
detailVo.setProcessFormList(processFormList(bpmnModel, historicProcIns));
// 设置流观察器
detailVo.setFlowViewer(getFlowViewer(bpmnModel, procInsId));
detailVo.setProcInsId(procInsId);
return detailVo;
}
@ -981,4 +1063,100 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
Set<String> rejectedSet = FlowableUtils.dfsFindRejects(bpmnModel, unfinishedTaskSet, finishedSequenceFlowSet, finishedTaskSet);
return new WfViewerVo(finishedTaskSet, finishedSequenceFlowSet, unfinishedTaskSet, rejectedSet);
}
@SuppressWarnings("unchecked")
public TableDataInfo<WfTaskInfoVo> selectPageOwnProcessInfoList(ProcessQuery processQuery, PageQuery pageQuery) {
TableDataInfo<WfTaskVo> t = selectPageOwnProcessList(processQuery, pageQuery);
List<WfTaskInfoVo> targetList = new ArrayList<>();
// 获取 rows 列表
List<WfTaskVo> taskList = t.getRows();
// 使用增强 for 循环遍历列表
for (WfTaskVo task : taskList) {
WfTaskInfoVo taskVo = new WfTaskInfoVo();
// 获取流程状态
HistoricVariableInstance processStatusVariable = historyService.createHistoricVariableInstanceQuery()
.processInstanceId(task.getProcInsId())
.variableName(ProcessConstants.PROCESS_STATUS_KEY)
.singleResult();
String processStatus = null;
if (ObjectUtil.isNotNull(processStatusVariable)) {
processStatus = Convert.toStr(processStatusVariable.getValue());
}
// 兼容旧流程
if (processStatus == null) {
processStatus = ObjectUtil.isNull(task.getFinishTime()) ?
ProcessStatus.RUNNING.getStatus() : ProcessStatus.COMPLETED.getStatus();
}
taskVo.setProcessStatus(processStatus);
taskVo.setCreateTime(task.getCreateTime());
taskVo.setFinishTime(task.getFinishTime());
taskVo.setProcInsId(task.getProcInsId());
taskVo.setDuration(task.getDuration());
taskVo.setDeployId(task.getDeployId());
taskVo.setProcDefId(task.getProcDefId());
taskVo.setProcDefName(task.getProcDefName());
taskVo.setProcDefVersion(task.getProcDefVersion());
taskVo.setCategory(task.getCategory());
taskVo.setTaskName(task.getTaskName());
// 在这里处理每个 task 对象
WfDetailVo detailVo = queryProcessDetail(task.getProcInsId(), "");
// 获取表单列表
List<FormConf> processFormList = detailVo.getProcessFormList();
// 获取项目名字
if(pageQuery.getDetailTitleName() != null){
String res = getFormData(processFormList, pageQuery.getDetailTitleName(), pageQuery);
taskVo.setProcessTitle(res);
}
// 获取项目负责人名字
if(pageQuery.getDetailDirectorName() != null){
String director = getFormData(processFormList, pageQuery.getDetailDirectorName(), pageQuery);
taskVo.setDirector(director);
}
targetList.add(taskVo);
}
TableDataInfo<WfTaskInfoVo> target = new TableDataInfo<>();
target.setRows(targetList);
target.setTotal(t.getTotal());
target.setCode(t.getCode());
target.setMsg(t.getMsg());
return target;
}
@SuppressWarnings("unchecked")
private String getFormData(List<FormConf> processFormList, String fieldsName, PageQuery pageQuery){
String title;
// 使用增强 for 循环遍历列表
for (FormConf form : processFormList) {
for (Map<String, Object> map : form.getFields()) {
// 检查当前 map 是否包含指定的 key
if (!map.containsKey("__config__") || !map.containsKey("__vModel__")) {
continue;
}
// 判断字段名和请求的请求的字段名是否相同
String name = (String)map.get("__vModel__");
if(!fieldsName.equals(name)){
continue;
}
// 获取指定 key 的值
Object value = map.get("__config__");
if (value instanceof HashMap) {
HashMap<String, Object> innerMap = (HashMap<String, Object>)value;
if(pageQuery.getDetailTitleName() != null && innerMap.containsKey("defaultValue")){
title = (String) innerMap.get("defaultValue");
return title;
}
}
}
}
return "";
}
}

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.project.mapper.ProjectApplicationMapper">
<resultMap type="com.ruoyi.project.domain.ProjectApplication" id="ProjectApplicationResult">
<result property="projectId" column="project_id"/>
<result property="projectName" column="project_name"/>
<result property="projectStatus" column="project_status"/>
<result property="projectAppStTime" column="project_app_st_time"/>
<result property="projectAppEndTime" column="project_app_end_time"/>
<result property="projectLeader" column="project_leader"/>
<result property="projectBudget" column="project_budget"/>
<result property="projectLeaderPhone" column="project_leader_phone"/>
</resultMap>
</mapper>

View File

@ -5,8 +5,8 @@
"author": "KonBAI",
"license": "MIT",
"scripts": {
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"dev": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
"build": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
"preview": "node build/index.js --preview",
"lint": "eslint --ext .js,.vue src"
},

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询项目申报列表
export function listApplication(query) {
return request({
url: '/project/application/list',
method: 'get',
params: query
})
}
// 查询项目申报详细
export function getApplication(projectId) {
return request({
url: '/project/application/' + projectId,
method: 'get'
})
}
// 新增项目申报
export function addApplication(data) {
return request({
url: '/project/application',
method: 'post',
data: data
})
}
// 修改项目申报
export function updateApplication(data) {
return request({
url: '/project/application',
method: 'put',
data: data
})
}
// 删除项目申报
export function delApplication(projectId) {
return request({
url: '/project/application/' + projectId,
method: 'delete'
})
}

View File

@ -51,6 +51,23 @@ export function detailProcess(query) {
})
}
// 我的发起的流程
export function listOwnInfoProcess(query) {
return request({
url: '/workflow/process/ownInfoList',
method: 'get',
params: query
})
}
export function detailProcesses(arr) {
return request({
url: '/workflow/process/details',
method: 'post',
data: arr
})
}
// 我的发起的流程
export function listOwnProcess(query) {
return request({
@ -60,6 +77,14 @@ export function listOwnProcess(query) {
})
}
export function listHandbook(query) {
return request({
url: '/workflow/process/handbookList',
method: 'get',
params: query
})
}
// 我待办的流程
export function listTodoProcess(query) {
return request({

View File

@ -35,7 +35,7 @@ export default {
},
data() {
return {
title: '科研财务管理系统',
title: '科研财务管理系统',
logo: logoImg
}
}

View File

@ -12,6 +12,42 @@ export const formConf = {
formBtns: true
}
export const textComponents = [
{
// 组件的自定义配置
__config__: {
label: '文本显示',
labelWidth: null,
showLabel: false,
changeTag: true,
tag: 'el-input',
tagIcon: 'text',
defaultValue: undefined,
required: false,
layout: 'colFormItem',
span: 24,
document: 'https://element.eleme.cn/#/zh-CN/component/el-input',
// 正则校验规则
regList: [],
},
// 组件的插槽属性
__slot__: {
prepend: '',
append: ''
},
// 其余的为可直接写在组件标签上的属性
style: {width: '100%'},
placeholder: '请输入要显示的字符然后打开只读属性',
clearable: false,
'prefix-icon': '',
'suffix-icon': '',
maxlength: null,
'show-word-limit': false,
readonly: false,
disabled: false
}
]
// 输入型组件 【左面板】
export const inputComponents = [
{

View File

@ -26,6 +26,17 @@ const layouts = {
let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null
if (config.showLabel === false) labelWidth = '0'
if(config.tagIcon === 'text') {
return (
<el-col span={config.span}>
<el-form-item class="text" label-width={labelWidth} prop={scheme.__vModel__}
label={config.showLabel ? config.label : ''}>
<render conf={scheme} on={listeners} />
</el-form-item>
</el-col>
)
}
else {
return (
<el-col span={config.span}>
<el-form-item label-width={labelWidth} prop={scheme.__vModel__}
@ -34,6 +45,7 @@ const layouts = {
</el-form-item>
</el-col>
)
}
},
rowFormItem(h, scheme) {
let child = renderChildren.apply(this, arguments)
@ -87,7 +99,6 @@ function renderFormItem(h, elementList) {
return elementList.map(scheme => {
const config = scheme.__config__
const layout = layouts[config.layout]
if (layout) {
return layout.call(this, h, scheme)
}

View File

@ -0,0 +1,395 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="项目名称" prop="projectName">
<el-input
v-model="queryParams.projectName"
placeholder="请输入项目名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="projectStatus">
<el-input
v-model="queryParams.projectStatus"
placeholder="请输入状态"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="申报开始日期" prop="projectAppStTime" label-width="140px">
<el-date-picker clearable
v-model="queryParams.projectAppStTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择申报开始日期">
</el-date-picker>
</el-form-item>
<el-form-item label="申报结束日期" prop="projectAppEndTime" label-width="140px">
<el-date-picker clearable
v-model="queryParams.projectAppEndTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择申报结束日期">
</el-date-picker>
</el-form-item>
<el-form-item label="项目负责人" prop="projectLeader" label-width="140px">
<el-input
v-model="queryParams.projectLeader"
placeholder="请输入项目负责人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="项目预算(万)" prop="projectBudget" label-width="100px">
<el-input
v-model="queryParams.projectBudget"
placeholder="请输入项目预算(万)"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="项目负责人联系电话" prop="projectLeaderPhone" label-width="140px">
<el-input
v-model="queryParams.projectLeaderPhone"
placeholder="请输入联系电话"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['project:application:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['project:application:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['project:application:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['project:application:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="applicationList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="项目ID" align="center" prop="projectId" v-if="true" width="180"/>
<el-table-column label="项目名称" align="center" prop="projectName" :min-width="280"/>
<el-table-column label="状态" align="center" prop="projectStatus" width="60"/>
<el-table-column label="申报开始日期" align="center" prop="projectAppStTime" :min-width="140" width="140">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.projectAppStTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="申报结束日期" align="center" prop="projectAppEndTime" width="140">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.projectAppEndTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="项目负责人" align="center" prop="projectLeader" width="100"/>
<el-table-column label="项目预算(万)" align="center" prop="projectBudget" :min-width="180" width="180"/>
<el-table-column label="项目负责人联系电话" align="center" prop="projectLeaderPhone" :min-width="220" width="220"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" :min-width="180" width="180">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['project:application:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['project:application:remove']"
>删除</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-video-play"
@click="handleUpdate(scope.row)"
v-hasPermi="['project:application:remove']"
>申报</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改项目申报对话框 -->
<el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="150px" >
<el-form-item label="项目名称" prop="projectName" >
<el-input v-model="form.projectName" placeholder="请输入项目名称" :style="{ width: '400px' }"/>
</el-form-item>
<el-form-item label="状态" prop="projectStatus" >
<el-input v-model="form.projectStatus" placeholder="请输入状态" :style="{ width: '50px' }"/>
</el-form-item>
<el-form-item label="申报开始日期" prop="projectAppStTime" >
<el-date-picker clearable
v-model="form.projectAppStTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择申报开始日期">
</el-date-picker>
</el-form-item>
<el-form-item label="申报结束日期" prop="projectAppEndTime">
<el-date-picker clearable
v-model="form.projectAppEndTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择申报结束日期">
</el-date-picker>
</el-form-item>
<el-form-item label="项目负责人" prop="projectLeader">
<el-input v-model="form.projectLeader" placeholder="请输入项目负责人" :style="{ width: '100px'}"/>
</el-form-item>
<el-form-item label="项目预算(万)" prop="projectBudget">
<el-input v-model="form.projectBudget" placeholder="请输入项目预算(万)" :style="{ width: '100px'}"/>
</el-form-item>
<el-form-item label="项目负责人电话" prop="projectLeaderPhone">
<el-input v-model="form.projectLeaderPhone" placeholder="请输入项目负责人联系电话" :style="{ width: '140px'}" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listApplication, getApplication, delApplication, addApplication, updateApplication } from "@/api/project/application";
export default {
name: "Application",
data() {
return {
// loading
buttonLoading: false,
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
applicationList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
projectName: undefined,
projectStatus: undefined,
projectAppStTime: undefined,
projectAppEndTime: undefined,
projectLeader: undefined,
projectBudget: undefined,
projectLeaderPhone: undefined
},
//
form: {},
//
rules: {
projectId: [
{ required: true, message: "项目ID不能为空", trigger: "blur" }
],
projectName: [
{ required: true, message: "项目名称不能为空", trigger: "blur" }
],
projectStatus: [
{ required: true, message: "状态不能为空", trigger: "blur" }
],
projectAppStTime: [
{ required: true, message: "申报开始日期不能为空", trigger: "blur" }
],
projectAppEndTime: [
{ required: true, message: "申报结束日期不能为空", trigger: "blur" }
],
projectLeader: [
{ required: true, message: "项目负责人不能为空", trigger: "blur" }
],
projectBudget: [
{ required: true, message: "项目预算(万)不能为空", trigger: "blur" }
],
projectLeaderPhone: [
{ required: true, message: "项目负责人联系电话不能为空", trigger: "blur" }
]
}
};
},
created() {
this.getList();
},
methods: {
/** 查询项目申报列表 */
getList() {
this.loading = true;
listApplication(this.queryParams).then(response => {
this.applicationList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
projectId: undefined,
projectName: undefined,
projectStatus: undefined,
projectAppStTime: undefined,
projectAppEndTime: undefined,
projectLeader: undefined,
projectBudget: undefined,
projectLeaderPhone: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.projectId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加项目申报";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const projectId = row.projectId || this.ids
getApplication(projectId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改项目申报";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.projectId != null) {
updateApplication(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addApplication(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const projectIds = row.projectId || this.ids;
this.$modal.confirm('是否确认删除项目申报编号为"' + projectIds + '"的数据项?').then(() => {
this.loading = true;
return delApplication(projectIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('project/application/export', {
...this.queryParams
}, `application_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -0,0 +1,117 @@
<template>
<div class="app-container">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>{{ processName }}</span>
</div>
<el-col :span="18" :offset="3">
<div class="form-conf" v-if="formOpen">
<parser :key="new Date().getTime()" :form-conf="formData" @submit="submit" ref="parser" @getData="getData"/>
</div>
</el-col>
</el-card>
</div>
</template>
<script>
import { listProcess} from "@/api/workflow/process";
import { listAllCategory } from '@/api/workflow/category'
import { getProcessForm, startProcess } from '@/api/workflow/process'
import Parser from '@/utils/generator/parser'
export default {
name: 'handbookApply',
components: {
Parser
},
data() {
return {
definitionId: null,
deployId: null,
procInsId: null,
formOpen: false,
formData: {},
processName: '',
categoryOptions: [],
//
processParams: null,
//
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: "项目指南录入",
category: "007"
},
}
},
created() {
this.initData();
},
methods: {
initData() {
/** 查询流程定义列表 */
listProcess(this.queryParams).then(response => {
this.processParams = response.rows[0];
this.processName = this.processParams.processName;
this.definitionId = this.processParams.definitionId;
getProcessForm({
definitionId: this.processParams.definitionId,
deployId: this.processParams.deploymentId,
procInsId: undefined
}).then(res => {
if (res.data) {
this.formData = res.data;
this.formOpen = true
}
})
})
},
/** 接收子组件传的值 */
getData(data) {
if (data) {
const variables = [];
data.fields.forEach(item => {
let variableData = {};
variableData.label = item.__config__.label
//
if (item.__config__.defaultValue instanceof Array) {
const array = [];
item.__config__.defaultValue.forEach(val => {
array.push(val)
})
variableData.val = array;
} else {
variableData.val = item.__config__.defaultValue
}
variables.push(variableData)
})
this.variables = variables;
}
},
submit(data) {
if (data && this.definitionId) {
//
startProcess(this.definitionId, JSON.stringify(data.valData)).then(res => {
this.$modal.msgSuccess(res.msg);
this.$tab.closeOpenPage({
path: '/work/own'
})
})
}
}
}
}
</script>
<style lang="scss" scoped>
.form-conf {
margin: 15px auto;
width: 80%;
padding: 15px;
}
</style>

View File

@ -0,0 +1,117 @@
<template>
<div class="app-container">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>{{ processName }}</span>
</div>
<el-col :span="18" :offset="3">
<div class="form-conf" v-if="formOpen">
<parser :key="new Date().getTime()" :form-conf="formData" @submit="submit" ref="parser" @getData="getData"/>
</div>
</el-col>
</el-card>
</div>
</template>
<script>
import { listProcess} from "@/api/workflow/process";
import { listAllCategory } from '@/api/workflow/category'
import { getProcessForm, startProcess } from '@/api/workflow/process'
import Parser from '@/utils/generator/parser'
export default {
name: 'WorkStart',
components: {
Parser
},
data() {
return {
definitionId: null,
deployId: null,
procInsId: null,
formOpen: false,
formData: {},
processName: '',
categoryOptions: [],
//
processParams: null,
//
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: "项目指南录入",
category: "007"
},
}
},
created() {
this.initData();
},
methods: {
initData() {
/** 查询流程定义列表 */
listProcess(this.queryParams).then(response => {
this.processParams = response.rows[0];
this.processName = this.processParams.processName;
this.definitionId = this.processParams.definitionId;
getProcessForm({
definitionId: this.processParams.definitionId,
deployId: this.processParams.deploymentId,
procInsId: undefined
}).then(res => {
if (res.data) {
this.formData = res.data;
this.formOpen = true
}
})
})
},
/** 接收子组件传的值 */
getData(data) {
if (data) {
const variables = [];
data.fields.forEach(item => {
let variableData = {};
variableData.label = item.__config__.label
//
if (item.__config__.defaultValue instanceof Array) {
const array = [];
item.__config__.defaultValue.forEach(val => {
array.push(val)
})
variableData.val = array;
} else {
variableData.val = item.__config__.defaultValue
}
variables.push(variableData)
})
this.variables = variables;
}
},
submit(data) {
if (data && this.definitionId) {
//
startProcess(this.definitionId, JSON.stringify(data.valData)).then(res => {
this.$modal.msgSuccess(res.msg);
this.$tab.closeOpenPage({
path: '/work/own'
})
})
}
}
}
}
</script>
<style lang="scss" scoped>
.form-conf {
margin: 15px auto;
width: 80%;
padding: 15px;
}
</style>

View File

@ -0,0 +1,412 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="流程标识" prop="processKey">
<el-input
v-model="queryParams.processKey"
placeholder="请输入流程标识"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="processName">
<el-input
v-model="queryParams.processName"
placeholder="请输入流程名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-select v-model="queryParams.category" clearable placeholder="请选择" size="small">
<el-option
v-for="item in categoryOptions"
:key="item.categoryId"
:label="item.categoryName"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="提交时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
v-hasPermi="['workflow:process:ownExport']"
@click="handleExport"
>导出</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="showList" @selection-change="handleSelectionChange">
<el-table-column label="指南名称" align="center">
<template slot-scope="scope">
{{ scope.row.handbookname }}
</template>
</el-table-column>
<el-table-column label="指南类别" align="center">
<template slot-scope="scope">
{{ scope.row.handbookclass }}
</template>
</el-table-column>
<el-table-column label="指南级别" align="center">
<template slot-scope="scope">
{{ scope.row.handbooklevel }}
</template>
</el-table-column>
<el-table-column label="截至日期" align="center">
<template slot-scope="scope">
{{ scope.row.handbookdate }}
</template>
</el-table-column>
<el-table-column label="指南文件" align="center">
<template slot-scope="scope">
<el-button class="file" @click="handbookDownload(scope.row.handbookfile)"></el-button>
</template>
</el-table-column>
<el-table-column label="项目申报" align="center">
<template slot-scope="scope">
<el-button class="file" @click="projectApply(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import {
stopProcess,
delProcess,
listHandbook,
detailProcess,
detailProcesses,
listProcess
} from '@/api/workflow/process';
import { listAllCategory } from '@/api/workflow/category';
import Parser from '@/utils/generator/parser'
import {getToken} from "@/utils/auth";
// import {deepClone} from "@/utils";
export default {
name: "handbookQuery",
dicts: ['wf_process_status'],
components: {
Parser,
},
data() {
return {
//
loading: true,
processLoading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
categoryOptions: [],
processTotal:0,
//
title: "",
//
open: false,
src: "",
definitionList:[],
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: undefined,
category: "007"
},
//
form: {},
//
rules: {
},
//
handbookList: [],
//
showList: [],
};
},
async created() {
await this.getList();
await this.getProcessDetails();
},
methods: {
//
handbookDownload(handbookfile) {
handbookfile.forEach( file => {
if(file.response.code === 200 && file.ossId) {
this.$download.oss(file.ossId);
}
})
},
projectApply(row) {
let queryParams = {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: "项目申报",
category: "002"
};
//
listProcess(queryParams).then(response => {
const apply = response.rows[0];
if(apply) {
this.$router.push({
path: '/workflow/process/start/' + apply.deploymentId,
query: {
definitionId: apply.definitionId,
processName: apply.processName,
}
})
}
});
},
/** 查询流程定义列表 */
getList() {
// zqjia:仿parser.js
return new Promise((resolve,reject)=>{
this.showList = [];
this.loading = true;
listHandbook(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.handbookList = response.rows;
this.total = response.total;
this.loading = false;
resolve();
});
})
},
//
getProcessDetails() {
return new Promise((resolve, reject)=>{
let pId = [];
let tId = [];
this.handbookList.forEach(handbook => {
pId.push(handbook.procInsId);
tId.push(undefined);
})
const params = {procInsIds: pId};
detailProcesses(pId).then(res => {
res.rows.forEach(row => {
let processForm = row.processFormList[0];
let formData = [];
this.initFormData(processForm.fields, formData);
formData["procDefId"] = row.procInsId;
this.showList.push(formData);
})
})
})
},
/** 查询流程分类列表 */
getCategoryList() {
listAllCategory().then(response => this.categoryOptions = response.data)
},
initFormData(componentList, formData) {
componentList.forEach(cur => {
this.buildOptionMethod(cur)
const config = cur.__config__;
if (cur.__vModel__) {
if(cur.__slot__ && 'options' in cur.__slot__) {
formData[cur.__vModel__] = cur.__slot__.options[config.defaultValue-1].label;
}
else {
formData[cur.__vModel__] = config.defaultValue;
}
}
if (config.children) {
this.initFormData(config.children, formData);
}
})
},
// Option
buildOptionMethod(scheme) {
const config = scheme.__config__;
if (config && config.tag === 'el-cascader') {
if (config.dataType === 'dynamic') {
this.$axios({
method: config.method,
url: config.url
}).then(resp => {
var { data } = resp
scheme[config.dataConsumer] = data[config.dataKey]
});
}
}
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
name: null,
category: null,
key: null,
tenantId: null,
deployTime: null,
derivedFrom: null,
derivedFromRoot: null,
parentDeploymentId: null,
engineVersion: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.procInsId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
handleAgain(row) {
this.$router.push({
path: '/workflow/process/start/' + row.deployId,
query: {
definitionId: row.procDefId,
procInsId: row.procInsId
}
})
},
/** 取消流程申请 */
handleStop(row){
const params = {
procInsId: row.procInsId
}
stopProcess(params).then( res => {
this.$modal.msgSuccess(res.msg);
this.getList();
});
},
/** 流程流转记录 */
handleFlowRecord(row) {
this.$router.push({
path: '/workflow/process/detail/' + row.procInsId,
query: {
processed: false
}
})
},
/** 删除按钮操作 */
handleDelete(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("删除成功");
})
},
/** 导出按钮操作 */
handleExport() {
this.download('workflow/process/ownExport', {
...this.queryParams
}, `wf_own_process_${new Date().getTime()}.xlsx`)
},
categoryFormat(row, column) {
return this.categoryOptions.find(k => k.code === row.category)?.categoryName ?? '';
}
}
};
</script>
<style scoped>
.file {
border: none;
background: none;
/* 取消其他默认样式 */
box-shadow: none;
padding: 0;
margin: 0;
}
.file:hover {
background: none; /* 去掉鼠标悬停时的背景 */
/* 如果需要可以添加其他hover效果 */
}
</style>

View File

@ -0,0 +1,472 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="流程标识" prop="processKey">
<el-input
v-model="queryParams.processKey"
placeholder="请输入流程标识"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="processName">
<el-input
v-model="queryParams.processName"
placeholder="请输入流程名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-select v-model="queryParams.category" clearable placeholder="请选择" size="small">
<el-option
v-for="item in categoryOptions"
:key="item.categoryId"
:label="item.categoryName"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="提交时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
v-hasPermi="['workflow:process:ownExport']"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- <el-table v-loading="loading" :data="handbookList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="流程编号" align="center" prop="procInsId" :show-overflow-tooltip="true"/>
<el-table-column label="指南名称" align="center" prop="procDefName" :show-overflow-tooltip="true"/>
<el-table-column label="流程类别" align="center" prop="category" :formatter="categoryFormat" />
<el-table-column label="流程版本" align="center" width="80px">
<template slot-scope="scope">
<el-tag size="medium" >v{{ scope.row.procDefVersion }}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前节点" align="center" prop="taskName"/>
<el-table-column label="提交时间" align="center" prop="createTime" width="180"/>
<el-table-column label="流程状态" align="center" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.wf_process_status" :value="scope.row.processStatus"/>
</template>
</el-table-column>
<el-table-column label="耗时" align="center" prop="duration" width="180"/>
<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-tickets"
@click="handleFlowRecord(scope.row)"
v-hasPermi="['workflow:process:query']"
>详情</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-if="scope.row.finishTime"
v-hasPermi="['workflow:process:remove']"
>删除</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-circle-close"
@click="handleStop(scope.row)"
v-hasPermi="['workflow:process:cancel']"
>取消</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-refresh-right"
v-hasPermi="['workflow:process:start']"
@click="handleAgain(scope.row)"
>重新发起</el-button>
</template>
</el-table-column>
</el-table> -->
<el-table v-loading="loading" :data="showList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" type="index" width="50"></el-table-column>
<!-- <el-table-column label="指南名称" align="center">
<template slot-scope="scope">
{{ scope.row[0] }}
</template>
</el-table-column> -->
<el-table-column label="指南名称" align="center" width="180px" :min-width="180">
<template slot-scope="scope">
<el-tag size="medium">{{ scope.row[0] }}</el-tag>
</template>
</el-table-column>
<el-table-column label="指南类别" align="center">
<template slot-scope="scope">
{{ scope.row[1] }}
</template>
</el-table-column>
<el-table-column label="指南级别" align="center">
<template slot-scope="scope">
{{ scope.row[2] }}
</template>
</el-table-column>
<el-table-column label="截至日期" align="center">
<template slot-scope="scope">
{{ scope.row[3] }}
</template>
</el-table-column>
<el-table-column label="指南文件" align="center">
<template slot-scope="scope">
<el-button class="file" @click="handbookDownload(scope.row[5])" style="color: #1890ff;">
<i class="el-icon-download"></i> {{ scope.row[4] }}
</el-button>
</template>
</el-table-column>
<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-tickets"
@click="handleFlowDetails(scope.row[5])"
v-hasPermi="['workflow:process:query']"
>详情</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-if="scope.row.finishTime"
v-hasPermi="['workflow:process:remove']"
>删除</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-circle-close"
@click="handleStop(scope.row)"
v-hasPermi="['workflow:process:cancel']"
>取消</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-refresh-right"
v-hasPermi="['workflow:process:start']"
@click="handleAgain(scope.row)"
>重新发起</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import {stopProcess, delProcess, listHandbook, detailProcess} from '@/api/workflow/process';
import { listAllCategory } from '@/api/workflow/category';
import Parser from '@/utils/generator/parser'
import {getToken} from "@/utils/auth";
// import {deepClone} from "@/utils";
export default {
name: "Own",
dicts: ['wf_process_status'],
components: {
Parser,
},
data() {
return {
//
loading: true,
processLoading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
categoryOptions: [],
processTotal:0,
//
handbookList: [],
//
title: "",
//
open: false,
src: "",
definitionList:[],
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: undefined,
category: "007"
},
//
form: {},
//
rules: {
},
processFormList: [], //
showList: [],
};
},
created() {
this.getCategoryList();
},
beforeRouteEnter(to, from, next) {
next(vm => {
vm.getList()
})
},
methods: {
//
handbookDownload(ossId) {
this.$download.oss(ossId)
},
//
getProcessDetails(procInsId, taskId) {
const params = {procInsId: procInsId, taskId: taskId}
detailProcess(params).then(res => {
const data = res.data;
const formList = data.processFormList;
formList.forEach(form => {
var dataShow = [];
const fields = form.fields;
// zqjia:fields
for (var i = 0; i < fields.length; i++) {
const tmp = fields[i];
const slot = tmp.__slot__;
const config = tmp.__config__;
if (i === 4 && config.defaultValue) {
tmp['file-list'] = config.defaultValue;
tmp['headers'] = {
Authorization: "Bearer " + getToken(),
}
// tmp['on-success'] = (res, file, fileList) => {
// if (res.code === 200 && fileList) {
// config.defaultValue = fileList;
// fileList.forEach(val =>{
// val.url = val.response.data.url;
// val.ossId = val.response.data.ossId;
// })
// }
// };
// zqjia:ossId
dataShow.push(config.defaultValue[0].name);
dataShow.push(config.defaultValue[0].ossId);
dataShow.push(procInsId);
}
else {
if (slot !== undefined && slot.options !== undefined) {
dataShow.push(slot.options[config.defaultValue - 1].label);
}
else {
dataShow.push(config.defaultValue);
}
}
}
this.showList.push(dataShow);
});
// zqjia:
this.processFormList.push(data.processFormList);
})
},
/** 查询流程分类列表 */
getCategoryList() {
listAllCategory().then(response => this.categoryOptions = response.data)
},
/** 查询流程定义列表 */
getList() {
this.loading = true;
listHandbook(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.handbookList = response.rows;
this.total = response.total;
this.loading = false;
this.handbookList.forEach(handbook => {
this.getProcessDetails(handbook.procInsId, undefined);
});
});
// console.log(this.showList);
console.log(this.processFormList);
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
name: null,
category: null,
key: null,
tenantId: null,
deployTime: null,
derivedFrom: null,
derivedFromRoot: null,
parentDeploymentId: null,
engineVersion: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.procInsId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
handleAgain(row) {
this.$router.push({
path: '/workflow/process/start/' + row.deployId,
query: {
definitionId: row.procDefId,
procInsId: row.procInsId
}
})
},
/** 取消流程申请 */
handleStop(row){
const params = {
procInsId: row.procInsId
}
stopProcess(params).then( res => {
this.$modal.msgSuccess(res.msg);
this.getList();
});
},
/** 流程流转记录 */
handleFlowRecord(row) {
this.$router.push({
path: '/workflow/process/detail/' + row.procInsId,
query: {
processed: false
}
})
},
handleFlowDetails(procInsId) {
this.$router.push({
path: '/workflow/process/detail/' + procInsId,
query: {
processed: false
}
})
},
/** 删除按钮操作 */
handleDelete(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("删除成功");
})
},
/** 导出按钮操作 */
handleExport() {
this.download('workflow/process/ownExport', {
...this.queryParams
}, `wf_own_process_${new Date().getTime()}.xlsx`)
},
categoryFormat(row, column) {
return this.categoryOptions.find(k => k.code === row.category)?.categoryName ?? '';
}
}
};
</script>
<style scoped>
.file {
border: none;
background: none;
/* 取消其他默认样式 */
box-shadow: none;
padding: 0;
margin: 0;
}
.file:hover {
background: none; /* 去掉鼠标悬停时的背景 */
/* 如果需要可以添加其他hover效果 */
}
</style>

View File

@ -645,7 +645,7 @@ import TreeNodeDialog from './TreeNodeDialog'
import { isNumberStr } from '@/utils/index'
import IconsDialog from './IconsDialog'
import {
inputComponents, selectComponents, layoutComponents
inputComponents, selectComponents, layoutComponents, textComponents
} from '@/utils/generator/config'
import { saveFormConf } from '@/utils/db'
@ -785,6 +785,10 @@ export default {
},
tagList() {
return [
{
label: '显示型组件',
options: textComponents
},
{
label: '输入型组件',
options: inputComponents

View File

@ -71,6 +71,7 @@
<draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup">
<draggable-item
v-for="(item, index) in drawingList"
:class="item.__config__.tagIcon"
:key="item.renderKey"
:drawing-list="drawingList"
:current-item="item"
@ -143,7 +144,13 @@ import render from '@/utils/generator/render'
import FormDrawer from './FormDrawer'
import JsonDrawer from './JsonDrawer'
import RightPanel from './RightPanel'
import { inputComponents, selectComponents, layoutComponents, formConf } from '@/utils/generator/config'
import {
inputComponents,
selectComponents,
layoutComponents,
formConf,
textComponents
} from '@/utils/generator/config'
import { beautifierConf, titleCase, deepClone } from '@/utils/index'
import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html'
import { makeUpJs } from '@/utils/generator/js'
@ -184,6 +191,7 @@ export default {
logo,
idGlobal,
formConf,
textComponents,
inputComponents,
selectComponents,
layoutComponents,
@ -201,6 +209,10 @@ export default {
saveDrawingListDebounce: debounce(340, saveDrawingList),
saveIdGlobalDebounce: debounce(340, saveIdGlobal),
leftComponents: [
{
title: '显示型组件',
list: textComponents
},
{
title: '输入型组件',
list: inputComponents
@ -563,6 +575,42 @@ export default {
<style lang='scss'>
// zqjia: set the style for el-input__inner in textShow component
// for textShow component with width 22
.el-col {
.text {
.el-input__inner, .el-input {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: bold;
font-size: 14px;
color: #606266;
border: 0 !important;
box-shadow: none !important;
background-color: transparent !important;
text-align: center;
}
}
}
// for multi textShow component in a line with width 24
.el-col-24 {
.text {
.el-input__inner, .el-input {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: bold;
font-size: 14px;
color: #606266;
border: 0 !important;
box-shadow: none !important;
background-color: transparent !important;
text-align: left;
}
}
}
.editor-tabs{
background: #121315;
.el-tabs__header{

View File

@ -83,7 +83,7 @@
<el-table v-loading="loading" fit :data="modelList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="流程ID" align="center" prop="modelKey" :show-overflow-tooltip="true" />
<el-table-column label="流程名称" align="center" :show-overflow-tooltip="true">
<el-table-column label="流程名称" align="center" :show-overflow-tooltip="true" :min-width="300" width="300">
<template slot-scope="scope">
<el-button type="text" @click="handleProcessView(scope.row)">
<span>{{ scope.row.modelName }}</span>
@ -98,7 +98,7 @@
</el-table-column>
<el-table-column label="描述" align="center" prop="description" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" :min-width="340" width="340">
<template slot-scope="scope">
<el-button
size="mini"
@ -113,7 +113,7 @@
icon="el-icon-brush"
@click="handleDesigner(scope.row)"
v-hasPermi="['workflow:model:designer']"
>设计</el-button>
>审批流程设计</el-button>
<el-button
type="text"
size="mini"
@ -154,9 +154,12 @@
/>
<!-- 添加或修改模型信息对话框 -->
<!-- logzhan: 这个地方非常关键, 他是对话框的设计部分 -->
<!-- logzhan: 注意visible.sync="open", 这个跟执行函数this.open高度相关 -->
<el-dialog :title="title" :visible.sync="open" width="30%" append-to-body @close="cancel()">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="模型标识" prop="modelKey">
<!-- logzhan: 这里设置clearable disabled,用户则无法修改这栏信息 -->
<el-input v-model="form.modelKey" clearable disabled />
</el-form-item>
<el-form-item label="模型名称" prop="modelName">
@ -503,6 +506,7 @@ export default {
this.open = true;
},
/** 修改按钮操作 */
// logzhan: UI?
handleUpdate(row) {
this.title = "修改流程模型";
this.form = {
@ -512,6 +516,8 @@ export default {
category: row.category,
description: row.description
};
//
// true,
this.open = true;
},
submitForm() {

View File

@ -0,0 +1,243 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="流程名称" prop="processName">
<el-input
v-model="queryParams.processName"
placeholder="请输入流程名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="审批时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
v-hasPermi="['workflow:process:finishedExport']"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="finishedList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="任务编号" align="center" prop="taskId" :show-overflow-tooltip="true"/>
<el-table-column label="流程名称" align="center" prop="procDefName" :show-overflow-tooltip="true"/>
<el-table-column label="任务节点" align="center" prop="taskName" />
<el-table-column label="流程发起人" align="center">
<template slot-scope="scope">
<label>{{scope.row.startUserName}}</label>
</template>
</el-table-column>
<el-table-column label="接收时间" align="center" prop="createTime" width="180"/>
<el-table-column label="审批时间" align="center" prop="finishTime" width="180"/>
<el-table-column label="耗时" align="center" prop="duration" width="180"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-tickets"
@click="handleFlowRecord(scope.row)"
v-hasPermi="['workflow:process:query']"
>流转记录</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-tickets"
@click="handleRevoke(scope.row)"
v-hasPermi="['workflow:process:revoke']"
>撤回
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listFinishedProcess } from '@/api/workflow/process';
import { revokeProcess } from "@/api/workflow/finished";
export default {
name: "Finished",
components: {
},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
finishedList: [],
//
title: "",
//
open: false,
src: "",
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
name: null,
category: null,
key: null,
tenantId: null,
deployTime: null,
derivedFrom: null,
derivedFromRoot: null,
parentDeploymentId: null,
engineVersion: null
},
//
form: {},
//
rules: {
}
};
},
beforeRouteEnter(to, from, next) {
next(vm => {
vm.getList()
})
},
methods: {
/** 查询流程定义列表 */
getList() {
this.loading = true;
listFinishedProcess(this.queryParams).then(response => {
this.finishedList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
name: null,
category: null,
key: null,
tenantId: null,
deployTime: null,
derivedFrom: null,
derivedFromRoot: null,
parentDeploymentId: null,
engineVersion: null
};
this.resetForm("form");
},
setIcon(val){
if (val){
return "el-icon-check";
}else {
return "el-icon-time";
}
},
setColor(val){
if (val){
return "#2bc418";
}else {
return "#b3bdbb";
}
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加流程定义";
},
/** 流程流转记录 */
handleFlowRecord(row){
this.$router.push({
path: '/workflow/process/detail/' + row.procInsId,
query: {
processed: false
}
})
},
/** 撤回任务 */
handleRevoke(row) {
const params = {
procInsId: row.procInsId,
taskId: row.taskId
};
revokeProcess(params).then(res => {
this.$modal.msgSuccess(res.msg);
this.getList();
});
},
/** 导出按钮操作 */
handleExport() {
this.download('workflow/process/finishedExport', {
...this.queryParams
}, `wf_finished_process_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -0,0 +1,326 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="流程标识" prop="processKey">
<el-input
v-model="queryParams.processKey"
placeholder="请输入流程标识"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="processName">
<el-input
v-model="queryParams.processName"
placeholder="请输入流程名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-select v-model="queryParams.category" clearable placeholder="请选择" size="small">
<el-option
v-for="item in categoryOptions"
:key="item.categoryId"
:label="item.categoryName"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="提交时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
v-hasPermi="['workflow:process:ownExport']"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="ownProcessList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="项目申报名" align="center" width="240px" :min-width="240">
<template slot-scope="scope">
<el-tag size="medium">{{ scope.row.processTitle }}</el-tag>
</template>
</el-table-column>
<el-table-column label="项目负责人" align="center" prop="director" width="100"/>
<el-table-column label="计划(基金)中文名称" align="center" width="200px">
<template slot-scope="scope">
<el-tag size="medium" >{{ scope.row.procDefName }}</el-tag>
</template>
</el-table-column>
<el-table-column label="审批类别" align="center" prop="category" :formatter="categoryFormat" width="120"/>
<el-table-column label="提交时间" align="center" prop="createTime" :min-width="180"/>
<el-table-column label="项目审核状态" align="center" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.wf_process_status" :value="scope.row.processStatus"/>
</template>
</el-table-column>
<!-- <el-table-column label="耗时" align="center" prop="duration" width="180"/> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
<template slot-scope="scope">
<el-button
type="text"
size="mini"
icon="el-icon-top"
@click="handleProcessStart(scope.row)"
v-hasPermi="['workflow:process:query']"
>发起立项</el-button>
<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-delete"
@click="handleDelete(scope.row)"
v-if="scope.row.finishTime"
v-hasPermi="['workflow:process:remove']"
>删除</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-circle-close"
@click="handleStop(scope.row)"
v-hasPermi="['workflow:process:cancel']"
>取消</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-refresh-right"
v-hasPermi="['workflow:process:start']"
@click="handleAgain(scope.row)"
>修改重审</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listOwnInfoProcess, stopProcess, delProcess } from '@/api/workflow/process';
import { listAllCategory } from '@/api/workflow/category';
export default {
name: "Own",
dicts: ['wf_process_status'],
components: {
},
data() {
return {
//
loading: true,
processLoading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
categoryOptions: [],
processTotal:0,
//
ownProcessList: [],
//
title: "",
//
open: false,
src: "",
definitionList:[],
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: undefined,
category: undefined,
detailTitleName: 'field101',
detailDirectorName: 'field102'
},
//
form: {},
//
rules: {
},
};
},
created() {
this.getCategoryList();
},
beforeRouteEnter(to, from, next) {
next(vm => {
vm.getList()
})
},
methods: {
/** 查询流程分类列表 */
getCategoryList() {
listAllCategory().then(response => this.categoryOptions = response.data)
},
/** 查询流程定义列表 */
getList() {
this.loading = true;
listOwnInfoProcess(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.ownProcessList = response.rows.filter(item => item.category === '002' && item.processStatus === 'completed');
//this.ownProcessList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
name: null,
category: null,
key: null,
tenantId: null,
deployTime: null,
derivedFrom: null,
derivedFromRoot: null,
parentDeploymentId: null,
engineVersion: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.procInsId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
handleAgain(row) {
this.$router.push({
path: '/workflow/process/start/' + row.deployId,
query: {
definitionId: row.procDefId,
procInsId: row.procInsId
}
})
console.log(row);
},
handleProcessStart(row) {
const deploymentId = 'b1531b69-3eae-11ef-97ad-106fd9c7c7b5'; // row deploymentId
const definitionId = 'Process_1720608606342:1:b161c16c-3eae-11ef-97ad-106fd9c7c7b5'; // row definitionId
this.$router.push({
path: `/workflow/process/start/${deploymentId}?definitionId=${definitionId}`,
});
},
/** 取消流程申请 */
handleStop(row){
const params = {
procInsId: row.procInsId
}
stopProcess(params).then( res => {
this.$modal.msgSuccess(res.msg);
this.getList();
});
},
/** 流程流转记录 */
handleFlowRecord(row) {
this.$router.push({
path: '/workflow/process/detail/' + row.procInsId,
query: {
processed: false
}
})
},
/** 删除按钮操作 */
handleDelete(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("删除成功");
})
},
/** 导出按钮操作 */
handleExport() {
this.download('workflow/process/ownExport', {
...this.queryParams
}, `wf_own_process_${new Date().getTime()}.xlsx`)
},
categoryFormat(row, column) {
return this.categoryOptions.find(k => k.code === row.category)?.categoryName ?? '';
}
}
};
</script>

View File

@ -434,7 +434,7 @@ export default {
}
this.historyProcNodeList = data.historyProcNodeList;
this.finishedInfo = data.flowViewer;
this.formOpen = true
this.formOpen = true;
})
},
onSelectCopyUsers() {

View File

@ -10,16 +10,16 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="processName">
<el-form-item label="项目名称" prop="processName">
<el-input
v-model="queryParams.processName"
placeholder="请输入流程名称"
placeholder="请输入项目名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-form-item label="项目分类" prop="category">
<el-select v-model="queryParams.category" clearable placeholder="请选择" size="small">
<el-option
v-for="item in categoryOptions"
@ -47,38 +47,55 @@
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- 下面这个地方就是流程的列表 -->
<el-table v-loading="loading" fit :data="processList">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="流程标识" align="center" prop="processKey" :show-overflow-tooltip="true" />
<el-table-column label="流程名称" align="center" :show-overflow-tooltip="true">
<el-table-column label="申报项目名称" align="left" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-button type="text" @click="handleProcessView(scope.row)">
<span>{{ scope.row.processName }}</span>
</el-button>
</template>
</el-table-column>
<el-table-column label="流程分类" align="center" prop="categoryName" :formatter="categoryFormat" />
<el-table-column label="审批分类" align="center" prop="categoryName" :formatter="categoryFormat" />
<el-table-column label="流程版本" align="center">
<template slot-scope="scope">
<el-tag size="medium" >v{{ scope.row.version }}</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" align="center">
<el-table-column label="申报状态" align="center">
<template slot-scope="scope">
<el-tag type="success" v-if="!scope.row.suspended"></el-tag>
<el-tag type="warning" v-if="scope.row.suspended"></el-tag>
<el-tag type="success" v-if="!scope.row.suspended"></el-tag>
<el-tag type="warning" v-if="scope.row.suspended"></el-tag>
</template>
</el-table-column>
<el-table-column label="部署时间" align="center" prop="deploymentTime" width="180"/>
<el-table-column label="发布时间" align="center" prop="deploymentTime" width="180"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<!-- 这个地方指定的按钮的相关UI和图标 -->
<el-button
type="text"
size="mini"
icon="el-icon-video-play"
icon="el-icon-top"
@click="handleStart(scope.row)"
v-hasPermi="['workflow:process:start']"
>发起</el-button>
>进入申报</el-button>
<!-- 这个地方的发起就是新建流程的发起按钮 -->
<el-button
type="text"
size="mini"
icon="el-icon-document-copy"
@click="handleStart(scope.row)"
v-hasPermi="['workflow:process:start']"
>详情</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-arrow-down"
@click="handleStart(scope.row)"
v-hasPermi="['workflow:process:start']"
>更多</el-button>
</template>
</el-table-column>
</el-table>
@ -139,10 +156,12 @@ export default {
}
}
},
//
created() {
this.getCategoryList();
this.getList();
},
// methods :
methods: {
/** 查询流程分类列表 */
getCategoryList() {
@ -152,6 +171,8 @@ export default {
getList() {
this.loading = true;
listProcess(this.queryParams).then(response => {
//
//this.processList = response.rows.filter(item => item.categoryName === 'completed');
this.processList = response.rows;
this.total = response.total;
this.loading = false

View File

@ -0,0 +1,309 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="流程标识" prop="processKey">
<el-input
v-model="queryParams.processKey"
placeholder="请输入流程标识"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="processName">
<el-input
v-model="queryParams.processName"
placeholder="请输入流程名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-select v-model="queryParams.category" clearable placeholder="请选择" size="small">
<el-option
v-for="item in categoryOptions"
:key="item.categoryId"
:label="item.categoryName"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="提交时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
v-hasPermi="['workflow:process:ownExport']"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="ownProcessList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="项目申报名" align="center" width="280px" :min-width="280">
<template slot-scope="scope">
<el-tag size="medium">{{ scope.row.processTitle }}</el-tag>
</template>
</el-table-column>
<el-table-column label="项目负责人" align="center" prop="director" width="140"/>
<el-table-column label="计划(基金)中文名称" align="center" width="200px">
<template slot-scope="scope">
<el-tag size="medium" >{{ scope.row.procDefName }}</el-tag>
</template>
</el-table-column>
<el-table-column label="审批类别" align="center" prop="category" :formatter="categoryFormat" width="180"/>
<el-table-column label="提交时间" align="center" prop="createTime" :min-width="180"/>
<el-table-column label="项目审核状态" align="center" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.wf_process_status" :value="scope.row.processStatus"/>
</template>
</el-table-column>
<!-- <el-table-column label="耗时" align="center" prop="duration" width="180"/> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="240">
<template slot-scope="scope">
<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-delete"
@click="handleDelete(scope.row)"
v-if="scope.row.finishTime"
v-hasPermi="['workflow:process:remove']"
>删除</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-circle-close"
@click="handleStop(scope.row)"
v-hasPermi="['workflow:process:cancel']"
>取消</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-refresh-right"
v-hasPermi="['workflow:process:start']"
@click="handleAgain(scope.row)"
>修改重审</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listOwnInfoProcess, stopProcess, delProcess } from '@/api/workflow/process';
import { listAllCategory } from '@/api/workflow/category';
export default {
name: "Own",
dicts: ['wf_process_status'],
components: {
},
data() {
return {
//
loading: true,
processLoading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
categoryOptions: [],
processTotal:0,
//
ownProcessList: [],
//
title: "",
//
open: false,
src: "",
definitionList:[],
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: undefined,
category: undefined,
detailTitleName: 'proj_name',
detailDirectorName: 'director'
},
//
form: {},
//
rules: {
},
};
},
created() {
this.getCategoryList();
},
beforeRouteEnter(to, from, next) {
next(vm => {
vm.getList()
})
},
methods: {
/** 查询流程分类列表 */
getCategoryList() {
listAllCategory().then(response => this.categoryOptions = response.data)
},
/** 查询流程定义列表 */
getList() {
this.loading = true;
listOwnInfoProcess(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.ownProcessList = response.rows.filter(item => item.category === '004');
//this.ownProcessList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
name: null,
category: null,
key: null,
tenantId: null,
deployTime: null,
derivedFrom: null,
derivedFromRoot: null,
parentDeploymentId: null,
engineVersion: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.procInsId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
handleAgain(row) {
this.$router.push({
path: '/workflow/process/start/' + row.deployId,
query: {
definitionId: row.procDefId,
procInsId: row.procInsId
}
})
console.log(row);
},
/** 取消流程申请 */
handleStop(row){
const params = {
procInsId: row.procInsId
}
stopProcess(params).then( res => {
this.$modal.msgSuccess(res.msg);
this.getList();
});
},
/** 流程流转记录 */
handleFlowRecord(row) {
this.$router.push({
path: '/workflow/process/detail/' + row.procInsId,
query: {
processed: false
}
})
},
/** 删除按钮操作 */
handleDelete(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("删除成功");
})
},
/** 导出按钮操作 */
handleExport() {
this.download('workflow/process/ownExport', {
...this.queryParams
}, `wf_own_process_${new Date().getTime()}.xlsx`)
},
categoryFormat(row, column) {
return this.categoryOptions.find(k => k.code === row.category)?.categoryName ?? '';
}
}
};
</script>

View File

@ -73,23 +73,27 @@
<el-table v-loading="loading" :data="ownProcessList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="流程编号" align="center" prop="procInsId" :show-overflow-tooltip="true"/>
<el-table-column label="流程名称" align="center" prop="procDefName" :show-overflow-tooltip="true"/>
<el-table-column label="流程类别" align="center" prop="category" :formatter="categoryFormat" />
<el-table-column label="流程版本" align="center" width="80px">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="项目申报名" align="center" width="280px" :min-width="280">
<template slot-scope="scope">
<el-tag size="medium" >v{{ scope.row.procDefVersion }}</el-tag>
<el-tag size="medium">{{ scope.row.processTitle }}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前节点" align="center" prop="taskName"/>
<el-table-column label="提交时间" align="center" prop="createTime" width="180"/>
<el-table-column label="流程状态" align="center" width="100">
<el-table-column label="项目负责人" align="center" prop="director" width="140"/>
<el-table-column label="计划(基金)中文名称" align="center" width="200px">
<template slot-scope="scope">
<el-tag size="medium" >{{ scope.row.procDefName }}</el-tag>
</template>
</el-table-column>
<el-table-column label="审批类别" align="center" prop="category" :formatter="categoryFormat" width="180"/>
<el-table-column label="提交时间" align="center" prop="createTime" :min-width="180"/>
<el-table-column label="项目审核状态" align="center" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.wf_process_status" :value="scope.row.processStatus"/>
</template>
</el-table-column>
<el-table-column label="耗时" align="center" prop="duration" width="180"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<!-- <el-table-column label="耗时" align="center" prop="duration" width="180"/> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="240">
<template slot-scope="scope">
<el-button
type="text"
@ -119,7 +123,7 @@
icon="el-icon-refresh-right"
v-hasPermi="['workflow:process:start']"
@click="handleAgain(scope.row)"
>重新发起</el-button>
>修改重审</el-button>
</template>
</el-table-column>
</el-table>
@ -136,7 +140,7 @@
</template>
<script>
import { listOwnProcess, stopProcess, delProcess } from '@/api/workflow/process';
import { listOwnInfoProcess, stopProcess, delProcess } from '@/api/workflow/process';
import { listAllCategory } from '@/api/workflow/category';
export default {
name: "Own",
@ -176,7 +180,9 @@ export default {
pageSize: 10,
processKey: undefined,
processName: undefined,
category: undefined
category: undefined,
detailTitleName: 'field101',
detailDirectorName: 'field102'
},
//
form: {},
@ -201,8 +207,9 @@ export default {
/** 查询流程定义列表 */
getList() {
this.loading = true;
listOwnProcess(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.ownProcessList = response.rows;
listOwnInfoProcess(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.ownProcessList = response.rows.filter(item => item.category === '002');
//this.ownProcessList = response.rows;
this.total = response.total;
this.loading = false;
});

View File

@ -0,0 +1,300 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="流程标识" prop="processKey">
<el-input
v-model="queryParams.processKey"
placeholder="请输入流程标识"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="processName">
<el-input
v-model="queryParams.processName"
placeholder="请输入流程名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-select v-model="queryParams.category" clearable placeholder="请选择" size="small">
<el-option
v-for="item in categoryOptions"
:key="item.categoryId"
:label="item.categoryName"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="提交时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
v-hasPermi="['workflow:process:ownExport']"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="ownProcessList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="项目编号" align="center" prop="procInsId" :show-overflow-tooltip="true"/>
<el-table-column label="计划(基金)中文名称" align="center" width="280px">
<template slot-scope="scope">
<el-tag size="medium" >{{ scope.row.procDefName }}</el-tag>
</template>
</el-table-column>
<el-table-column label="审批类别" align="center" prop="category" :formatter="categoryFormat" width="140"/>
<el-table-column label="提交时间" align="center" prop="createTime" width="180"/>
<el-table-column label="项目审核状态" align="center" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.wf_process_status" :value="scope.row.processStatus"/>
</template>
</el-table-column>
<el-table-column label="耗时" align="center" prop="duration" width="180"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="240">
<template slot-scope="scope">
<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-delete"
@click="handleDelete(scope.row)"
v-if="scope.row.finishTime"
v-hasPermi="['workflow:process:remove']"
>删除</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-circle-close"
@click="handleStop(scope.row)"
v-hasPermi="['workflow:process:cancel']"
>取消</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-refresh-right"
v-hasPermi="['workflow:process:start']"
@click="handleAgain(scope.row)"
>修改重审</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listOwnProcess, stopProcess, delProcess } from '@/api/workflow/process';
import { listAllCategory } from '@/api/workflow/category';
export default {
name: "Own",
dicts: ['wf_process_status'],
components: {
},
data() {
return {
//
loading: true,
processLoading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
categoryOptions: [],
processTotal:0,
//
ownProcessList: [],
//
title: "",
//
open: false,
src: "",
definitionList:[],
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: undefined,
category: undefined
},
//
form: {},
//
rules: {
},
};
},
created() {
this.getCategoryList();
},
beforeRouteEnter(to, from, next) {
next(vm => {
vm.getList()
})
},
methods: {
/** 查询流程分类列表 */
getCategoryList() {
listAllCategory().then(response => this.categoryOptions = response.data)
},
/** 查询流程定义列表 */
getList() {
this.loading = true;
listOwnProcess(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.ownProcessList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
name: null,
category: null,
key: null,
tenantId: null,
deployTime: null,
derivedFrom: null,
derivedFromRoot: null,
parentDeploymentId: null,
engineVersion: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.procInsId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
handleAgain(row) {
this.$router.push({
path: '/workflow/process/start/' + row.deployId,
query: {
definitionId: row.procDefId,
procInsId: row.procInsId
}
})
console.log(row);
},
/** 取消流程申请 */
handleStop(row){
const params = {
procInsId: row.procInsId
}
stopProcess(params).then( res => {
this.$modal.msgSuccess(res.msg);
this.getList();
});
},
/** 流程流转记录 */
handleFlowRecord(row) {
this.$router.push({
path: '/workflow/process/detail/' + row.procInsId,
query: {
processed: false
}
})
},
/** 删除按钮操作 */
handleDelete(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("删除成功");
})
},
/** 导出按钮操作 */
handleExport() {
this.download('workflow/process/ownExport', {
...this.queryParams
}, `wf_own_process_${new Date().getTime()}.xlsx`)
},
categoryFormat(row, column) {
return this.categoryOptions.find(k => k.code === row.category)?.categoryName ?? '';
}
}
};
</script>

View File

@ -0,0 +1,226 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="流程标识" prop="processKey">
<el-input
v-model="queryParams.processKey"
placeholder="请输入流程标识"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="项目名称" prop="processName">
<el-input
v-model="queryParams.processName"
placeholder="请输入项目名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="项目分类" prop="category">
<el-select v-model="queryParams.category" clearable placeholder="请选择" size="small">
<el-option
v-for="item in categoryOptions"
:key="item.categoryId"
:label="item.categoryName"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
v-hasPermi="['workflow:process:startExport']"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- 下面这个地方就是流程的列表 -->
<el-table v-loading="loading" fit :data="processList">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="流程类型" align="left" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-button type="text" @click="handleProcessView(scope.row)">
<span>{{ scope.row.processName }}</span>
</el-button>
</template>
</el-table-column>
<el-table-column label="审批分类" align="center" prop="categoryName" :formatter="categoryFormat" />
<el-table-column label="流程版本" align="center">
<template slot-scope="scope">
<el-tag size="medium" >v{{ scope.row.version }}</el-tag>
</template>
</el-table-column>
<el-table-column label="流程状态" align="center">
<template slot-scope="scope">
<el-tag type="success" v-if="!scope.row.suspended"></el-tag>
<el-tag type="warning" v-if="scope.row.suspended"></el-tag>
</template>
</el-table-column>
<el-table-column label="发布时间" align="center" prop="deploymentTime" width="180"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<!-- 这个地方指定的按钮的相关UI和图标 -->
<el-button
type="text"
size="mini"
icon="el-icon-top"
@click="handleStart(scope.row)"
v-hasPermi="['workflow:process:start']"
>发起流程</el-button>
<!-- 这个地方的发起就是新建流程的发起按钮 -->
<el-button
type="text"
size="mini"
icon="el-icon-document-copy"
@click="handleStart(scope.row)"
v-hasPermi="['workflow:process:start']"
>详情</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-arrow-down"
@click="handleStart(scope.row)"
v-hasPermi="['workflow:process:start']"
>更多</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 流程图 -->
<el-dialog :title="processView.title" :visible.sync="processView.open" width="70%" append-to-body>
<process-viewer :key="`designer-${processView.index}`" :xml="processView.xmlData" :style="{height: '400px'}" />
</el-dialog>
</div>
</template>
<script>
import { listProcess, getBpmnXml } from "@/api/workflow/process";
import { listAllCategory } from '@/api/workflow/category'
import ProcessViewer from '@/components/ProcessViewer'
export default {
name: 'WorkProcess',
components: {
ProcessViewer
},
data() {
return {
//
loading: true,
//
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: undefined,
category: undefined
},
//
showSearch: true,
//
total: 0,
filterCategoryText: '',
categoryOptions: [],
categoryProps: {
label: 'categoryName',
value: 'code'
},
//
processList: [],
processView: {
title: '',
open: false,
index: undefined,
xmlData:"",
}
}
},
//
created() {
this.getCategoryList();
this.getList();
},
// methods :
methods: {
/** 查询流程分类列表 */
getCategoryList() {
listAllCategory().then(response => this.categoryOptions = response.data)
},
/** 查询流程定义列表 */
getList() {
this.loading = true;
listProcess(this.queryParams).then(response => {
//
//this.processList = response.rows.filter(item => item.categoryName === 'completed');
this.processList = response.rows;
this.total = response.total;
this.loading = false
})
},
//
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
//
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 查看流程图 */
handleProcessView(row) {
let definitionId = row.definitionId;
this.processView.title = "流程图";
this.processView.index = definitionId;
// xml
getBpmnXml(definitionId).then(res => {
this.processView.xmlData = res.data;
})
this.processView.open = true;
},
handleStart(row) {
this.$router.push({
path: '/workflow/process/start/' + row.deploymentId,
query: {
definitionId: row.definitionId,
}
})
},
/** 导出按钮操作 */
handleExport() {
this.download('workflow/process/startExport', {
...this.queryParams
}, `wf_start_process_${new Date().getTime()}.xlsx`)
},
categoryFormat(row, column) {
return this.categoryOptions.find(k => k.code === row.category)?.categoryName ?? '';
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,318 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="流程标识" prop="processKey">
<el-input
v-model="queryParams.processKey"
placeholder="请输入流程标识"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="processName">
<el-input
v-model="queryParams.processName"
placeholder="请输入流程名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-select v-model="queryParams.category" clearable placeholder="请选择" size="small">
<el-option
v-for="item in categoryOptions"
:key="item.categoryId"
:label="item.categoryName"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="提交时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
v-hasPermi="['workflow:process:ownExport']"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="ownProcessList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" type="index" width="50"/>
<el-table-column label="项目计划名" align="center" :min-width="260" width="auto">
<template slot-scope="scope">
<el-tag size="medium" >{{ scope.row.processTitle }}</el-tag>
</template>
</el-table-column>
<el-table-column label="审核类型" align="center" prop="procDefName" :min-width="140" width="auto"/>
<el-table-column label="审批类别" align="center" prop="category" :formatter="categoryFormat" width="140"/>
<el-table-column label="提交时间" align="center" prop="createTime" width="180"/>
<el-table-column label="项目审核状态" align="center" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.wf_process_status" :value="scope.row.processStatus"/>
</template>
</el-table-column>
<el-table-column label="耗时" align="center" prop="duration" width="160"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280">
<template slot-scope="scope">
<el-button
type="text"
size="mini"
icon="el-icon-top"
@click="handleProcessStart(scope.row)"
v-hasPermi="['workflow:process:query']"
>项目申报</el-button>
<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"
@click="handleStop(scope.row)"
v-hasPermi="['workflow:process:cancel']"
>取消</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-refresh-right"
v-hasPermi="['workflow:process:start']"
@click="handleAgain(scope.row)"
>修改重审</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listOwnInfoProcess, stopProcess, delProcess } from '@/api/workflow/process';
import { listAllCategory } from '@/api/workflow/category';
export default {
name: "Own",
dicts: ['wf_process_status'],
components: {
},
data() {
return {
//
loading: true,
processLoading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
categoryOptions: [],
processTotal:0,
//
ownProcessList: [],
//
title: "",
//
open: false,
src: "",
definitionList:[],
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: undefined,
// code
// category: "006"
category: undefined,
detailTitleName: 'proj_plan_title',
detailDirectorName: undefined
},
//
form: {},
//
rules: {
},
};
},
created() {
this.getCategoryList();
},
beforeRouteEnter(to, from, next) {
next(vm => {
vm.getList()
})
},
methods: {
/** 查询流程分类列表 */
getCategoryList() {
listAllCategory().then(response => this.categoryOptions = response.data)
},
/** 查询流程定义列表 */
getList() {
this.loading = true;
listOwnInfoProcess(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.ownProcessList = response.rows.filter(item => item.category === '006');
//this.ownProcessList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
name: null,
category: null,
key: null,
tenantId: null,
deployTime: null,
derivedFrom: null,
derivedFromRoot: null,
parentDeploymentId: null,
engineVersion: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.procInsId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
handleAgain(row) {
this.$router.push({
path: '/workflow/process/start/' + row.deployId,
query: {
definitionId: row.procDefId,
procInsId: row.procInsId
}
})
console.log(row);
},
/** 取消流程申请 */
handleStop(row){
const params = {
procInsId: row.procInsId
}
stopProcess(params).then( res => {
this.$modal.msgSuccess(res.msg);
this.getList();
});
},
/** 流程流转记录 */
//
handleFlowRecord(row) {
this.$router.push({
path: '/workflow/process/detail/' + row.procInsId,
query: {
processed: false
}
})
},
handleProcessStart(row) {
const deploymentId = '7d553e9a-3e02-11ef-a576-106fd9c7c7b5'; // row deploymentId
const definitionId = 'Process_1720536463039:1:7d67b52d-3e02-11ef-a576-106fd9c7c7b5'; // row definitionId
this.$router.push({
path: `/workflow/process/start/${deploymentId}?definitionId=${definitionId}`,
});
},
/** 删除按钮操作 */
handleDelete(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("删除成功");
})
},
/** 导出按钮操作 */
handleExport() {
this.download('workflow/process/ownExport', {
...this.queryParams
}, `wf_own_process_${new Date().getTime()}.xlsx`)
},
// cateory001
categoryFormat(row, column) {
return this.categoryOptions.find(k => k.code === row.category)?.categoryName ?? '';
}
}
};
</script>

View File

@ -2,8 +2,9 @@
<div class="app-container">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>发起流程</span>
<span>{{ processName }}</span>
</div>
<el-col :span="18" :offset="3">
<div class="form-conf" v-if="formOpen">
<parser :key="new Date().getTime()" :form-conf="formData" @submit="submit" ref="parser" @getData="getData"/>
@ -29,6 +30,8 @@ export default {
procInsId: null,
formOpen: false,
formData: {},
processName: null,
}
},
created() {
@ -39,6 +42,8 @@ export default {
this.deployId = this.$route.params && this.$route.params.deployId;
this.definitionId = this.$route.query && this.$route.query.definitionId;
this.procInsId = this.$route.query && this.$route.query.procInsId;
this.processName = this.$route.query && this.$route.query.processName;
getProcessForm({
definitionId: this.definitionId,
deployId: this.deployId,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,73 +0,0 @@
## Ruoyi-flowable-plus环境配置指南
> 版本 1.0 更新日期2024/06/11 作者:詹力
>
> 参考https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init
Ruoyi-flowable-plus是一个支持工作流的若依后台管理框架。工作流的的支持可以有效解决流程审核和流程跟踪等问题。
## 一、后端配置
#### 1.1 软件与环境准备
下面的软件环境在裸机环境下实测可以运行。
> 网盘地址http://logzhan.ticp.io:52440 账号uestc 密码123
>
> 1. IDE : [IntelliJ IDEA 2022.1.3 (Ultimate Edition)](http://logzhan.ticp.io:52440/web%E5%BC%80%E5%8F%91/IDEA-2022.1.3)
> 2. NodeJs : [NodeJS 14.14](http://logzhan.ticp.io:52440/d/%E6%88%91%E7%9A%84%E5%A4%87%E4%BB%BD/logzhan%E7%9A%84%E4%BA%91%E7%9B%98/web%E5%BC%80%E5%8F%91/node-v14.14.0-x64.msi)
> 3. Redis : [下载地址](http://logzhan.ticp.io:52440/d/%E6%88%91%E7%9A%84%E5%A4%87%E4%BB%BD/logzhan%E7%9A%84%E4%BA%91%E7%9B%98/GoWeb%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85/Redis-Windows.zip)
> 4. JAVA SDK : [java1.8](http://logzhan.ticp.io:52440/d/%E6%88%91%E7%9A%84%E5%A4%87%E4%BB%BD/logzhan%E7%9A%84%E4%BA%91%E7%9B%98/Web%E5%BC%80%E5%8F%91/jdk-8u241-windows-x64.exe)
> 5. SQL : [Sql 8.0]()
#### 1.2 IDE的相关配置和依赖下载
启动`Intellij IDEA`选择打开`Ruoyi-flowable-plus`的工程目录IDE即可**自动下载依赖**(IDE内置Maven)。根据[官方教程](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init)配置SDK如下。在`SDK`选项中选择`Edit`并选择1.1中graalvm-17的解压目录即可管理。
<img src="http://logzhan.ticp.io:30000/logzhan/PictureHost/raw/branch/main/Ruoyi-flowable-Plus/%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/Image/5%E3%80%81%E6%9B%B4%E6%94%B9JDK.png" style="zoom: 67%;" />
同步成功后如下图所示:
![](http://logzhan.ticp.io:30000/logzhan/PictureHost/raw/branch/main/Ruoyi-flowable-Plus/%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/Image/IDE%E4%BE%9D%E8%B5%96%E5%90%8C%E6%AD%A5.png)
#### 1.3 本地数据库的配置和导入
打开`nvicat`或者其他数据库软件,创建`ry-flowable-plus`或者其他你喜欢的数据库名。
<img src="http://logzhan.ticp.io:30000/logzhan/PictureHost/raw/branch/main/Ruoyi-flowable-Plus/%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/Image/10%E3%80%81%E5%88%9B%E5%BB%BA%E6%95%B0%E6%8D%AE%E5%BA%93.png" style="zoom:50%;" />
选择你创建的数据库并打开,右键选择运行数据库。
![](http://logzhan.ticp.io:30000/logzhan/PictureHost/raw/branch/main/Ruoyi-flowable-Plus/%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/Image/10%E3%80%81%E8%BF%90%E8%A1%8C%E6%95%B0%E6%8D%AE%E5%BA%93.png)
1. 运行`mysql_ry_v0.8.x.sql`
2. 运行`flowable_6.7.2_mysql(...).sql`
3. 运行`mysql_xxl_job.sql`
#### 1.4 远程数据库的配置
数据库的配置,打开`ruoyi-admin\src\main\resource\application-dev.yml`,下面的`url`是采用个人搭建的公共数据库,可以在外网访问。本地数据库修改为`mysql://localhost:3306/`。`ry-flowable-plus`是数据库名,根据个人实际创建数据库时的名字进行调整。
```yml
# 主库数据源
master:
type: ${spring.datasource.type}
driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应 考虑性能问题)
url: jdbc:mysql://logzhan.ticp.io:53306/ry-flowable-plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true
username: root
password: 351002
```
## 二、前端配置
前端配置非常简单,只要求安装`nodejs`,然后进入`ruoyi-ui`
```shell
npm install --registry=https://registry.npmmirror.com
npm run dev
```
成功后会弹出网址即可访问。