管理端之审批设置

奋斗吧
奋斗吧
擅长邻域:未填写

标签: 管理端之审批设置 Java博客 51CTO博客

2023-07-18 18:24:26 145浏览

管理端之审批设置,1. 需求描述   76公司日常办公,审批是必不可少的一个功能,例如常用的钉钉OA审批,今天我们就要做类似的审批功能。审批设置模块包含:审批类型与审批模板审批类型:审批类型即为审批的分类,如:出勤、人事、财务等审批模板:设置具体审批的基本信息、表单信息与审批流程定义,审批流涉及工作流引擎Activiti,常见的审批模板如:加班、出差、请假、费用报销等,我们可

1. 需求描述   76

管理端之审批设置_表单

公司日常办公,审批是必不可少的一个功能,例如常用的钉钉OA审批,今天我们就要做类似的审批功能。

审批设置模块包含:审批类型与审批模板

审批类型:审批类型即为审批的分类,如:出勤、人事、财务等

审批模板:设置具体审批的基本信息、表单信息与审批流程定义,审批流涉及工作流引擎Activiti,常见的审批模板如:加班、出差、请假、费用报销等,我们可以根据公司具体业务配置具体的审批模板

2. 页面效果   76

2.1 管理端

2.1.1 审批类型

管理端之审批设置_表单_02

2.1.2  审批模板

管理端之审批设置_表单_03

2.1.3 在线流程设计

管理端之审批设置_实体类_04

2.2 员工端

2.2.1 审批中心

管理端之审批设置_表单_05

2.2.2 发起审批,显示动态表单

管理端之审批设置_持久层_06

3. 数据库表设计   76

管理端之审批设置_持久层_07

3.1 审批类型表:oa_process_type

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='审批类型';

#
# Data for table "oa_process_type"
#

INSERT INTO `oa_process_type` VALUES (1,'出勤','出勤','2022-12-06 09:35:12','2022-12-06 09:36:13',0),(2,'人事','人事','2022-12-06 09:35:19','2022-12-06 09:36:16',0),(3,'财务','财务','2022-12-06 09:35:29','2022-12-06 09:36:17',0);

管理端之审批设置_表单_08

3.2 审批模板表:oa_process_template

# Structure for table "oa_process_template"
#

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='审批模板';

#
# Data for table "oa_process_template"
#

