1、列表页面
1.1、动态添加路由
在“系统管理”->“菜单管理”添加“审批设置”->“审批类型”
对于菜单信息,我们也可以直接导入菜单表初始化数据,后续不用再单独配置
说明:“审批模板设置”页面内容较多,因此单独打开一个独立页面
1.3、列表页面
创建views/processSet/processTemplate/list.vue
<template>
<div class="app-container">
<!-- 工具条 -->
<div class="tools-div">
<el-button type="success" icon="el-icon-plus" size="mini" @click="add()" :disabled="$hasBP('bnt.processTemplate.templateSet') === false">添加审批设置</el-button>
</div>
<!-- 列表 -->
<el-table
v-loading="listLoading"
:data="list"
stripe
border
style="width: 100%;margin-top: 10px;"
>
<el-table-column
label="序号"
width="70"
align="center"
>
<template slot-scope="scope">
{{ (page - 1) * limit + scope.$index + 1 }}
</template>
</el-table-column>iconPath
<el-table-column prop="name" label="审批名称"/>
<el-table-column label="图标">
<template slot-scope="scope">
<img :src="scope.row.iconUrl" style="width: 30px;height: 30px;vertical-align: text-bottom;">
</template>
</el-table-column>
<el-table-column prop="processTypeName" label="审批类型"/>
<el-table-column prop="description" label="描述"/>
<el-table-column prop="createTime" label="创建时间"/>
<el-table-column prop="updateTime" label="更新时间"/>
<el-table-column label="操作" width="250" align="center">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="edit(scope.row.id)" :disabled="$hasBP('bnt.processTemplate.templateSet') === false">修改审批设置</el-button>
<el-button type="text" size="mini" @click="removeDataById(scope.row.id)" :disabled="$hasBP('bnt.processTemplate.remove') === false">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
:current-page="page"
:total="total"
:page-size="limit"
:page-sizes="[5, 10, 20, 30, 40, 50, 100]"
style="padding: 30px 0; text-align: center;"
layout="sizes, prev, pager, next, jumper, ->, total, slot"
@current-change="fetchData"
@size-change="changeSize"
/>
</div>
</template>
<script>
import api from '@/api/process/processTemplate'
export default {
data() {
return {
listLoading: true, // 数据是否正在加载
list: null, // banner列表
total: 0, // 数据库中的总记录数
page: 1, // 默认页码
limit: 10, // 每页记录数
searchObj: {} // 查询表单对象
}
},
// 生命周期函数:内存准备完毕,页面尚未渲染
created() {
this.fetchData()
},
// 生命周期函数:内存准备完毕,页面渲染成功
mounted() {
},
methods: {
// 当页码发生改变的时候
changeSize(size) {
this.limit = size
this.fetchData(1)
},
// 加载banner列表数据
fetchData(page = 1) {
// 异步获取远程数据(ajax)
this.page = page
api.getPageList(this.page, this.limit, this.searchObj).then(
response => {
this.list = response.data.records
this.total = response.data.total
// 数据加载并绑定成功
this.listLoading = false
}
)
},
// 重置查询表单
resetData() {
this.searchObj = {}
this.fetchData()
},
// 根据id删除数据
removeDataById(id) {
this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => { // promise
// 点击确定,远程调用ajax
return api.removeById(id)
}).then((response) => {
this.fetchData(this.page)
this.$message.success(response.message)
}).catch(() => {
this.$message.info('取消删除')
})
},
add() {
this.$router.push('/processSet/templateSet')
},
edit(id) {
this.$router.push('/processSet/templateSet?id=' + id)
}
}
}
</script>
2、添加审批模板
![OA系统添加审批模板 OA系统添加审批模板](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuL2ltZ19jb252ZXJ0L2E1ZTI5ZDZmOGJjNDAyOGE1NmNhYzhmYzQyZTk1YjAwLnBuZw%3D%3D.png?w=700&webp=1)
1、基本设置:一些基本信息
2、表单设置:动态表单
3、流程设置:本地设计流程定义,上传流程定义文件及流程定义图片(压缩上传)
涉及未实现接口:
1、获取全部审批分类
2、上传流程定义压缩文件
2.1、form-create
官网:http://www.form-create.com/v2/guide/
轻松搞定 form 表单,让你不再为表单而烦恼。
form-create 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成组件。
form-create-designer 是基于 form-create实现的表单设计器组件。可以通过拖拽的方式快速创建表单,提高开发者对表单的开发效率,节省开发者的时间
表单设计器:
http://www.form-create.com/designer/?fr=home
![OA系统添加审批模板 OA系统添加审批模板](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuL2ltZ19jb252ZXJ0Lzg2NDVlNTA4MGViYWIwMzMwYTY4NmI5ZjA3YzhiNjk1LnBuZw%3D%3D.png?w=700&webp=1)
可以通过拖拽的方式快速配置动态表单,配置好的动态表单可以通过:生成JSON与生成Options获取数据,这两数据对于表字段:form_props与form_options,后续我们通过这两字段渲染动态表单。
大家可以根据表单设计器,查看数据格式
2.2、集成form-create
1、添加依赖
在package.json文件添加依赖,注意版本号,更高的版本号可能与本项目不兼容
"@form-create/element-ui": "^2.5.17",
"@form-create/designer": "^1.0.8",
2、在 main.js 中写入以下内容:
importformCreatefrom'@form-create/element-ui'
importFcDesignerfrom'@form-create/designer'
Vue.use(formCreate)
Vue.use(FcDesigner)
3、集成表单设计器
创建views/processSet/processTemplate/templateSet.vue
<template>
<divclass="app-container">
<divid="app1">
<fc-designerclass="form-build"ref="designer"/>
<el-button@click="save">获取数据</el-button>
</div>
</div>
</template>
<script>
exportdefault {
data() {
return {
}
},
created() {
},
methods: {
save() {
console.log(this.$refs.designer.getRule())
console.log(this.$refs.designer.getOption())
}
}
}
</script>
显示效果:
![OA系统添加审批模板 OA系统添加审批模板](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuL2ltZ19jb252ZXJ0LzQzOTU4MjMxNWZhMDdlZDViNjI3NTJmZjMxMmQwN2JiLnBuZw%3D%3D.png?w=700&webp=1)
随便拉几个表单项,点击“获取数据”,就是我们需要的动态表单数据格式了。
2.3、获取全部审批分类接口
1、在ProcessTypeController类添加接口
@ApiOperation(value="获取全部审批分类")
@GetMapping("findAll")
publicResultfindAll() {
returnResult.ok(processTypeService.list());
}
2、在processType.js添加前端接口
findAll() {
returnrequest({
url: `${api_name}/findAll`,
method: 'get'
})
}
2.4、上传流程定义接口
在ProcessTemplateController类添加接口
@PreAuthorize("hasAuthority('bnt.processTemplate.templateSet')")
@ApiOperation(value="上传流程定义")
@PostMapping("/uploadProcessDefinition")
publicResultuploadProcessDefinition(MultipartFilefile) throwsFileNotFoundException {
Stringpath=newFile(ResourceUtils.getURL("classpath:").getPath()).getAbsolutePath();
StringfileName=file.getOriginalFilename();
// 上传目录
FiletempFile=newFile(path+"/processes/");
// 判断目录是否存着
if (!tempFile.exists()) {
tempFile.mkdirs();//创建目录
}
// 创建空文件用于写入文件
FileimageFile=newFile(path+"/processes/"+fileName);
// 保存文件流到本地
try {
file.transferTo(imageFile);
} catch (IOExceptione) {
e.printStackTrace();
returnResult.fail("上传失败");
}
Map<String, Object>map=newHashMap<>();
//根据上传地址后续部署流程定义,文件名称为流程定义的默认key
map.put("processDefinitionPath", "processes/"+fileName);
map.put("processDefinitionKey", fileName.substring(0, fileName.lastIndexOf(".")));
returnResult.ok(map);
}
2.5、模板设置完整代码
<template>
<divclass="app-container">
<el-steps:active="stepIndex"finish-status="success">
<el-steptitle="基本设置"></el-step>
<el-steptitle="表单设置"></el-step>
<el-steptitle="流程设置"></el-step>
</el-steps>
<divclass="tools-div">
<el-buttonv-if="stepIndex > 1"icon="el-icon-check"type="primary"size="small"@click="pre()"round>上一步
</el-button>
<el-buttonicon="el-icon-check"type="primary"size="small"@click="next()"round>{{
stepIndex == 3 ? '提交保存' : '下一步'
}}
</el-button>
<el-buttontype="primary"size="small"@click="back()">返回</el-button>
</div>
<!-- 第一步 -->
<divv-show="stepIndex == 1"style="margin-top: 20px;">
<el-formref="flashPromotionForm"label-width="150px"size="small"style="padding-right: 40px;">
<el-form-itemlabel="审批类型">
<el-selectv-model="processTemplate.processTypeId"placeholder="请选择审批类型">
<el-optionv-for="item in processTypeList":label="item.name":value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-itemlabel="审批名称">
<el-inputv-model="processTemplate.name"/>
</el-form-item>
<el-form-itemlabel="审批图标">
<el-selectv-model="processTemplate.iconUrl"placeholder="请选择审批图标">
<el-optionv-for="item in iconUrlList":label="item.iconUrl":value="item.iconUrl">
<img:src="item.iconUrl"style="width: 30px;height: 30px;vertical-align: text-bottom;">
</el-option>
</el-select>
</el-form-item>
<el-form-itemlabel="描述">
<el-inputv-model="processTemplate.description"/>
</el-form-item>
</el-form>
</div>
<!-- 第二步 -->
<divv-show="stepIndex == 2"style="margin-top: 20px;">
<!--表单构建器-->
<fc-designerclass="form-build"ref="designer"/>
</div>
<!-- 第三步 -->
<divv-show="stepIndex == 3"style="margin-top: 20px;">
<el-upload
class="upload-demo"
drag
action="/dev-api/admin/process/processTemplate/uploadProcessDefinition"
:headers="uploadHeaders"
multiple="false"
:before-upload="beforeUpload"
:on-success="onUploadSuccess"
:file-list="fileList"
>
<iclass="el-icon-upload"></i>
<divclass="el-upload__text">将Activiti流程设计文件拖到此处,或<em>点击上传</em></div>
<divclass="el-upload__tip"slot="tip">只能上传zip压缩文件,且不超过2048kb</div>
</el-upload>
</div>
</div>
</template>
<script>
importapifrom'@/api/process/processTemplate'
importprocessTypeApifrom'@/api/process/processType'
importstorefrom'@/store'
constdefaultForm= {
id: '',
name: '',
iconUrl: '',
formProps: '',
formOptions: '',
processDefinitionKey: '',
processDefinitionPath: '',
description: ''
}
exportdefault {
data() {
return {
stepIndex: 1,
processTypeList: [],
processTemplate: defaultForm,
iconUrlList: [
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1t695CFYqK1RjSZLeXXbXppXa-102-102.png', tag: '请假' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1bHOWCSzqK1RjSZFjXXblCFXa-112-112.png', tag: '出差' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1cbCYCPTpK1RjSZKPXXa3UpXa-112-112.png', tag: '机票出差' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1cbCYCPTpK1RjSZKPXXa3UpXa-112-112.png', tag: '机票改签' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1e76lCOLaK1RjSZFxXXamPFXa-112-112.png', tag: '外出' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1Yfa0CG6qK1RjSZFmXXX0PFXa-112-112.png', tag: '补卡申请' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1Y8PlCNjaK1RjSZKzXXXVwXXa-112-112.png', tag: '加班' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB11X99CNTpK1RjSZFKXXa2wXXa-102-102.png', tag: '居家隔离' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1_YG.COrpK1RjSZFhXXXSdXXa-102-102.png', tag: '请假' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB13ca1CMDqK1RjSZSyXXaxEVXa-102-102.png', tag: '调岗' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1U9iBCSzqK1RjSZPcXXbTepXa-102-102.png', tag: '离职' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB11pS_CFzqK1RjSZSgXXcpAVXa-102-102.png', tag: '费用申请' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1t695CFYqK1RjSZLeXXbXppXa-102-102.png', tag: '用章申请' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB13f_aCQzoK1RjSZFlXXai4VXa-102-102.png', tag: '携章外出' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1_YG.COrpK1RjSZFhXXXSdXXa-102-102.png', tag: '学期内分期' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1_YG.COrpK1RjSZFhXXXSdXXa-102-102.png', tag: '特殊学费' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1Yfa0CG6qK1RjSZFmXXX0PFXa-112-112.png', tag: '充值卡申领' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1e76lCOLaK1RjSZFxXXamPFXa-112-112.png', tag: '礼品申领' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1FNG.CMHqK1RjSZFgXXa7JXXa-102-102.png', tag: '邮寄快递申请' },
{ iconUrl: 'https://gw.alicdn.com/imgextra/i3/O1CN01LLn0YV1LhBXs7T2iO_!!6000000001330-2-tps-120-120.png', tag: '合同审批' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1e76lCOLaK1RjSZFxXXamPFXa-112-112.png', tag: '合同借阅' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1e76lCOLaK1RjSZFxXXamPFXa-112-112.png', tag: '魔点临时开门权限' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1bHOWCSzqK1RjSZFjXXblCFXa-112-112.png', tag: '北京科技园车证审批' },
{ iconUrl: 'https://gw.alicdn.com/tfs/TB1e76lCOLaK1RjSZFxXXamPFXa-112-112.png', tag: '魔点访客提前预约审批' }
],
uploadHeaders: {
'token': store.getters.token
},
fileList: []
}
},
created() {
letid=this.$route.query.id
console.log(id)
if (id>0) {
this.fetchDataById(id)
}
this.fetchProcessTypeData()
},
methods: {
pre() {
this.stepIndex-=1
},
next() {
if (this.stepIndex===2) {
this.processTemplate.formProps=JSON.stringify(this.$refs.designer.getRule())
this.processTemplate.formOptions=JSON.stringify(this.$refs.designer.getOption())
console.log(JSON.stringify(this.processTemplate))
}
if (this.stepIndex===3) {
this.saveOrUpdate()
}
this.stepIndex+=1
},
fetchProcessTypeData() {
processTypeApi.findAll().then(response=> {
this.processTypeList=response.data
})
},
fetchDataById(id) {
api.getById(id).then(response=> {
this.processTemplate=response.data
// 给表单设计器赋值
this.$refs.designer.setRule(JSON.parse(this.processTemplate.formProps))
this.$refs.designer.setOption(JSON.parse(this.processTemplate.formOptions))
this.fileList= [{
name: this.processTemplate.processDefinitionPath,
url: this.processTemplate.processDefinitionPath
}]
})
},
saveOrUpdate() {
this.saveBtnDisabled=true// 防止表单重复提交
if (!this.processTemplate.id) {
this.saveData()
} else {
this.updateData()
}
},
// 新增
saveData() {
api.save(this.processTemplate).then(response=> {
this.$router.push('/processSet/processTemplate')
})
},
// 根据id更新记录
updateData() {
api.updateById(this.processTemplate).then(response=> {
this.$router.push('/processSet/processTemplate')
})
},
// 文件上传限制条件
beforeUpload(file) {
constisZip=file.type==='application/x-zip-compressed'
constisLt2M=file.size/1024/1024<2
if (!isZip) {
this.$message.error('文件格式不正确!')
returnfalse
}
if (!isLt2M) {
this.$message.error('上传大小不能超过 2MB!')
returnfalse
}
returntrue
},
// 上传成功的回调
onUploadSuccess(res, file) {
// 填充上传文件列表
this.processTemplate.processDefinitionPath=res.data.processDefinitionPath
this.processTemplate.processDefinitionKey=res.data.processDefinitionKey
},
back() {
this.$router.push('/processSet/processTemplate')
}
}
}
</script>
3、查看审批模板
查看审批模板基本信息、动态表单信息
3.1、添加按钮
<el-buttontype="text"size="mini"@click="show(scope.row)">查看审批设置</el-button>
3.2、定义data
rule: [],
option: {},
processTemplate: {},
formDialogVisible: false
3.3、定义方法
show(row) {
this.rule=JSON.parse(row.formProps)
this.option=JSON.parse(row.formOptions)
this.processTemplate=row
this.formDialogVisible=true
}
3.4、定义弹出层
<e<el-dialogtitle="查看审批设置":visible.sync="formDialogVisible"width="35%">
<h3>基本信息</h3>
<el-divider/>
<el-formref="flashPromotionForm"label-width="150px"size="small"style="padding-right: 40px;">
<el-form-itemlabel="审批类型"style="margin-bottom: 0px;">{{ processTemplate.processTypeName }}</el-form-item>
<el-form-itemlabel="名称"style="margin-bottom: 0px;">{{ processTemplate.name }}</el-form-item>
<el-form-itemlabel="创建时间"style="margin-bottom: 0px;">{{ processTemplate.createTime }}</el-form-item>
</el-form>
<h3>表单信息</h3>
<el-divider/>
<div>
<form-create
:rule="rule"
:option="option"
></form-create>
</div>
<spanslot="footer"class="dialog-footer">
<el-button@click="formDialogVisible = false"size="small">取 消</el-button>
</span>
</el-dialog>