Commit 8a10568b24c3677cd3d58430dfe866d9faaec055

Authored by YunaiV
1 parent 749cb5d7

1. 修改 Parser.vue 组件,实现 submit 传递 conf 和 values 参数

2. 完成流程创建的前端 UI 界面
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmDefinitionConvert.java
... ... @@ -17,6 +17,7 @@ import org.mapstruct.factory.Mappers;
17 17  
18 18 import java.util.List;
19 19 import java.util.Map;
  20 +import java.util.function.Function;
20 21  
21 22 /**
22 23 * Bpm 流程定义的 Convert
... ... @@ -59,10 +60,18 @@ public interface BpmDefinitionConvert {
59 60  
60 61 BpmProcessDefinitionExtDO convert2(BpmDefinitionCreateReqDTO bean);
61 62  
62   - @Named("convertList3")
63   - List<BpmProcessDefinitionRespVO> convertList3(List<ProcessDefinition> list);
  63 + default List<BpmProcessDefinitionRespVO> convertList3(List<ProcessDefinition> list,
  64 + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap) {
  65 + return CollectionUtils.convertList(list, processDefinition -> {
  66 + BpmProcessDefinitionRespVO respVO = convert3(processDefinition);
  67 + BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId());
  68 + if (processDefinitionExtDO != null) {
  69 + respVO.setFormId(processDefinitionExtDO.getFormId());
  70 + }
  71 + return respVO;
  72 + });
  73 + }
64 74  
65   - @Named("convert3")
66 75 @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
67 76 BpmProcessDefinitionRespVO convert3(ProcessDefinition bean);
68 77  
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java
... ... @@ -79,8 +79,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
79 79 Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds);
80 80  
81 81 // 获得 BpmProcessDefinitionDO Map
82   - List<BpmProcessDefinitionExtDO> processDefinitionDOs = Collections.emptyList();
83   - processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
  82 + List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
84 83 convertList(processDefinitions, ProcessDefinition::getId));
85 84 Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = CollectionUtils.convertMap(processDefinitionDOs,
86 85 BpmProcessDefinitionExtDO::getProcessDefinitionId);
... ... @@ -104,8 +103,16 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
104 103 } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), listReqVO.getSuspensionState())) {
105 104 definitionQuery.active();
106 105 }
  106 + // 执行查询
  107 + List<ProcessDefinition> processDefinitions = definitionQuery.list();
  108 +
  109 + // 获得 BpmProcessDefinitionDO Map
  110 + List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
  111 + convertList(processDefinitions, ProcessDefinition::getId));
  112 + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = CollectionUtils.convertMap(processDefinitionDOs,
  113 + BpmProcessDefinitionExtDO::getProcessDefinitionId);
107 114 // 执行查询,并返回
108   - return BpmDefinitionConvert.INSTANCE.convertList3(definitionQuery.list());
  115 + return BpmDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap);
109 116 }
110 117  
111 118 @Override
... ...
yudao-admin-ui/src/api/bpm/definition.js
... ... @@ -8,6 +8,14 @@ export function getProcessDefinitionPage(query) {
8 8 })
9 9 }
10 10  
  11 +export function getProcessDefinitionList(query) {
  12 + return request({
  13 + url: '/bpm/process-definition/list',
  14 + method: 'get',
  15 + params: query
  16 + })
  17 +}
  18 +
11 19 export function getProcessDefinitionBpmnXML(id) {
12 20 return request({
13 21 url: '/bpm/process-definition/get-bpmn-xml?id=' + id,
... ...
yudao-admin-ui/src/api/bpm/processInstance.js
... ... @@ -8,6 +8,14 @@ export function getMyProcessInstancePage(query) {
8 8 })
9 9 }
10 10  
  11 +export function createProcessInstance(data) {
  12 + return request({
  13 + url: '/bpm/process-instance/create',
  14 + method: 'POST',
  15 + data: data
  16 + })
  17 +}
  18 +
11 19 export function cancelProcessInstance(id, reason) {
12 20 return request({
13 21 url: '/bpm/process-instance/cancel',
... ...
yudao-admin-ui/src/components/parser/Parser.vue
... ... @@ -173,8 +173,13 @@ export default {
173 173 submitForm() {
174 174 this.$refs[this.formConf.formRef].validate(valid => {
175 175 if (!valid) return false
176   - // 触发sumit事件
177   - this.$emit('submit', this[this.formConf.formModel])
  176 + // 触发 submit 事件
  177 + // update by 芋道源码
  178 + // this.$emit('submit', this[this.formConf.formModel])
  179 + this.$emit('submit', {
  180 + conf: this.formConfCopy,
  181 + values: this[this.formConf.formModel]
  182 + })
178 183 return true
179 184 })
180 185 }
... ...
yudao-admin-ui/src/views/bpm/processInstance/create.vue
1 1 <template>
2 2 <div class="app-container">
3   - <!-- 列表 -->
4   - <el-table v-loading="loading" :data="list">
5   - <el-table-column label="定义编号" align="center" prop="id" width="400" />
6   - <el-table-column label="定义名称" align="center" prop="name" width="100">
7   - <template slot-scope="scope">
8   - <el-button type="text" @click="handleBpmnDetail(scope.row)">
9   - <span>{{ scope.row.name }}</span>
10   - </el-button>
11   - </template>
12   - </el-table-column>
13   - <el-table-column label="定义分类" align="center" prop="category" width="100">
14   - <template slot-scope="scope">
15   - <span>{{ getDictDataLabel(DICT_TYPE.BPM_MODEL_CATEGORY, scope.row.category) }}</span>
16   - </template>
17   - </el-table-column>
18   - <el-table-column label="表单信息" align="center" prop="formId">
19   - <template slot-scope="scope">
20   - <el-button v-if="scope.row.formId" type="text" @click="handleFormDetail(scope.row)">
21   - <span>{{ scope.row.formName }}</span>
22   - </el-button>
23   - <label v-else>暂无表单</label>
24   - </template>
25   - </el-table-column>
26   - <el-table-column label="流程版本" align="center" prop="processDefinition.version" width="80">
27   - <template slot-scope="scope">
28   - <el-tag size="medium" v-if="scope.row">v{{ scope.row.version }}</el-tag>
29   - <el-tag size="medium" type="warning" v-else>未部署</el-tag>
30   - </template>
31   - </el-table-column>
32   - <el-table-column label="状态" align="center" prop="version" width="80">
33   - <template slot-scope="scope">
34   - <el-tag type="success" v-if="scope.row.suspensionState === 1">激活</el-tag>
35   - <el-tag type="warning" v-if="scope.row.suspensionState === 2">挂起</el-tag>
36   - </template>
37   - </el-table-column>
38   - <el-table-column label="部署时间" align="center" prop="deploymentTime" width="180">
39   - <template slot-scope="scope">
40   - <span>{{ parseTime(scope.row.deploymentTime) }}</span>
41   - </template>
42   - </el-table-column>
43   - <el-table-column label="定义描述" align="center" prop="description" width="300" show-overflow-tooltip />
44   - </el-table>
  3 + <!-- 第一步,通过流程定义的列表,选择对应的流程 -->
  4 + <div v-if="!selectProcessInstance">
  5 + <el-table v-loading="loading" :data="list">
  6 + <el-table-column label="流程名称" align="center" prop="name" width="200">
  7 + <template slot-scope="scope">
  8 + <el-button type="text" @click="handleBpmnDetail(scope.row)">
  9 + <span>{{ scope.row.name }}</span>
  10 + </el-button>
  11 + </template>
  12 + </el-table-column>
  13 + <el-table-column label="流程分类" align="center" prop="category" width="100">
  14 + <template slot-scope="scope">
  15 + <span>{{ getDictDataLabel(DICT_TYPE.BPM_MODEL_CATEGORY, scope.row.category) }}</span>
  16 + </template>
  17 + </el-table-column>
  18 + <el-table-column label="流程版本" align="center" prop="processDefinition.version" width="80">
  19 + <template slot-scope="scope">
  20 + <el-tag size="medium" v-if="scope.row">v{{ scope.row.version }}</el-tag>
  21 + </template>
  22 + </el-table-column>
  23 + <el-table-column label="流程描述" align="center" prop="description" width="300" show-overflow-tooltip />
  24 + <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  25 + <template slot-scope="scope">
  26 + <el-button type="text" size="small" icon="el-icon-plus" @click="handleSelect(scope.row)">选择</el-button>
  27 + </template>
  28 + </el-table-column>
  29 + </el-table>
  30 + </div>
  31 + <!-- 第二步,填写表单,进行流程的提交 -->
  32 + <div v-else>
  33 + <el-card class="box-card" >
  34 + <div slot="header" class="clearfix">
  35 + <span class="el-icon-document">{{ selectProcessInstance.name }}</span>
  36 + <el-button style="float: right;" type="primary" @click="selectProcessInstance = undefined">选择其它流程</el-button>
  37 + </div>
  38 + <el-col :span="16" :offset="6">
  39 + <div>
  40 + <parser :key="new Date().getTime()" :form-conf="detailForm" @submit="submitForm" />
  41 + </div>
  42 + </el-col>
  43 + </el-card>
  44 + </div>
45 45  
46   - <!-- 流程表单配置详情 -->
47   - <el-dialog title="表单详情" :visible.sync="detailOpen" width="50%" append-to-body>
48   - <parser :key="new Date().getTime()" :form-conf="detailForm" />
49   - </el-dialog>
50   -
51   - <!-- 流程模型图的预览 -->
52   - <el-dialog title="流程图" :visible.sync="showBpmnOpen" width="80%" append-to-body>
  46 + <el-card class="box-card">
  47 + <div slot="header" class="clearfix">
  48 + <span class="el-icon-picture-outline">流程图</span>
  49 + </div>
53 50 <my-process-viewer key="designer" v-model="bpmnXML" v-bind="bpmnControlForm" />
54   - </el-dialog>
  51 + </el-card>
55 52  
56   - <!-- 分页组件 -->
57   - <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
58   - @pagination="getList"/>
59 53 </div>
60 54 </template>
61 55  
62 56 <script>
63   -import {getProcessDefinitionBpmnXML, getProcessDefinitionPage} from "@/api/bpm/definition";
  57 +import {getProcessDefinitionBpmnXML, getProcessDefinitionList} from "@/api/bpm/definition";
64 58 import {DICT_TYPE, getDictDatas} from "@/utils/dict";
65 59 import {getForm} from "@/api/bpm/form";
66 60 import {decodeFields} from "@/utils/formGenerator";
67 61 import Parser from '@/components/parser/Parser'
  62 +import {createProcessInstance} from "@/api/bpm/processInstance";
68 63  
69 64 export default {
70 65 name: "processDefinition",
... ... @@ -79,49 +74,51 @@ export default {
79 74 total: 0,
80 75 // 表格数据
81 76 list: [],
82   - // 查询参数
83   - queryParams: {
84   - pageNo: 1,
85   - pageSize: 10
86   - },
87 77  
88 78 // 流程表单详情
89   - detailOpen: false,
90 79 detailForm: {
91 80 fields: []
92 81 },
93 82  
94 83 // BPMN 数据
95   - showBpmnOpen: false,
96 84 bpmnXML: null,
97 85 bpmnControlForm: {
98 86 prefix: "activiti"
99 87 },
100 88  
  89 + // 流程表单
  90 + selectProcessInstance: undefined, // 选择的流程实例
  91 +
101 92 // 数据字典
102 93 categoryDictDatas: getDictDatas(DICT_TYPE.BPM_MODEL_CATEGORY),
103 94 };
104 95 },
105 96 created() {
106   - const key = this.$route.query && this.$route.query.key
107   - if (key) {
108   - this.queryParams['key'] = key
109   - }
110 97 this.getList();
111 98 },
112 99 methods: {
113 100 /** 查询流程定义列表 */
114 101 getList() {
115 102 this.loading = true;
116   - getProcessDefinitionPage(this.queryParams).then(response => {
117   - this.list = response.data.list;
118   - this.total = response.data.total;
119   - this.loading = false;
  103 + getProcessDefinitionList({
  104 + suspensionState: 1
  105 + }).then(response => {
  106 + this.list = response.data
  107 + this.loading = false
120 108 }
121 109 );
122 110 },
123   - /** 流程表单的详情按钮操作 */
124   - handleFormDetail(row) {
  111 + /** 处理选择流程的按钮操作 **/
  112 + handleSelect(row) {
  113 + // 如果无表单,则无法发起流程
  114 + if (!row.formId) {
  115 + this.$message.error('该流程未绑定表单,无法发起流程!请重新选择你要发起的流程');
  116 + return;
  117 + }
  118 + // 设置选择的流程
  119 + this.selectProcessInstance = row;
  120 +
  121 + // 加载对应的表单
125 122 getForm(row.formId).then(response => {
126 123 // 设置值
127 124 const data = response.data
... ... @@ -129,16 +126,36 @@ export default {
129 126 ...JSON.parse(data.conf),
130 127 fields: decodeFields(data.fields)
131 128 }
132   - // 弹窗打开
133   - this.detailOpen = true
134   - })
135   - },
136   - /** 流程图的详情按钮操作 */
137   - handleBpmnDetail(row) {
  129 + });
  130 +
  131 + // 加载流程图
138 132 getProcessDefinitionBpmnXML(row.id).then(response => {
139 133 this.bpmnXML = response.data
140   - // 弹窗打开
141   - this.showBpmnOpen = true
  134 + })
  135 + },
  136 + /** 提交按钮 */
  137 + submitForm(params) {
  138 + if (!params) {
  139 + return;
  140 + }
  141 + // 设置表单禁用
  142 + const conf = params.conf;
  143 + conf.disabled = true; // 表单禁用
  144 + conf.formBtns = false; // 按钮隐藏
  145 +
  146 + // 提交表单,创建流程
  147 + const variables = params.values;
  148 + createProcessInstance({
  149 + processDefinitionId: this.selectProcessInstance.id,
  150 + variables: variables
  151 + }).then(response => {
  152 + this.msgSuccess("发起流程成功");
  153 + // 关闭当前窗口
  154 + this.$store.dispatch("tagsView/delView", this.$route);
  155 + this.$router.go(-1);
  156 + }).catch(() => {
  157 + conf.disabled = false; // 表单开启
  158 + conf.formBtns = true; // 按钮展示
142 159 })
143 160 },
144 161 }
... ... @@ -149,4 +166,9 @@ export default {
149 166 .my-process-designer {
150 167 height: calc(100vh - 200px);
151 168 }
  169 +
  170 +.box-card {
  171 + width: 100%;
  172 + margin-bottom: 20px;
  173 +}
152 174 </style>
... ...
yudao-admin-ui/src/views/bpm/processInstance/index.vue
... ... @@ -47,7 +47,7 @@
47 47  
48 48 <!-- 列表 -->
49 49 <el-table v-loading="loading" :data="list">
50   - <el-table-column label="编号" align="center" prop="id" width="300" />
  50 + <el-table-column label="编号" align="center" prop="id" width="320" />
51 51 <el-table-column label="流程名" align="center" prop="name" />
52 52 <el-table-column label="流程分类" align="center" prop="category">
53 53 <template slot-scope="scope">
... ...