INSERT INTO `oa_process_template` VALUES (1,'加班','https://gw.alicdn.com/tfs/TB1bHOWCSzqK1RjSZFjXXblCFXa-112-112.png','1','[{\"type\":\"datePicker\",\"field\":\"sdate\",\"title\":\"开始时间\",\"info\":\"\",\"_fc_drag_tag\":\"datePicker\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"datePicker\",\"field\":\"edate\",\"title\":\"结束时间\",\"info\":\"\",\"_fc_drag_tag\":\"datePicker\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"input\",\"field\":\"day\",\"title\":\"加班天数\",\"info\":\"\",\"_fc_drag_tag\":\"input\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"input\",\"field\":\"reason\",\"title\":\"加班原因\",\"info\":\"\",\"props\":{\"type\":\"textarea\",\"rows\":4},\"_fc_drag_tag\":\"input\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"select\",\"field\":\"dept\",\"title\":\"所属部门\",\"info\":\"\",\"effect\":{\"fetch\":\"\"},\"options\":[{\"value\":\"技术部\",\"label\":\"技术部\"},{\"value\":\"产品部\",\"label\":\"产品部\"},{\"label\":\"市场部\",\"value\":\"市场部\"},{\"label\":\"人事部\",\"value\":\"人事部\"}],\"_fc_drag_tag\":\"select\",\"hidden\":false,\"display\":true}]','{\n    \"form\": {\n        \"labelPosition\": \"right\",\n        \"size\": \"medium\",\n        \"labelWidth\": \"80px\",\n        \"hideRequiredAsterisk\": false,\n        \"showMessage\": true,\n        \"inlineMessage\": false\n    },\n    \"submitBtn\": {\n                         \"innerText\":\"提交审批 \",\n                        \"round\":true,\n                        \"width\": \"280px\",\n                        \"type\":\"primary\"\n                     },\n    \"resetBtn\": false\n}\n','jiaban','','','加班',1,'2022-12-07 14:33:51','2022-12-27 09:12:58',0),(2,'请假','https://gw.alicdn.com/imgextra/i3/O1CN01LLn0YV1LhBXs7T2iO_!!6000000001330-2-tps-120-120.png','2','[{\"type\":\"datePicker\",\"field\":\"sdate\",\"title\":\"开始时间\",\"info\":\"\",\"_fc_drag_tag\":\"datePicker\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"datePicker\",\"field\":\"edate\",\"title\":\"结束时间\",\"info\":\"\",\"_fc_drag_tag\":\"datePicker\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"input\",\"field\":\"day\",\"title\":\"请假天数\",\"info\":\"\",\"_fc_drag_tag\":\"input\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"input\",\"field\":\"reason\",\"title\":\"请假原因\",\"info\":\"\",\"props\":{\"type\":\"textarea\",\"rows\":4},\"_fc_drag_tag\":\"input\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"select\",\"field\":\"dept\",\"title\":\"所属部门\",\"info\":\"\",\"effect\":{\"fetch\":\"\"},\"options\":[{\"value\":\"技术部\",\"label\":\"技术部\"},{\"value\":\"产品部\",\"label\":\"产品部\"},{\"label\":\"市场部\",\"value\":\"市场部\"},{\"label\":\"人事部\",\"value\":\"人事部\"}],\"_fc_drag_tag\":\"select\",\"hidden\":false,\"display\":true}]','{\n    \"form\": {\n        \"labelPosition\": \"right\",\n        \"size\": \"medium\",\n        \"labelWidth\": \"80px\",\n        \"hideRequiredAsterisk\": false,\n        \"showMessage\": true,\n        \"inlineMessage\": false\n    },\n    \"submitBtn\": {\n                         \"innerText\":\"提交审批 \",\n                        \"round\":true,\n                        \"width\": \"280px\",\n                        \"type\":\"primary\"\n                     },\n    \"resetBtn\": false\n}\n','qingjia','','','请假',0,'2022-12-07 15:04:02','2022-12-27 09:13:00',0),(3,'申请费用','https://gw.alicdn.com/tfs/TB1e76lCOLaK1RjSZFxXXamPFXa-112-112.png','3','[{\"type\":\"datePicker\",\"field\":\"sdate\",\"title\":\"使用时间\",\"info\":\"\",\"_fc_drag_tag\":\"datePicker\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}],\"props\":{\"format\":\"\"}},{\"type\":\"input\",\"field\":\"amount\",\"title\":\"申请金额\",\"info\":\"\",\"_fc_drag_tag\":\"input\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"select\",\"field\":\"F0ma1n7tec860p\",\"title\":\"费用类别\",\"info\":\"\",\"effect\":{\"fetch\":\"\"},\"options\":[{\"value\":\"房租费\",\"label\":\"房租费\"},{\"value\":\"水费\",\"label\":\"水费\"},{\"label\":\"电费\",\"value\":\"电费\"},{\"label\":\"网络费\",\"value\":\"网络费\"},{\"label\":\"火车票\",\"value\":\"火车票\"},{\"label\":\"飞机票\",\"value\":\"飞机票\"},{\"label\":\"部门团建费\",\"value\":\"部门团建费\"}],\"_fc_drag_tag\":\"select\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"input\",\"field\":\"reason\",\"title\":\"其他补充\",\"info\":\"\",\"props\":{\"type\":\"textarea\",\"rows\":4},\"_fc_drag_tag\":\"input\",\"hidden\":false,\"display\":true},{\"type\":\"select\",\"field\":\"dept\",\"title\":\"所属部门\",\"info\":\"\",\"effect\":{\"fetch\":\"\"},\"options\":[{\"value\":\"技术部\",\"label\":\"技术部\"},{\"value\":\"产品部\",\"label\":\"产品部\"},{\"label\":\"市场部\",\"value\":\"市场部\"},{\"label\":\"人事部\",\"value\":\"人事部\"}],\"_fc_drag_tag\":\"select\",\"hidden\":false,\"display\":true},{\"type\":\"input\",\"field\":\"content\",\"title\":\"申请事由\",\"info\":\"\",\"props\":{\"type\":\"textarea\",\"rows\":4},\"_fc_drag_tag\":\"input\",\"hidden\":false,\"display\":true,\"validate\":[{\"trigger\":\"change\",\"mode\":\"required\",\"message\":\"必须输入\",\"required\":true,\"type\":\"string\"}]},{\"type\":\"switch\",\"field\":\"F9hn1n7twlkcfk\",\"title\":\"消息提示\",\"info\":\"\",\"_fc_drag_tag\":\"switch\",\"hidden\":false,\"display\":true},{\"type\":\"span\",\"title\":\"注意\",\"native\":false,\"children\":[\"有疑问找云尚小秘哦!\"],\"_fc_drag_tag\":\"span\",\"hidden\":false,\"display\":true}]',' ','feiyong','','','申请费用',0,'2022-12-08 10:35:33','2022-12-26 21:00:01',0);

