在第二篇改造流程中,对于前端form表单的UI界面和后端流程号的关联,是在前端程序里写死的,如果更新了流程模型,那么就需要重新修改和编译前端程序,过程比较繁琐,故本次将其改善为通过界面实现手动配置
6.1 功能策划
- 在“流程部署” 的版本管理处,新增一个关联按钮,点击后列出所有前端需要关联的UI的id号列表
- 选择一个流程版本后,直接通过上述关联按钮,将流程和前端界面关联
最终效果如下所示:
6.2 新增SQL表
为实现关联功能,在数据库新增一个关联表wf_notice_config,用以关联流程号和前端UI界面:
其中id为自定义的前端UI的id,记录后一次性写死在前端即可;procdef_id是流程模型中对应的版本号和流程id号,后期在界面实现手动点击写入
6.3 生成表对应的后端代码
使用代码生成器,生成上述代码对应的后端代码,其中的关键代码如下:
WfNoticeConfigController:
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/workflow/noticeConfig")
public class WfNoticeConfigController extends BaseController {
private final IWfNoticeConfigService iWfNoticeConfigService;
/**
* 查询用于手动从前端界面设置公共的流程id列表
*/
@SaCheckPermission("workflow:noticeConfig:list")
@GetMapping("/list")
public TableDataInfo<WfNoticeConfigVo> list(WfNoticeConfigBo bo, PageQuery pageQuery) {
return iWfNoticeConfigService.queryPageList(bo, pageQuery);
}
/**
* 修改用于手动从前端界面设置公共的流程id
*/
@SaCheckPermission("workflow:noticeConfig:edit")
@Log(title = "用于手动从前端界面设置公共的流程id", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WfNoticeConfigBo bo) {
return toAjax(iWfNoticeConfigService.updateByBo(bo));
}
....
}
WfNoticeConfigServerImpl:
@RequiredArgsConstructor
@Service
public class WfNoticeConfigServiceImpl implements IWfNoticeConfigService {
private final WfNoticeConfigMapper baseMapper;
/**
* 查询用于手动从前端界面设置公共的流程id
*/
@Override
public WfNoticeConfigVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 修改用于手动从前端界面设置公共的流程id
*/
@Override
public Boolean updateByBo(WfNoticeConfigBo bo) {
WfNoticeConfig update = BeanUtil.toBean(bo, WfNoticeConfig.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
....
}
6.4 前端改造
在api/workflow下增加一个针对新增表查询和修改的路由文件,noticeconfig.js:
import request from '@/utils/request'
// 查询前端UI列表
export function listNoticeConfig(query) {
return request({
url: '/workflow/noticeConfig/list',
method: 'get',
params: query
})
}
// 修改添加procdef的id至UI列表,形成关联
export function addNoticeConfig(data) {
return request({
url: '/workflow/noticeConfig',
method: 'put',
data:data
})
}
之后,重点是针对“流程部署” 页面改造,/views/workfolw下index.vue:
- template的“版本管理”对话框中增加一个关联按钮:
<el-button
type="text"
size="mini"
icon="el-icon-paperclip"
@click="handleUiConfig(scope.row.definitionId)"
v-hasPermi="['workflow:noticeConfig:list']"
>关联UI</el-button>
- 和上述对话框平齐的位置,再新增一个点击按钮后的“关联”对话框:
<el-dialog title="请选择此流程要关联的前端UI:" :visible.sync="noticeConfig.open" width="70%" append-to-body>
<el-table v-loading="noticeConfig.loading" :data="noticeConfig.dataList">
<el-table-column label="UIID" align="center" prop="id" :show-overflow-tooltip="true" />
<el-table-column label="已关联的流程号" align="center" prop="procdefId" :show-overflow-tooltip="true" />
<el-table-column label="描述" align="center" prop="describtion" :show-overflow-tooltip="true" />
<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-paperclip"
@click="handleConnectUi(scope.row.id,scope.row.describtion,noticeConfig.definitionId)"
v-hasPermi="['workflow:noticeConfig:add']"
>点击关联</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="noticeConfigTotal > 0"
:total="noticeConfigTotal"
:page.sync="noticeConfigQueryParams.pageNum"
:limit.sync="noticeConfigQueryParams.pageSize"
@pagination="getNoticeConfigList"
/>
</el-dialog>
- 在script部分中导入新增的api两方法:
import { listNoticeConfig, addNoticeConfig} from '@/api/workflow/noticeconfig'
- data中新增相关变量的声明:
data() {
return {
...
//新增关联表的列表数据、对话框显示和流程id号
noticeConfig:{
open: false,
loading: false,
dataList: [],
definitionId:""
},
//以下用以列表数据请求和分页
noticeConfigTotal: 0,
noticeConfigQueryParams: {
pageNum: 1,
pageSize: 10,
},
}
}
- methods中新增对应的关联方法:
//获取新增关联表的列表数据的方法
getNoticeConfigList() {
this.noticeConfig.loading = true;
listNoticeConfig(this.noticeConfigQueryParams).then(response => {
this.noticeConfig.dataList = response.rows;
this.noticeConfigTotal = response.total;
this.noticeConfig.loading = false;
})
//console.log(this.noticeConfig);
},
//处理关联按钮的动作,其中definitionId是用来传递流程id号
handleUiConfig(definitionId) {
this.noticeConfig.open = true;
this.getNoticeConfigList();
this.noticeConfig.definitionId = definitionId;
},
//把流程号和对应的前端UI关联的核心方法
handleConnectUi(id,describtion,definitionId){
this.$modal.confirm('是否确认要和' + id + "关联?").then(() => {
this.loading = true;
var data = {
id:id,
describtion:describtion,
procdefId:definitionId
};
return addNoticeConfig(data);
}).then(() => {
this.loading = false;
this.getNoticeConfigList();
this.$modal.msgSuccess("关联成功");
}).finally(() => {
this.loading = false;
});
}
最后还需要修改前端新建公告时,对应的常量设置和新的请求方法(通过上述修改,已经把每次需要在文件中配置流程号,改为固定一个配置的id对应新增表的id,前端通过直接发送这个写死的id即可从后端拿到数据,故需修改新建公告中的配置常量和路由)
在views/system/notice/config中修改为如下(一次性写死,后期不用再次调整了):
export const UIId = "45612378920240325";
create.vue中相应的修改一下import和对应的请求方法:
import { UIId } from './config'
handleStart(row){
// 此处修改为导入的UIId
startProcess(UIId, JSON.stringify(row)).then(res => {
this.$modal.msgSuccess(res.msg);
this.getList();
})
},
6.5 新的前后端路由方法
后端新写一个直接用UIId号查找到流程号再发起流程的新路由方法,在WfProcessController中新增:
/**
* 根据流程定义id启动流程实例
*
* @param uiid ui表对应的id号
* @param variables 变量集合,json对象
*/
@SaCheckPermission("workflow:process:start")
@PostMapping("/startbyuiid/{uiid}")
public R<Void> startbyuiid(@PathVariable(value = "uiid") String uiid, @RequestBody Map<String, Object> variables) {
WfNoticeConfigVo wfNoticeConfigVo = noticeConfigService.queryById(Long.valueOf(uiid));
String processDefId = wfNoticeConfigVo.getProcdefId();
if (StringUtils.isNotBlank(processDefId)){
processService.startProcessByDefId(processDefId, variables);
return R.ok("流程启动成功");
} else {
return R.fail("流程启动失败,未关联流程id和uiid,请到流程部署中关联");
}
}
前端对应的create.vue的路由process.js中修改:
// 部署流程实例
export function startProcess(uiid, data) {
return request({
//以下接口路径修改为后端新增的路由方法
url: '/workflow/process/startbyuiid/' + uiid,
method: 'post',
data: data
})
}
大功告成!
6.6 过程避坑
- 前后端路由中路径必须保证一致,尤其区分大小写,需格外注意
- 新增的SQL表为避免过多的额外设置,最好都仿照正式表加上creat_by等相关的四个字段
- SQL字段起名时,一开始就要避免用到desc等语法关键字,运行过程中报错需反复修改