目录
一、审批流程
二、审批类型代码实现
三、审批模板实现
一、审批流程
数据库表:
CREATE TABLE `oa_process_type` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '类型名称', `description` VARCHAR(255) DEFAULT NULL COMMENT '描述', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `is_deleted` TINYINT(3) NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)', PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='审批类型'; SELECT * FROM oa_process_type; CREATE TABLE `oa_process_template` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '角色id', `name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '模板名称', `icon_url` VARCHAR(100) DEFAULT NULL COMMENT '图标路径', `process_type_id` VARCHAR(255) DEFAULT NULL, `form_props` TEXT COMMENT '表单属性', `form_options` TEXT COMMENT '表单选项', `process_definition_key` VARCHAR(20) DEFAULT NULL COMMENT '流程定义key', `process_definition_path` VARCHAR(255) DEFAULT NULL COMMENT '流程定义上传路径', `process_model_id` VARCHAR(255) DEFAULT NULL COMMENT '流程定义模型id', `description` VARCHAR(255) DEFAULT NULL COMMENT '描述', `status` TINYINT(3) NOT NULL DEFAULT '0', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `is_deleted` TINYINT(3) NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)', PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='审批模板'; SELECT * FROM oa_process_template; CREATE TABLE `oa_process` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `process_code` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '审批code', `user_id` BIGINT(1) NOT NULL DEFAULT '0' COMMENT '用户id', `process_template_id` BIGINT(20) DEFAULT NULL COMMENT '审批模板id', `process_type_id` BIGINT(20) DEFAULT NULL COMMENT '审批类型id', `title` VARCHAR(255) DEFAULT NULL COMMENT '标题', `description` VARCHAR(255) DEFAULT NULL COMMENT '描述', `form_values` TEXT COMMENT '表单值', `process_instance_id` VARCHAR(255) DEFAULT NULL COMMENT '流程实例id', `current_auditor` VARCHAR(255) DEFAULT NULL COMMENT '当前审批人', `status` TINYINT(3) DEFAULT NULL COMMENT '状态(0:默认 1:审批中 2:审批通过 -1:驳回)', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `is_deleted` TINYINT(3) NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)', PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='审批类型'; CREATE TABLE `oa_process_record` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `process_id` BIGINT(20) NOT NULL DEFAULT '0' COMMENT '审批流程id', `description` VARCHAR(255) DEFAULT NULL COMMENT '审批描述', `status` TINYINT(3) DEFAULT '0' COMMENT '状态', `operate_user_id` BIGINT(20) NOT NULL DEFAULT '0' COMMENT '操作用户id', `operate_user` VARCHAR(20) DEFAULT NULL COMMENT '操作用户', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `is_deleted` TINYINT(3) NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)', PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='审批记录';
二、审批类型代码实现
后端代码:
@Api(tags = "审批类型")
@RestController
@RequestMapping("/admin/process/processType")
public class OaProcessTypeController {
@Autowired
private OaProcessTypeService processTypeService;
@ApiOperation("分页查询")
@GetMapping("/pageProcessType/{page}/{limit}")
public Result pageProcessType(@PathVariable("page") Long page,
@PathVariable("limit") Long limit){
Page<ProcessType> typePage = new Page<>(page,limit);
return Result.ok(processTypeService.page(typePage));
}
@ApiOperation("根据id查询")
@GetMapping("/getById/{id}")
public Result getById(@PathVariable("id") Long id){
return Result.ok(processTypeService.getById(id));
}
@ApiOperation("添加")
@PostMapping("/add")
public Result add(@RequestBody ProcessType processType){
processTypeService.save(processType);
return Result.ok();
}
@ApiOperation("修改")
@PutMapping("/update")
public Result update(@RequestBody ProcessType processType){
processTypeService.updateById(processType);
return Result.ok();
}
@ApiOperation("删除")
@DeleteMapping("/delete/{id}")
public Result delete(@PathVariable("id") Long id){
processTypeService.removeById(id);
return Result.ok();
}
}
前端代码:
创建src/api/process/processType.js
import request from '@/utils/request'
const api_name = '/admin/process/processType'
export default {
getPageList(page, limit) {
return request({
url: `${api_name}/pageProcessType/${page}/${limit}`,
method: 'get'
})
},
getById(id) {
return request({
url: `${api_name}/getById/${id}`,
method: 'get'
})
},
save(role) {
return request({
url: `${api_name}/add`,
method: 'post',
data: role
})
},
updateById(role) {
return request({
url: `${api_name}/update`,
method: 'put',
data: role
})
},
removeById(id) {
return request({
url: `${api_name}/delete/${id}`,
method: 'delete'
})
}
}
创建views/processSet/processType/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.processType.add') === false">添 加</el-button>
</div>
<!-- banner列表 -->
<el-table
v-loading="listLoading"
:data="list"
stripe
border
style="width: 100%;margin-top: 10px;"
>
<el-table-column
type="selection"
width="55"
/>
<el-table-column
label="序号"
width="70"
align="center"
>
<template slot-scope="scope">
{{ (page - 1) * limit + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="name" label="类型名称"/>
<el-table-column prop="description" label="描述"/>
<el-table-column prop="createTime" label="创建时间"/>
<el-table-column prop="updateTime" label="更新时间"/>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="edit(scope.row.id)" :disabled="$hasBP('bnt.processType.update') === false">修改</el-button>
<el-button type="text" size="mini" @click="removeDataById(scope.row.id)" :disabled="$hasBP('bnt.processType.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"
/>
<el-dialog title="添加/修改" :visible.sync="dialogVisible" width="40%">
<el-form ref="flashPromotionForm" label-width="150px" size="small" style="padding-right: 40px;">
<el-form-item label="类型名称">
<el-input v-model="processType.name"/>
</el-form-item>
<el-form-item label="描述">
<el-input v-model="processType.description"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false" size="small">取 消</el-button>
<el-button type="primary" @click="saveOrUpdate()" size="small">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import api from '@/api/process/processType'
const defaultForm = {
id: '',
name: '',
description: ''
}
export default {
data() {
return {
listLoading: true, // 数据是否正在加载
list: null, // banner列表
total: 0, // 数据库中的总记录数
page: 1, // 默认页码
limit: 10, // 每页记录数
searchObj: {}, // 查询表单对象
dialogVisible: false,
processType: defaultForm,
saveBtnDisabled: false
}
},
// 生命周期函数:内存准备完毕,页面尚未渲染
created() {
this.fetchData()
},
// 生命周期函数:内存准备完毕,页面渲染成功
mounted() {
},
methods: {
// 当页码发生改变的时候
changeSize(size) {
console.log(size)
this.limit = size
this.fetchData(1)
},
// 加载列表数据
fetchData(page = 1) {
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() {
console.log('重置查询表单')
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.dialogVisible = true
this.processType = Object.assign({}, defaultForm)
},
edit(id) {
this.dialogVisible = true
this.fetchDataById(id)
},
fetchDataById(id) {
api.getById(id).then(response => {
this.processType = response.data
})
},
saveOrUpdate() {
this.saveBtnDisabled = true // 防止表单重复提交
if (!this.processType.id) {
this.saveData()
} else {
this.updateData()
}
},
// 新增
saveData() {
api.save(this.processType).then(response => {
this.$message.success(response.message || '操作成功')
this.dialogVisible = false
this.fetchData(this.page)
})
},
// 根据id更新记录
updateData() {
api.updateById(this.processType).then(response => {
this.$message.success(response.message || '操作成功')
this.dialogVisible = false
this.fetchData(this.page)
})
}
}
}
</script>
三、审批模板实现
分页查询审批模板:
@Autowired
private OaProcessTypeService processTypeService;
//分页查询
@Override
public IPage<ProcessTemplate> selectPageProcessTem(Page<ProcessTemplate> templatePage) {
//调用mapper方法实现分页查询
Page<ProcessTemplate> processTemplatePage = baseMapper.selectPage(templatePage, null);
//从分页数据中拿到list集合
List<ProcessTemplate> records = processTemplatePage.getRecords();
//从集合中获取审批类型id
for (ProcessTemplate processTemplate:records) {
//根据list集合id查询
LambdaQueryWrapper<ProcessType> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProcessType::getId,processTemplate.getProcessTypeId());
ProcessType processType = processTypeService.getOne(wrapper);
if (processType == null){
continue;
}
//封装数据
processTemplate.setProcessTypeName(processType.getName());
}
return processTemplatePage;
}@ApiOperation("分页查询")
@GetMapping("/pageQuery/{page}/{limit}")
public Result pageQuery(@PathVariable("page") Long page,
@PathVariable("limit") Long limit){
Page<ProcessTemplate> templatePage = new Page<>(page,limit);
return Result.ok(processTemplateService.selectPageProcessTem(templatePage));
}
@ApiOperation(value = "新增")
@PostMapping("save")
public Result save(@RequestBody ProcessTemplate processTemplate) {
processTemplateService.save(processTemplate);
return Result.ok();
}
@ApiOperation(value = "修改")
@PutMapping("update")
public Result updateById(@RequestBody ProcessTemplate processTemplate) {
processTemplateService.updateById(processTemplate);
return Result.ok();
}
@ApiOperation(value = "删除")
@DeleteMapping("remove/{id}")
public Result remove(@PathVariable Long id) {
processTemplateService.removeById(id);
return Result.ok();
}
添加审批模板:
💕、查询所有审批类型
@ApiOperation("查询所有审批分类")
@GetMapping("/findAll")
public Result findAll(){
List<ProcessType> list = processTypeService.list();
return Result.ok(list);
}@ApiOperation("上传流程定义")
@PostMapping("/unloadProcessDefinition")
public Result unloadProcessDefinition(MultipartFile multipartFile) throws IOException {
//获取目录位置
String path = new File(ResourceUtils.getURL("calsspath:").getPath()).getAbsolutePath();
//设置上传文件夹
File file = new File(path + "/processes/");
if (!file.exists()){
file.mkdirs();
}
//创建空文件,实现文件上传
String fileName = multipartFile.getOriginalFilename();
File zipFine = new File(path + "/processes/" + fileName);
//报存文件
try {
multipartFile.transferTo(zipFine);
} catch (IOException e) {
throw new CJCException(209,"文件报存失败");
}
Map<String, Object> map = new HashMap<>();
//根据上传地址后续部署流程定义,文件名称为流程定义的默认key
map.put("processDefinitionPath", "processes/" + fileName);
map.put("processDefinitionKey", fileName.substring(0, fileName.lastIndexOf(".")));
return Result.ok(map);
}
部署流程发布:
@Override
public void publish(Long id) {
ProcessTemplate processTemplate = baseMapper.selectById(id);
processTemplate.setStatus(1);
baseMapper.updateById(processTemplate);
}@ApiOperation("部署流程发布")
@GetMapping("/publish/{id}")
public Result publish(@PathVariable("id") Long id){
//修改模板发布状态 1:已发布
processTemplateService.publish(id);
return Result.ok();
}