管理端之审批设置_持久层_09

重要字段说明:

form_props:动态表单的表单属性,后续入门form-create组件会详细讲解

form_options:动态表单的表单选项,后续入门form-create组件会详细讲解,这两项就是配置动态表单的

process_definition_key:流程定义key,前面Activiti入门已讲解,我们启动流程实例会使用它

process_definition_path:保存流程定义文件的路径

process_model_id:流程定义模型id,流程定义实现两种方式,一种:上传,第二种:在线制作,分别使用这两个字段保存记录

4.  审批设置   77

4.1审批类型

操作service-oa模块

我们使用之前写好的代码生成器,生成相应代码

管理端之审批设置_实体类_10

修改以下

管理端之审批设置_实体类_11

管理端之审批设置_实体类_12

成功

管理端之审批设置_持久层_13

管理端之审批设置_表单_14

老规矩删除我们不用的实体类,然后吧持久层和业务层中引用的实体类修改成我们自己的实体类

这里就不做演示了

管理端之审批设置_实体类_15

将启动类放到com.atguigu包下

管理端之审批设置_持久层_16

4.1.1 持久层OaProcessTypeMapper

操作service-oa模块

package com.atguigu.process.mapper;

import com.atguigu.model.process.ProcessType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 * 审批类型 Mapper 接口
 * </p>
 */
public interface OaProcessTypeMapper extends BaseMapper<ProcessType> {

}

4.1.2 业务层接口OaProcessTypeService

package com.atguigu.process.service;

import com.atguigu.model.process.ProcessType;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 * 审批类型 服务类   77
 * </p>
 */
public interface OaProcessTypeService extends IService<ProcessType> {

}

4.1.3 业务层接口实现类 OaProcessTypeServiceImpl

package com.atguigu.process.service.impl;

import com.atguigu.model.process.ProcessType;
import com.atguigu.process.mapper.OaProcessTypeMapper;
import com.atguigu.process.service.OaProcessTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 审批类型 服务实现类  77
 * </p>
 */
@Service
public class OaProcessTypeServiceImpl extends ServiceImpl<OaProcessTypeMapper, ProcessType> implements OaProcessTypeService {

}

4.1.4 控制层  OaProcessTypeController

这里实现审批类型的CRUD操作

package com.atguigu.process.controller;


import com.atguigu.common.result.Result;
import com.atguigu.model.process.ProcessType;
import com.atguigu.process.service.OaProcessTypeService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

/**
 * <p>
 * 审批类型 前端控制器   77
 * </p>
 */
@RestController
@RequestMapping(value = "/admin/process/processType")
public class OaProcessTypeController {
    @Autowired
    private OaProcessTypeService processTypeService;

    @ApiOperation(value = "获取分页列表")
    @GetMapping("{page}/{limit}")
    public Result index(@PathVariable Long page,
                        @PathVariable Long limit){
        Page<ProcessType> pageParam = new Page<>();
        IPage<ProcessType> pageModel = processTypeService.page(pageParam);
        return Result.ok(pageModel);
    }
    
    @ApiOperation(value = "获取")
    @GetMapping("get/{id}")
    public Result get(@PathVariable Long id) {
        ProcessType processType = processTypeService.getById(id);
        return Result.ok(processType);
    }
    
