Commit 8c7db2af70540509bada3474a8534af8a89a99a5
1 parent
24c03cf1
BPM 模型重构 4:修改模型,修改成单独的弹窗
Showing
5 changed files
with
120 additions
and
33 deletions
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/model/vo/BpmModelBaseVO.java
| ... | ... | @@ -27,7 +27,15 @@ public class BpmModelBaseVO { |
| 27 | 27 | @NotEmpty(message = "流程分类不能为空") |
| 28 | 28 | private String category; |
| 29 | 29 | |
| 30 | - @ApiModelProperty(value = "表单编号", example = "1024") | |
| 30 | + @ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1") | |
| 31 | + private Integer formType; | |
| 32 | + @ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 31 | 33 | private Long formId; |
| 34 | + @ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", | |
| 35 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 36 | + private String formCustomCreatePath; | |
| 37 | + @ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", | |
| 38 | + notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") | |
| 39 | + private String formCustomViewPath; | |
| 32 | 40 | |
| 33 | 41 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/model/BpmModelConvert.java
| ... | ... | @@ -12,6 +12,7 @@ import org.activiti.engine.repository.Deployment; |
| 12 | 12 | import org.activiti.engine.repository.Model; |
| 13 | 13 | import org.activiti.engine.repository.ProcessDefinition; |
| 14 | 14 | import org.mapstruct.Mapper; |
| 15 | +import org.mapstruct.MappingTarget; | |
| 15 | 16 | import org.mapstruct.factory.Mappers; |
| 16 | 17 | |
| 17 | 18 | import java.util.List; |
| ... | ... | @@ -44,18 +45,15 @@ public interface BpmModelConvert { |
| 44 | 45 | default BpmModelPageItemRespVO convert(Model model, BpmFormDO form, Deployment deployment, ProcessDefinition processDefinition) { |
| 45 | 46 | BpmModelPageItemRespVO modelRespVO = new BpmModelPageItemRespVO(); |
| 46 | 47 | modelRespVO.setId(model.getId()); |
| 47 | - modelRespVO.setName(model.getName()); | |
| 48 | - modelRespVO.setKey(model.getKey()); | |
| 49 | - modelRespVO.setCategory(model.getCategory()); | |
| 50 | 48 | modelRespVO.setCreateTime(model.getCreateTime()); |
| 51 | - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); | |
| 52 | - if (metaInfo != null) { | |
| 53 | - modelRespVO.setDescription(metaInfo.getDescription()); | |
| 54 | - } | |
| 49 | + // 通用 copy | |
| 50 | + copyTo(model, modelRespVO); | |
| 51 | + // Form | |
| 55 | 52 | if (form != null) { |
| 56 | 53 | modelRespVO.setFormId(form.getId()); |
| 57 | 54 | modelRespVO.setFormName(form.getName()); |
| 58 | 55 | } |
| 56 | + // ProcessDefinition | |
| 59 | 57 | modelRespVO.setProcessDefinition(this.convert(processDefinition)); |
| 60 | 58 | if (modelRespVO.getProcessDefinition() != null) { |
| 61 | 59 | modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ? |
| ... | ... | @@ -68,18 +66,23 @@ public interface BpmModelConvert { |
| 68 | 66 | default BpmModelRespVO convert(Model model) { |
| 69 | 67 | BpmModelRespVO modelRespVO = new BpmModelRespVO(); |
| 70 | 68 | modelRespVO.setId(model.getId()); |
| 71 | - modelRespVO.setName(model.getName()); | |
| 72 | - modelRespVO.setKey(model.getKey()); | |
| 73 | - modelRespVO.setCategory(model.getCategory()); | |
| 74 | 69 | modelRespVO.setCreateTime(model.getCreateTime()); |
| 75 | - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); | |
| 76 | - if (metaInfo != null) { | |
| 77 | - modelRespVO.setFormId(metaInfo.getFormId()); | |
| 78 | - modelRespVO.setDescription(metaInfo.getDescription()); | |
| 79 | - } | |
| 70 | + // 通用 copy | |
| 71 | + copyTo(model, modelRespVO); | |
| 80 | 72 | return modelRespVO; |
| 81 | 73 | } |
| 82 | 74 | |
| 75 | + default void copyTo(Model model, BpmModelBaseVO to) { | |
| 76 | + to.setName(model.getName()); | |
| 77 | + to.setKey(model.getKey()); | |
| 78 | + to.setCategory(model.getCategory()); | |
| 79 | + // metaInfo | |
| 80 | + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); | |
| 81 | + copyTo(metaInfo, to); | |
| 82 | + } | |
| 83 | + | |
| 84 | + void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to); | |
| 85 | + | |
| 83 | 86 | default BpmDefinitionCreateReqDTO convert2(Model model) { |
| 84 | 87 | BpmDefinitionCreateReqDTO createReqDTO = new BpmDefinitionCreateReqDTO(); |
| 85 | 88 | createReqDTO.setModelId(model.getId()); | ... | ... |
yudao-admin-ui/src/router/index.js
| ... | ... | @@ -169,7 +169,7 @@ export const constantRoutes = [ |
| 169 | 169 | hidden: true, |
| 170 | 170 | children: [ |
| 171 | 171 | { |
| 172 | - path: 'manager/model/edit', | |
| 172 | + path: 'manager/model/design', | |
| 173 | 173 | component: (resolve) => require(['@/views/bpm/model/modelEditor'], resolve), |
| 174 | 174 | name: '设计流程', |
| 175 | 175 | meta: { title: '设计流程' } | ... | ... |
yudao-admin-ui/src/utils/dict.js
| ... | ... | @@ -36,6 +36,7 @@ export const DICT_TYPE = { |
| 36 | 36 | |
| 37 | 37 | // bpm |
| 38 | 38 | BPM_MODEL_CATEGORY: 'bpm_model_category', |
| 39 | + BPM_MODEL_FORM_TYPE: 'bpm_model_form_type', | |
| 39 | 40 | BPM_PROCESS_INSTANCE_STATUS: 'bpm_process_instance_status', |
| 40 | 41 | BPM_PROCESS_INSTANCE_RESULT: 'bpm_process_instance_result', |
| 41 | 42 | OA_LEAVE_STATUS: 'flow_status', | ... | ... |
yudao-admin-ui/src/views/bpm/model/index.vue
| ... | ... | @@ -26,11 +26,11 @@ |
| 26 | 26 | <el-row :gutter="10" class="mb8"> |
| 27 | 27 | <el-col :span="1.5"> |
| 28 | 28 | <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" |
| 29 | - v-hasPermi="['bpm:model:create']">新建流程模型</el-button> | |
| 29 | + v-hasPermi="['bpm:model:create']">新建流程</el-button> | |
| 30 | 30 | </el-col> |
| 31 | 31 | <el-col :span="1.5"> |
| 32 | 32 | <el-button type="info" icon="el-icon-upload2" size="mini" @click="handleImport" |
| 33 | - v-hasPermi="['bpm:model:import']">导入流程模型</el-button> | |
| 33 | + v-hasPermi="['bpm:model:import']">导入流程</el-button> | |
| 34 | 34 | </el-col> |
| 35 | 35 | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| 36 | 36 | </el-row> |
| ... | ... | @@ -82,9 +82,11 @@ |
| 82 | 82 | </template> |
| 83 | 83 | </el-table-column> |
| 84 | 84 | </el-table-column> |
| 85 | - <el-table-column label="操作" align="center" width="300"> | |
| 85 | + <el-table-column label="操作" align="center" width="380" fixed="right"> | |
| 86 | 86 | <template slot-scope="scope"> |
| 87 | - <el-button size="mini" type="text" icon="el-icon-setting" @click="handleUpdate(scope.row)" | |
| 87 | + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | |
| 88 | + v-hasPermi="['bpm:model:update']">修改流程</el-button> | |
| 89 | + <el-button size="mini" type="text" icon="el-icon-setting" @click="handleDesign(scope.row)" | |
| 88 | 90 | v-hasPermi="['bpm:model:update']">设计流程</el-button> |
| 89 | 91 | <el-button size="mini" type="text" icon="el-icon-thumb" @click="handleDeploy(scope.row)" |
| 90 | 92 | v-hasPermi="['bpm:model:deploy']">发布流程</el-button> |
| ... | ... | @@ -109,21 +111,50 @@ |
| 109 | 111 | <my-process-viewer key="designer" v-model="bpmnXML" v-bind="bpmnControlForm" /> |
| 110 | 112 | </el-dialog> |
| 111 | 113 | |
| 112 | - <!-- 对话框(添加) --> | |
| 113 | - <el-dialog title="新建模型" :visible.sync="open" width="500px" append-to-body> | |
| 114 | - <el-form ref="form" :model="form" :rules="rules" label-width="80px"> | |
| 114 | + <!-- 对话框(添加 / 修改) --> | |
| 115 | + <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> | |
| 116 | + <el-form ref="form" :model="form" :rules="rules" label-width="110px"> | |
| 115 | 117 | <el-form-item label="流程标识" prop="key"> |
| 116 | - <el-input v-model="form.key" placeholder="请输入流标标识" style="width: 350px;" /> | |
| 117 | - <el-tooltip class="item" effect="light" content="新建后,流程标识不可修改!" placement="top"> | |
| 118 | + <el-input v-model="form.key" placeholder="请输入流标标识" style="width: 330px;" :disabled="form.id" /> | |
| 119 | + <el-tooltip v-if="!form.id" class="item" effect="light" content="新建后,流程标识不可修改!" placement="top"> | |
| 120 | + <i style="padding-left: 5px;" class="el-icon-question" /> | |
| 121 | + </el-tooltip> | |
| 122 | + <el-tooltip v-else class="item" effect="light" content="流程标识不可修改!" placement="top"> | |
| 118 | 123 | <i style="padding-left: 5px;" class="el-icon-question" /> |
| 119 | 124 | </el-tooltip> |
| 120 | 125 | </el-form-item> |
| 121 | 126 | <el-form-item label="流程名称" prop="name"> |
| 122 | - <el-input v-model="form.name" placeholder="请输入流程名称" clearable /> | |
| 127 | + <el-input v-model="form.name" placeholder="请输入流程名称" :disabled="form.id" clearable /> | |
| 123 | 128 | </el-form-item> |
| 124 | 129 | <el-form-item label="流程描述" prop="description"> |
| 125 | 130 | <el-input type="textarea" v-model="form.description" clearable /> |
| 126 | 131 | </el-form-item> |
| 132 | + <div v-if="form.id"> | |
| 133 | + <el-form-item label="表单类型" prop="formType"> | |
| 134 | + <el-radio-group v-model="form.formType"> | |
| 135 | + <el-radio v-for="dict in modelFormTypeDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)"> | |
| 136 | + {{dict.label}} | |
| 137 | + </el-radio> | |
| 138 | + </el-radio-group> | |
| 139 | + </el-form-item> | |
| 140 | + <el-form-item v-if="form.formType === 10" label="流程表单" prop="formId" required error="流程表单不能为空"> | |
| 141 | + <el-select v-model="form.formId" clearable style="width: 100%"> | |
| 142 | + <el-option v-for="form in forms" :key="form.id" :label="form.name" :value="form.id"/> | |
| 143 | + </el-select> | |
| 144 | + </el-form-item> | |
| 145 | + <el-form-item v-if="form.formType === 20" label="表单提交路由" prop="formCustomCreatePath" required error="表单提交路由不能为空"> | |
| 146 | + <el-input v-model="form.formCustomCreatePath" placeholder="请输入表单提交路由" style="width: 330px;" /> | |
| 147 | + <el-tooltip class="item" effect="light" content="自定义表单的提交路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/create" placement="top"> | |
| 148 | + <i style="padding-left: 5px;" class="el-icon-question" /> | |
| 149 | + </el-tooltip> | |
| 150 | + </el-form-item> | |
| 151 | + <el-form-item v-if="form.formType === 20" label="表单查看路由" prop="formCustomViewPath" required error="表单查看路由不能为空"> | |
| 152 | + <el-input v-model="form.formCustomViewPath" placeholder="请输入表单查看路由" style="width: 330px;" /> | |
| 153 | + <el-tooltip class="item" effect="light" content="自定义表单的查看路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/view" placement="top"> | |
| 154 | + <i style="padding-left: 5px;" class="el-icon-question" /> | |
| 155 | + </el-tooltip> | |
| 156 | + </el-form-item> | |
| 157 | + </div> | |
| 127 | 158 | </el-form> |
| 128 | 159 | <div slot="footer" class="dialog-footer"> |
| 129 | 160 | <el-button type="primary" @click="submitForm">确 定</el-button> |
| ... | ... | @@ -132,7 +163,7 @@ |
| 132 | 163 | </el-dialog> |
| 133 | 164 | |
| 134 | 165 | <!-- 用户导入对话框 --> |
| 135 | - <el-dialog title="导入流程模型" :visible.sync="upload.open" width="400px" append-to-body> | |
| 166 | + <el-dialog title="导入流程" :visible.sync="upload.open" width="400px" append-to-body> | |
| 136 | 167 | <el-upload ref="upload" :limit="1" accept=".bpmn, .xml" :headers="upload.headers" :action="upload.url" |
| 137 | 168 | :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" |
| 138 | 169 | :auto-upload="false" name="bpmnFile" :data="upload.form" drag> |
| ... | ... | @@ -168,7 +199,15 @@ |
| 168 | 199 | </template> |
| 169 | 200 | |
| 170 | 201 | <script> |
| 171 | -import {deleteModel, deployModel, getModelPage, getModel, updateModelState, createModel} from "@/api/bpm/model"; | |
| 202 | +import { | |
| 203 | + deleteModel, | |
| 204 | + deployModel, | |
| 205 | + getModelPage, | |
| 206 | + getModel, | |
| 207 | + updateModelState, | |
| 208 | + createModel, | |
| 209 | + updateModel | |
| 210 | +} from "@/api/bpm/model"; | |
| 172 | 211 | import {DICT_TYPE, getDictDatas} from "@/utils/dict"; |
| 173 | 212 | import {getForm, getSimpleForms} from "@/api/bpm/form"; |
| 174 | 213 | import {decodeFields} from "@/utils/formGenerator"; |
| ... | ... | @@ -210,12 +249,14 @@ export default { |
| 210 | 249 | }, |
| 211 | 250 | |
| 212 | 251 | // 流程表单 |
| 252 | + title: "", | |
| 213 | 253 | open: false, |
| 214 | 254 | form: {}, |
| 215 | 255 | // 表单校验 |
| 216 | 256 | rules: { |
| 217 | 257 | key: [{ required: true, message: "流程标识不能为空", trigger: "blur" }], |
| 218 | 258 | name: [{ required: true, message: "流程名称不能为空", trigger: "blur" }], |
| 259 | + formType: [{ required: true, message: "流程名称不能为空", trigger: "blur" }], | |
| 219 | 260 | }, |
| 220 | 261 | |
| 221 | 262 | // 流程导入参数 |
| ... | ... | @@ -241,6 +282,7 @@ export default { |
| 241 | 282 | |
| 242 | 283 | // 数据字典 |
| 243 | 284 | categoryDictDatas: getDictDatas(DICT_TYPE.BPM_MODEL_CATEGORY), |
| 285 | + modelFormTypeDictDatas: getDictDatas(DICT_TYPE.BPM_MODEL_FORM_TYPE) | |
| 244 | 286 | }; |
| 245 | 287 | }, |
| 246 | 288 | created() { |
| ... | ... | @@ -269,9 +311,14 @@ export default { |
| 269 | 311 | // 表单重置 |
| 270 | 312 | reset() { |
| 271 | 313 | this.form = { |
| 314 | + id: undefined, | |
| 272 | 315 | key: undefined, |
| 273 | 316 | name: undefined, |
| 274 | - description: undefined | |
| 317 | + description: undefined, | |
| 318 | + formType: undefined, | |
| 319 | + formId: undefined, | |
| 320 | + formCustomCreatePath: undefined, | |
| 321 | + formCustomViewPath: undefined | |
| 275 | 322 | }; |
| 276 | 323 | this.resetForm("form"); |
| 277 | 324 | }, |
| ... | ... | @@ -289,12 +336,25 @@ export default { |
| 289 | 336 | /** 新增按钮操作 */ |
| 290 | 337 | handleAdd() { |
| 291 | 338 | this.reset(); |
| 339 | + this.title = "新建模型"; | |
| 292 | 340 | this.open = true; |
| 293 | 341 | }, |
| 294 | 342 | /** 修改按钮操作 */ |
| 295 | 343 | handleUpdate(row) { |
| 344 | + this.reset(); | |
| 345 | + this.title = "修改模型"; | |
| 346 | + this.open = true; | |
| 347 | + // 设置 form | |
| 348 | + this.form = { | |
| 349 | + ...row | |
| 350 | + }; | |
| 351 | + // 触发一次校验 | |
| 352 | + this.$refs["form"].validate(); | |
| 353 | + }, | |
| 354 | + /** 设计按钮操作 */ | |
| 355 | + handleDesign(row) { | |
| 296 | 356 | this.$router.push({ |
| 297 | - path:"/bpm/manager/model/edit", | |
| 357 | + path:"/bpm/manager/model/design", | |
| 298 | 358 | query:{ |
| 299 | 359 | modelId: row.id |
| 300 | 360 | } |
| ... | ... | @@ -306,8 +366,23 @@ export default { |
| 306 | 366 | if (!valid) { |
| 307 | 367 | return; |
| 308 | 368 | } |
| 369 | + // 更新 | |
| 370 | + if (this.form.id) { | |
| 371 | + updateModel({ | |
| 372 | + ...this.form, | |
| 373 | + formId: this.form.formType === 10 ? this.form.formId : undefined, | |
| 374 | + formCustomCreatePath: this.form.formType === 20 ? this.form.formCustomCreatePath : undefined, | |
| 375 | + formCustomViewPath: this.form.formType === 20 ? this.form.formCustomViewPath : undefined, | |
| 376 | + }).then(response => { | |
| 377 | + this.msgSuccess("修改模型成功"); | |
| 378 | + this.open = false; | |
| 379 | + this.getList(); | |
| 380 | + }); | |
| 381 | + return; | |
| 382 | + } | |
| 383 | + // 创建 | |
| 309 | 384 | createModel(this.form).then(response => { |
| 310 | - this.msgSuccess("新建流程模型成功"); | |
| 385 | + this.msgSuccess("新建流程成功"); | |
| 311 | 386 | this.open = false; |
| 312 | 387 | this.getList(); |
| 313 | 388 | }); |
| ... | ... | @@ -404,7 +479,7 @@ export default { |
| 404 | 479 | // 重置表单 |
| 405 | 480 | this.uploadClose(); |
| 406 | 481 | // 提示,并刷新 |
| 407 | - this.msgSuccess("导入流程模型成功!请点击【设计流程】按钮,进行编辑保存后,才可以进行【发布流程】"); | |
| 482 | + this.msgSuccess("导入流程成功!请点击【设计流程】按钮,进行编辑保存后,才可以进行【发布流程】"); | |
| 408 | 483 | this.getList(); |
| 409 | 484 | }, |
| 410 | 485 | uploadClose() { | ... | ... |