OA系统添加审批模板

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、添加审批模板

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

可以通过拖拽的方式快速配置动态表单,配置好的动态表单可以通过:生成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 中写入以下内容:

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

3、集成表单设计器

创建views/processSet/processTemplate/templateSet.vue

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

显示效果:

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

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")
public Result uploadProcessDefinition(MultipartFilefile) throwsFileNotFoundException {
    String path=newFile(ResourceUtils.getURL("classpath:").getPath()).getAbsolutePath();
​ 
    String fileName=file.getOriginalFilename();
    // 上传目录
    File tempFile=newFile(path+"/processes/");
    // 判断目录是否存着
    if (!tempFile.exists()) {
        tempFile.mkdirs();//创建目录
    }
    // 创建空文件用于写入文件
    FileimageFile=newFile(path+"/processes/"+fileName);
    // 保存文件流到本地
    try {
        file.transferTo(imageFile);
    } catch (IOExceptione) {
        e.printStackTrace();
        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);
}

2.5、模板设置完整代码

<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-buttonicon="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-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-button type="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、定义弹出层

<el-dialog title="查看审批设置":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>

4、部署流程定义

4.1、根据上传部署

4.1.1、定义service接口

操作类:ProcessService

void deploy ByZip(StringdeployPath);
4.1.2、service接口实现

操作类:ProcessServiceImpl

@Override
public void deployByZip(StringdeployPath) {
    // 定义zip输入流
    InputStreaminputStream=this
            .getClass()
            .getClassLoader()
            .getResourceAsStream(deployPath);
    ZipInputStreamzipInputStream=newZipInputStream(inputStream);
    // 流程部署
    Deploymentdeployment=repositoryService.createDeployment()
            .addZipInputStream(zipInputStream)
            .deploy();
}

4.2、完善审批模板发布

操作类:ProcessTemplateServiceImpl

@Autowired
privateProcessServiceprocessService;
​
@Transactional
@Override
public void publish(Longid) {
   ProcessTemplateprocessTemplate=this.getById(id);
   processTemplate.setStatus(1);
   processTemplateMapper.updateById(processTemplate);
​
   //优先发布在线流程设计
    if(!StringUtils.isEmpty(processTemplate.getProcessDefinitionPath())) {
        processService.deployByZip(processTemplate.getProcessDefinitionPath());
    }
}

说明:审批模板发布后不可以再编辑

4.3、页面按钮控制

按钮添加判断,发布后不可以编辑:v-if="scope.row.status == 0"

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

猜你喜欢

转载自blog.csdn.net/m0_57037182/article/details/129732724
今日推荐