    @ApiOperation(value = "新增")
    @PostMapping("save")
    public Result save(@RequestBody ProcessType processType) {
        processTypeService.save(processType);
        return Result.ok();
    }
    
    @ApiOperation(value = "修改")
    @PutMapping("update")
    public Result updateById(@RequestBody ProcessType processType) {
        processTypeService.updateById(processType);
        return Result.ok();
    }
    
    @ApiOperation(value = "删除")
    @DeleteMapping("remove/{id}")
    public Result remove(@PathVariable Long id) {
        processTypeService.removeById(id);
        return Result.ok();
    }
}


4.2 审批类型前端   77

4.2.1  动态添加路由

在“系统管理”->“菜单管理”添加“审批设置”->“审批类型”

对于菜单信息,我们也可以直接导入菜单表初始化数据,后续不用再单独配置

4.2.2 定义api

创建src/api/process/processType.js

管理端之审批设置_实体类_17

import request from '@/utils/request'

const api_name = '/admin/process/processType'

export default {

  getPageList(page, limit) {
    return request({
      url: `${api_name}/${page}/${limit}`,
      method: 'get'
    })
  },
  getById(id) {
    return request({
      url: `${api_name}/get/${id}`,
      method: 'get'
    })
  },
  save(role) {
    return request({
      url: `${api_name}/save`,
      method: 'post',
      data: role
    })
  },
  updateById(role) {
    return request({
      url: `${api_name}/update`,
      method: 'put',
      data: role
    })
  },
  removeById(id) {
    return request({
      url: `${api_name}/remove/${id}`,
      method: 'delete'
    })
  }
}

4.2.3 创建vue页面

创建views/processSet/processType/list.vue

管理端之审批设置_持久层_18

<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>

测试

因为启动类我们移动了位置所以,注解ComponentScan就不再需要扫描包了因为它现在本来就在com.atguigu包下

管理端之审批设置_实体类_19

但是启动还是报错了,说是mapper没找到(因为们用的process包下的mapper,不是之前的auth包了),这是因为我们之前在service-util中配置的分页插件没找到mapper

管理端之审批设置_表单_20

添加一个新的mapper路径

管理端之审批设置_持久层_21

再次启动

后端启动成功

管理端之审批设置_表单_22

启动前端成功

管理端之审批设置_表单_23

管理端之审批设置_持久层_24

浏览器输入http://localhost:9528/

管理端之审批设置_实体类_25

添加

管理端之审批设置_持久层_26

修改

管理端之审批设置_实体类_27

删除

管理端之审批设置_表单_28

4.3审批模板   78

4.3.1 持久层 OaProcessTemplateService

操作service-oa模块

package com.atguigu.process.service;

import com.atguigu.model.process.ProcessTemplate;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 * 审批模板 服务类
 * </p>
 */
public interface OaProcessTemplateService extends IService<ProcessTemplate> {

}

4.3.2 业务层接口OaProcessTemplateService

package com.atguigu.process.service;

import com.atguigu.model.process.ProcessTemplate;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 * 审批模板 服务类   77
 * </p>
 */
public interface OaProcessTemplateService extends IService<ProcessTemplate> {

}

4.3.3 业务层接口实现类OaProcessTemplateServiceImpl

package com.atguigu.process.service.impl;

import com.atguigu.model.process.ProcessTemplate;
import com.atguigu.process.mapper.OaProcessTemplateMapper;
import com.atguigu.process.service.OaProcessTemplateService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 审批模板 服务实现类  77
 * </p>
 */
@Service
public class OaProcessTemplateServiceImpl extends ServiceImpl<OaProcessTemplateMapper, ProcessTemplate> implements OaProcessTemplateService {

}

4.3.4 控制层OaProcessTemplateController    79

package com.atguigu.process.controller;


import com.atguigu.common.result.Result;
import com.atguigu.model.process.ProcessTemplate;
import com.atguigu.process.service.OaProcessTemplateService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * <p>
 * 审批模板 前端控制器  78
 * </p>
 */
@RestController
@RequestMapping(value = "/admin/process/processTemplate")
public class OaProcessTemplateController {
    @Autowired
    private OaProcessTemplateService processTemplateService;

