一、审批管理
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='审批记录';
后端代码:
mapper层
@Mapper public interface OaProcessMapper extends BaseMapper<Process> { IPage<ProcessVo> selectPage(Page<ProcessVo> processPage,@Param("vo") ProcessQueryVo processQueryVo); }
mapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cjc.process.mapper.OaProcessMapper"> <select id="selectPage" resultType="com.cjc.vo.process.ProcessVo"> SELECT a.id,a.process_code,a.user_id,a.process_template_id,a.process_type_id,a.title,a.description,a.form_values,a.process_instance_id,a.current_auditor,a.status,a.create_time,a.update_time, b.name AS processTemplateName, c.name AS processTypeName, d.name FROM oa_process a LEFT JOIN sys_user d ON a.user_id = d.id LEFT JOIN oa_process_template b ON a.process_template_id = b.id LEFT JOIN oa_process_type c ON a.process_type_id = c.id <where> <if test="vo.keyword != null and vo.keyword != ''"> and (a.process_code like CONCAT('%',#{vo.keyword},'%') or a.title like CONCAT('%',#{vo.keyword},'%') or d.phone like CONCAT('%',#{vo.keyword},'%') or d.name like CONCAT('%',#{vo.keyword},'%')) </if> <if test="vo.userId != null and vo.userId != ''"> and a.user_id = #{vo.userId} </if> <if test="vo.status != null and vo.status != ''"> and a.status = #{vo.status} </if> <if test="vo.createTimeBegin != null and vo.createTimeBegin != ''"> and a.create_time >= #{vo.createTimeBegin} </if> <if test="vo.createTimeEnd != null and vo.createTimeEnd != ''"> and a.create_time <= #{vo.createTimeEnd} </if> </where> </select> </mapper>
service层
public interface OaProcessService extends IService<Process> { IPage<ProcessVo> selectPage(Page<ProcessVo> processPage, ProcessQueryVo processQueryVo); }
serviceImpl层
@Service public class OaProcessServiceImpl extends ServiceImpl<OaProcessMapper, Process> implements OaProcessService { @Override public IPage<ProcessVo> selectPage(Page<ProcessVo> processPage, ProcessQueryVo processQueryVo) { IPage<ProcessVo> processVoIPage = baseMapper.selectPage(processPage, processQueryVo); return processVoIPage; } }
controller层
@Api(tags = "审批管理") @RestController @RequestMapping("/admin/process") public class OaProcessController { @Autowired private OaProcessService processService; @ApiOperation("分页查询") @GetMapping("/pageQuery/{page}/{limit}") public Result pageQuery(@PathVariable Long page, @PathVariable Long limit, ProcessQueryVo processQueryVo){ Page<ProcessVo> processPage = new Page<>(); IPage<ProcessVo> model = processService.selectPage(processPage, processQueryVo); return Result.ok(model); } }
前端代码:
创建src/api/process/process.js
import request from '@/utils/request' const api_name = '/admin/process' export default { getPageList(page, limit, searchObj) { return request({ url: `${api_name}/pageQuery/${page}/${limit}`, method: 'get', params: searchObj // url查询字符串或表单键值对 }) } }
创建views/processMgr/process/list.vue
<template> <div class="app-container"> <div class="search-div"> <el-form label-width="70px" size="small"> <el-row> <el-col :span="8"> <el-form-item label="关 键 字"> <el-input style="width: 95%" v-model="searchObj.keyword" placeholder="审批编号/标题/手机号码/姓名"></el-input> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="状态"> <el-select v-model="searchObj.status" placeholder="请选状态" style="width: 100%;" > <el-option v-for="item in statusList" :key="item.status" :label="item.name" :value="item.status" /> </el-select> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="操作时间"> <el-date-picker v-model="createTimes" type="datetimerange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" value-format="yyyy-MM-dd HH:mm:ss" style="margin-right: 10px;width: 100%;" /> </el-form-item> </el-col> </el-row> <el-row style="display:flex"> <el-button type="primary" icon="el-icon-search" size="mini" :loading="loading" @click="fetchData()">搜索 </el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetData">重置</el-button> </el-row> </el-form> </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> <el-table-column prop="processCode" label="审批编号" width="130"/> <el-table-column prop="title" label="标题" width="180"/> <el-table-column prop="name" label="用户"/> <el-table-column prop="processTypeName" label="审批类型"/> <el-table-column prop="processTemplateName" label="审批模板"/> <el-table-column prop="description" label="描述" width="180"/> <el-table-column label="状态"> <template slot-scope="scope"> {{ scope.row.status === 1 ? '审批中' : scope.row.status === 2 ? '完成' : '驳回' }} </template> </el-table-column> <el-table-column prop="createTime" label="创建时间" width="160"/> <el-table-column label="操作" width="120" align="center"> <template slot-scope="scope"> <el-button type="text" size="mini" @click="show(scope.row.id)">查看</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/process' export default { data() { return { listLoading: true, // 数据是否正在加载 list: null, // banner列表 total: 0, // 数据库中的总记录数 page: 1, // 默认页码 limit: 10, // 每页记录数 searchObj: {}, // 查询表单对象 statusList: [ { 'status': '1', 'name': '进行中' }, { 'status': '2', 'name': '已完成' }, { 'status': '-1', 'name': '驳回' } ], createTimes: [] } }, // 生命周期函数:内存准备完毕,页面尚未渲染 created() { console.log('list created......') this.fetchData() }, // 生命周期函数:内存准备完毕,页面渲染成功 mounted() { console.log('list mounted......') }, methods: { // 当页码发生改变的时候 changeSize(size) { console.log(size) this.limit = size this.fetchData(1) }, // 加载banner列表数据 fetchData(page = 1) { console.log('翻页。。。' + page) // 异步获取远程数据(ajax) this.page = page if (this.createTimes && this.createTimes.length === 2) { this.searchObj.createTimeBegin = this.createTimes[0] this.searchObj.createTimeEnd = this.createTimes[1] } 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() }, show(id) { console.log(id) } } } </script>
流程部署:
后端:
@Override public void deployByZip(String deployPath) { InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(deployPath); ZipInputStream zipInputStream = new ZipInputStream(resourceAsStream); //部署 Deployment deploy = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy(); System.out.println(deploy.getId()); System.out.println(deploy.getName()); }
@Override public void publish(Long id) { ProcessTemplate processTemplate = baseMapper.selectById(id); processTemplate.setStatus(1); baseMapper.updateById(processTemplate); if (StringUtils.hasLength(processTemplate.getProcessDefinitionPath())){ processService.deployByZip(processTemplate.getProcessDefinitionPath()); } }
前端代码
<el-button type="text" v-if="scope.row.status == 0" size="mini" @click="edit(scope.row.id)" :disabled="$hasBP('bnt.processTemplate.templateSet') === false">修改审批设置</el-button> <el-button type="text" v-if="scope.row.status == 0" size="mini" @click="removeDataById(scope.row.id)" :disabled="$hasBP('bnt.processTemplate.remove') === false">删除</el-button>