    //分页查询审批模板
    @ApiOperation("获取分页审批模板数据")
    @GetMapping("{page}/{limit}")
    public Result index(@PathVariable Long page,
                        @PathVariable Long limit) {
        Page<ProcessTemplate> pageParam = new Page<>(page,limit);
        //分页查询审批模板,把审批类型对应名称查询   78
        IPage<ProcessTemplate> pageModel =
                processTemplateService.selectPageProcessTempate(pageParam);
        return Result.ok(pageModel);
    }

    //@PreAuthorize("hasAuthority('bnt.processTemplate.list')")
    @ApiOperation(value = "获取")
    @GetMapping("get/{id}")
    public Result get(@PathVariable Long id) {
        ProcessTemplate processTemplate = processTemplateService.getById(id);
        return Result.ok(processTemplate);
    }

    //@PreAuthorize("hasAuthority('bnt.processTemplate.templateSet')")
    @ApiOperation(value = "新增")
    @PostMapping("save")
    public Result save(@RequestBody ProcessTemplate processTemplate) {
        processTemplateService.save(processTemplate);
        return Result.ok();
    }

    //@PreAuthorize("hasAuthority('bnt.processTemplate.templateSet')")
    @ApiOperation(value = "修改")
    @PutMapping("update")
    public Result updateById(@RequestBody ProcessTemplate processTemplate) {
        processTemplateService.updateById(processTemplate);
        return Result.ok();
    }

    //@PreAuthorize("hasAuthority('bnt.processTemplate.remove')")
    @ApiOperation(value = "删除")
    @DeleteMapping("remove/{id}")
    public Result remove(@PathVariable Long id) {
        processTemplateService.removeById(id);
        return Result.ok();
    }
}


业务层接口

package com.atguigu.process.service;

import com.atguigu.model.process.ProcessTemplate;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 * 审批模板 服务类   77
 * </p>
 */
public interface OaProcessTemplateService extends IService<ProcessTemplate> {

    //分页查询审批模板,把审批类型对应名称查询   78
    IPage<ProcessTemplate> selectPageProcessTempate(Page<ProcessTemplate> pageParam);
}

业务层接口实现类

package com.atguigu.process.service.impl;

import com.atguigu.model.process.ProcessTemplate;
import com.atguigu.model.process.ProcessType;
import com.atguigu.process.mapper.OaProcessTemplateMapper;
import com.atguigu.process.service.OaProcessTemplateService;
import com.atguigu.process.service.OaProcessTypeService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 审批模板 服务实现类  77
 * </p>
 */
@Service
public class OaProcessTemplateServiceImpl extends ServiceImpl<OaProcessTemplateMapper, ProcessTemplate> implements OaProcessTemplateService {

    @Autowired
    private OaProcessTypeService processTypeService;

    //分页查询审批模板,把审批类型对应名称查询   79
    @Override
    public IPage<ProcessTemplate> selectPageProcessTempate(Page<ProcessTemplate> pageParam) {
        //1 调用mapper的方法实现分页查询
        Page<ProcessTemplate> processTemplatePage = baseMapper.selectPage(pageParam, null);

        //2 第一步分页查询返回分页数据,从分页数据获取列表list集合
        List<ProcessTemplate> processTemplateList = processTemplatePage.getRecords();

        //3 遍历list集合,得到每个对象的审批类型id
        for(ProcessTemplate processTemplate : processTemplateList) {
            //得到每个对象的审批类型id
            Long processTypeId = processTemplate.getProcessTypeId();
            //4 根据审批类型id,查询获取对应名称
            LambdaQueryWrapper<ProcessType> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ProcessType::getId,processTypeId);
            ProcessType processType = processTypeService.getOne(wrapper);
            if(processType == null) {
                continue;
            }
            //5 完成最终封装processTypeName
            processTemplate.setProcessTypeName(processType.getName());
        }
        return processTemplatePage;
    }
}

4.4 审批模板前端   79

4.4.1  动态添加路由

在“系统管理”->“菜单管理”添加“审批设置”->“审批类型”

对于菜单信息,我们也可以直接导入菜单表初始化数据,后续不用再单独配置

说明:“审批模板设置”页面内容较多,因此单独打开一个独立页面

4.4.2 定义api

创建src/api/process/processTemplate.js

基本的增删改查接口

管理端之审批设置_实体类_29

import request from '@/utils/request'

const api_name = '/admin/process/processTemplate'

export default {

  getPageList(page, limit) {
    return request({
      url: `${api_name}/${page}/${limit}`,
      method: 'get'
    })
  },
  getById(id) {
    return request({
      url: `${api_name}/get/${id}`,
      method: 'get'
    })
  },

  save(role) {
    return request({
      url: `${api_name}/save`,
      method: 'post',
      data: role
    })
  },

  updateById(role) {
    return request({
      url: `${api_name}/update`,
      method: 'put',
      data: role
    })
  },
  removeById(id) {
    return request({
      url: `${api_name}/remove/${id}`,
      method: 'delete'
    })
  }
}

4.4.3  列表页面

创建views/processSet/processTemplate/list.vue

管理端之审批设置_表单_30

<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>

测试

启动前后端,成功

管理端之审批设置_表单_31

管理端之审批设置_持久层_32

浏览器输入http://localhost:9528/

管理端之审批设置_实体类_33

4.5 添加审批模板   80

效果图

管理端之审批设置_持久层_34

1、基本设置:一些基本信息

2、表单设置:动态表单

3、流程设置:本地设计流程定义,上传流程定义文件及流程定义图片(压缩上传)

涉及未实现接口:

1、获取全部审批分类

2、上传流程定义压缩文件

4.5.1 form-create   80

官网:http://www.form-create.com/v2/guide/

轻松搞定 form 表单,让你不再为表单而烦恼。

form-create 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成组件。

form-create-designer 是基于 form-create实现的表单设计器组件。可以通过拖拽的方式快速创建表单,提高开发者对表单的开发效率,节省开发者的时间

表单设计器

http://www.form-create.com/designer/?fr=home

管理端之审批设置_实体类_35

可以通过拖拽的方式快速配置动态表单,配置好的动态表单可以通过:生成JSON与生成Options获取数据,这两数据对于表字段:form_props与form_options,后续我们通过这两字段渲染动态表单。

 大家可以根据表单设计器,查看数据格式

4.5.2 集成form-create   80

1、添加依赖

在package.json文件添加依赖,注意版本号,更高的版本号可能与本项目不兼容

管理端之审批设置_实体类_36

下载这两个依赖

管理端之审批设置_表单_37

"@form-create/element-ui": "^2.5.17",
"@form-create/designer": "^1.0.8",

2、在 main.js 中写入以下内容:

管理端之审批设置_持久层_38

import formCreate from '@form-create/element-ui'
import FcDesigner from '@form-create/designer'
Vue.use(formCreate)
Vue.use(FcDesigner)

3、集成表单设计器

创建views/processSet/processTemplate/templateSet.vue

管理端之审批设置_表单_39

<template>
  <div class="app-container">
    <div id="app1">
      <fc-designer class="form-build" ref="designer"/>
      <el-button @click="save">获取数据</el-button>
    </div>
  </div>
</template>

<script>

export default {
  data() {
    return {
    }
  },

  created() {

  },

  methods: {
    save() {
      console.log(this.$refs.designer.getRule())
      console.log(this.$refs.designer.getOption())
    }
  }
}
</script>

显示效果:

管理端之审批设置_实体类_40

随便拉几个表单项,点击“获取数据”,就是我们需要的动态表单数据格式了。

4.5.3 获取全部审批分类接口   80

操作service-oa模块

1、在OaProcessTypeController类添加接口

//查询所有审批分类   80
    @GetMapping("findAll")
    public Result findAll() {
        List<ProcessType> list = processTypeService.list();
        return Result.ok(list);
    }

2、在processType.js添加前端接口

管理端之审批设置_实体类_41

findAll() {
  return request({
    url: `${api_name}/findAll`,
    method: 'get'
  })
}

4.5.4 上传流程定义接口    80

上传用activiti做的流程定义接口 (我们上传到target\classes\processes目录下,processes是我们新建的文件夹专门放activiti资源的)

操作service-oa模块

在OaProcessTemplateController类添加接口

//上传用activiti做的流程定义接口 (我们上传到target\classes\processes目录下)  80
    @ApiOperation(value = "上传流程定义")
    @PostMapping("/uploadProcessDefinition")
    public Result uploadProcessDefinition(MultipartFile file) throws FileNotFoundException {
        //获取classes目录位置
        String path = new File(ResourceUtils.getFile("classpath:")
                .getPath()).getAbsolutePath();
        //设置上传文件夹processes
        File tempFile = new File(path + "/processes/");
        if(!tempFile.exists()) {
            tempFile.mkdirs();
        }
        //创建空文件,实现文件写入
        String filename = file.getOriginalFilename();
        File zipFile = new File(path + "/processes/" + filename);

        //保存文件
        try {
            file.transferTo(zipFile);
        } catch (IOException e) {
            return Result.fail();
        }

        Map<String, Object> map = new HashMap<>();
        //根据上传地址后续部署流程定义,文件名称为流程定义的默认key
        map.put("processDefinitionPath", "processes/" + filename);
        map.put("processDefinitionKey", filename.substring(0, filename.lastIndexOf(".")));
        return Result.ok(map);
    }

4.5.5 模板设置完整代码   80

<template>
  <div class="app-container">
    <el-steps :active="stepIndex" finish-status="success">
      <el-step title="基本设置"></el-step>
      <el-step title="表单设置"></el-step>
      <el-step title="流程设置"></el-step>
    </el-steps>

    <div class="tools-div">
      <el-button v-if="stepIndex > 1" icon="el-icon-check" type="primary" size="small" @click="pre()" round>上一步
      </el-button>
      <el-button icon="el-icon-check" type="primary" size="small" @click="next()" round>{{
          stepIndex == 3 ? '提交保存' : '下一步'
        }}
      </el-button>
      <el-button type="primary" size="small" @click="back()">返回</el-button>
    </div>

    <!-- 第一步 -->
    <div v-show="stepIndex == 1" style="margin-top: 20px;">
      <el-form ref="flashPromotionForm" label-width="150px" size="small" style="padding-right: 40px;">
        <el-form-item label="审批类型">
          <el-select v-model="processTemplate.processTypeId" placeholder="请选择审批类型">
            <el-option :key="item.id" v-for="item in processTypeList" :label="item.name" :value="item.id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="审批名称">
          <el-input v-model="processTemplate.name"/>
        </el-form-item>
        <el-form-item label="审批图标">
          <el-select v-model="processTemplate.iconUrl" placeholder="请选择审批图标">
            <el-option :key="item.id" v-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-item label="描述">
          <el-input v-model="processTemplate.description"/>
        </el-form-item>
      </el-form>
    </div>

    <!-- 第二步 -->
    <div v-show="stepIndex == 2" style="margin-top: 20px;">
      <!--表单构建器-->
      <fc-designer class="form-build" ref="designer"/>
    </div>

    <!-- 第三步 -->
    <div v-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"
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将Activiti流程设计文件拖到此处,或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">只能上传zip压缩文件,且不超过2048kb</div>
      </el-upload>
    </div>
  </div>
</template>

<script>
import api from '@/api/process/processTemplate'
import processTypeApi from '@/api/process/processType'
import store from '@/store'

const defaultForm = {
  id: '',
  name: '',
  iconUrl: '',
  formProps: '',
  formOptions: '',
  processDefinitionKey: '',
  processDefinitionPath: '',
  description: ''
}
export default {
  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() {
    let id = 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) {
      const isZip = file.type === 'application/x-zip-compressed'
      const isLt2M = file.size / 1024 / 1024 < 2

      if (!isZip) {
        this.$message.error('文件格式不正确!')
        return false
      }
      if (!isLt2M) {
        this.$message.error('上传头像图片大小不能超过 2MB!')
        return false
      }
      return true
    },

    // 上传图片成功的回调
    onUploadSuccess(res, file) {
      // 填充上传文件列表
      this.processTemplate.processDefinitionPath = res.data.processDefinitionPath
      this.processTemplate.processDefinitionKey = res.data.processDefinitionKey
    },

    back() {
      this.$router.push('/processSet/processTemplate')
    }
  }
}
</script>

测试

后端正常启动

管理端之审批设置_实体类_42

前端启动成功

管理端之审批设置_实体类_43

浏览器输入http://localhost:9528/

管理端之审批设置_实体类_44

管理端之审批设置_持久层_45

管理端之审批设置_持久层_46

可以预览一下

管理端之审批设置_实体类_47

上传文件,这里我们把资源放在了E:\java\yunshang_office_tools\activiti_ziyuan

管理端之审批设置_表单_48

管理端之审批设置_实体类_49

成功后看后端,正好生成了我们对应的文件

管理端之审批设置_实体类_50

点击保存

管理端之审批设置_持久层_51

管理端之审批设置_实体类_52

数据库中也增加了相应的记录

管理端之审批设置_持久层_53

至此,成功

4.6 查看审批模板   81

查看审批模板基本信息、动态表单信息

4.6.1 添加按钮

管理端之审批设置_实体类_54

<el-button type="text" size="mini" @click="show(scope.row)">查看审批设置</el-button>

4.6.2 定义data   81

管理端之审批设置_持久层_55

rule: [],
option: {},
processTemplate: {},
formDialogVisible: false

4.6.3 定义方法   81

管理端之审批设置_实体类_56

show(row) {
  this.rule = JSON.parse(row.formProps)
  this.option = JSON.parse(row.formOptions)
  this.processTemplate = row
  this.formDialogVisible = true
}

4.6.4 定义弹出层   81

管理端之审批设置_实体类_57

<el-dialog title="查看审批设置" :visible.sync="formDialogVisible" width="35%">
  <h3>基本信息</h3>
  <el-divider/>
  <el-form ref="flashPromotionForm" label-width="150px" size="small" style="padding-right: 40px;">
    <el-form-item label="审批类型" style="margin-bottom: 0px;">{{ processTemplate.processTypeName }}</el-form-item>
    <el-form-item label="名称" style="margin-bottom: 0px;">{{ processTemplate.name }}</el-form-item>
    <el-form-item label="创建时间" 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>
  <span slot="footer" class="dialog-footer">
    <el-button @click="formDialogVisible = false" size="small">取 消</el-button>
  </span>
</el-dialog>

测试

管理端之审批设置_实体类_58

管理端之审批设置_实体类_59

5. 发布   81

发布后审批模板就不可以修改了,然后部署流程定义

5.1 添加controller接口

操作service-oa模块

在OaProcessTemplateController类添加接口

//部署流程定义(发布)  81
    @ApiOperation(value = "发布")
    @GetMapping("/publish/{id}")
    public Result publish(@PathVariable Long id) {
        //修改模板发布状态 1 已经发布
        //流程定义部署
        processTemplateService.publish(id);
        return Result.ok();
    }

业务层接口OaProcessTemplateService

//部署流程定义(发布)  81
    void publish(Long id);

业务层接口实现类OaProcessTemplateServiceImpl

//部署流程定义(发布)  81
    @Override
    public void publish(Long id) {
        //修改模板发布状态 1 已经发布  81
        ProcessTemplate processTemplate = baseMapper.selectById(id);
        processTemplate.setStatus(1);
        baseMapper.updateById(processTemplate);
        
        //后续完成流程定义的部署

    }

5.2 前端整合   81

1、添加api接口

管理端之审批设置_持久层_60

publish(id) {
  return request({
    url: `${api_name}/publish/${id}`,
    method: 'get'
  })
}

2、添加按钮

管理端之审批设置_表单_61

<el-button v-if="scope.row.status == 0" type="text" size="mini" @click="publish(scope.row.id)" :disabled="$hasBP('bnt.processTemplate.publish')  === false">发布</el-button>

3、添加按钮方法

管理端之审批设置_实体类_62

publish(id) {
  api.publish(id).then(response => {
    this.$message.success('发布成功')
    this.fetchData(this.page)
  })
}

测试

浏览器输入http://localhost:9528/

管理端之审批设置_实体类_63

管理端之审批设置_持久层_64

数据库也有相应变化

管理端之审批设置_实体类_65

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695