05-云尚办公系统-Activiti7入门,审批管理

15.Activiti7

部署-启动-分配-拾取-完成-(转交-完成)-结束 途中可以查询

/**
 * @author Yangmc email:yangmc@tayo.com
 * @create 2024-01-26 6:35
 * @description 请假审批流程
 */
@SpringBootTest
public class ProcessTest {

    @Autowired
    private RepositoryService repositoryService;//部署流程定义,管理流程资源

    @Autowired
    private RuntimeService runtimeService;//启动流程实例

    @Autowired
    private TaskService taskService;//处理业务运行中的各种任务

    @Autowired
    private HistoryService historyService;//查询历史信息

    /**
     * 单个文件的部署
     */
    @Test
    public void deployProcess() {
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("process/qingjia.bpmn20.xml")//加载类路径下的资源
                .addClasspathResource("process/qingjia.png")
                .name("请假申请流程")
                .deploy();
        System.out.println("流程id:" + deploy.getId());
        System.out.println("流程名称:" + deploy.getName());
    }

    /**
     * 启动流程实例
     */
    @Test
    public void startProcess() {
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjia");
        System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例id:" + processInstance.getId());
        System.out.println("当前活动id:" + processInstance.getActivityId());
    }

    /**
     * 查询个人的代办任务--zhangsan
     */
    @Test
    public void findTaskList() {
        String assign = "zhangsan";
        List<Task> list = taskService.createTaskQuery()
                .taskAssignee(assign)
                .list();
        for (Task task : list) {
            System.out.println("流程实例id" + task.getProcessInstanceId());
            System.out.println("任务id:" + task.getId());
            System.out.println("任务负责人:" + task.getAssignee());
            System.out.println("任务名称:" + task.getName());
        }
    }

    /**
     * 处理当前任务
     */
    @Test
    public void completeTask() {
        // 查询负责人需要处理的任务,返回一条
        Task task = taskService.createTaskQuery().
                taskAssignee("zhangsan").
                singleResult();
        // 完成任务.参数是任务id
        taskService.complete(task.getId());
    }

    /**
     * 查询已经处理的任务
     */
    @Test
    public void findCompleteTaskList() {
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee("zhangsan")
                .finished().list();
        for (HistoricTaskInstance historicTaskInstance : list) {
            System.out.println("流程实例id:" + historicTaskInstance.getProcessInstanceId());
            System.out.println("任务id:" + historicTaskInstance.getId());
            System.out.println("任务负责人:" + historicTaskInstance.getAssignee());
            System.out.println("任务名称:" + historicTaskInstance.getName());
        }
    }

    /**
     * 删除流程定义
     */
    @Test
    public void deleteDeployment() {
        //部署id
        String deploymentId = "qingjia:1:c493c327-bb02-11ed-8360-005056c00001";
//        //删除流程定义,如果该流程定义已有流程实例启动则删除时出错
//        repositoryService.deleteDeployment(deploymentId);
        //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式
        repositoryService.deleteDeployment(deploymentId, true);
    }

    /**
     * 启动流程实例,添加businessKey
     */
    @Test
    public void startUpProcessAddBusinessKey(){
        // 启动流程实例,指定业务标识businessKey,也就是请假申请单id
        ProcessInstance processInstance = runtimeService.
                startProcessInstanceByKey("qingjia","1001");
        // 输出
        System.out.println("业务id:"+processInstance.getBusinessKey()); //1001
        System.out.println("processInstance.getId() = " + processInstance.getId()); // 71f6803b-bb19-11ed-a845-005056c00001
    }

    /**
     * 单个流程实例挂起
     */
    @Test
    public void SuspendProcessInstanceSingle() {
        String processInstanceId = "71f6803b-bb19-11ed-a845-005056c00001";
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        //获取到当前流程定义是否为暂停状态   suspended方法为true代表为暂停   false就是运行的
        boolean suspended = processInstance.isSuspended();
        if (suspended) {
            runtimeService.activateProcessInstanceById(processInstanceId);
            System.out.println("流程实例:" + processInstanceId + "激活");
        } else {
            runtimeService.suspendProcessInstanceById(processInstanceId);
            System.out.println("流程实例:" + processInstanceId + "挂起");
        }
    }

    /**
     * 全部流程实例挂起
     */
    @Test
    public void suspendProcessInstanceAll() {

        // 1、获取流程定义对象
        ProcessDefinition qingjia = repositoryService.createProcessDefinitionQuery().processDefinitionKey("qingjia").singleResult();
        // 2、调用流程定义对象的方法判断当前状态:挂起   激活
        boolean suspended = qingjia.isSuspended();
        if (suspended) {
            // 暂定,那就可以激活
            // 参数1:流程定义的id  参数2:是否激活    参数3:时间点
            repositoryService.activateProcessDefinitionById(qingjia.getId(), true, null);
            System.out.println("流程定义:" + qingjia.getId() + "激活");
        } else {
            repositoryService.suspendProcessDefinitionById(qingjia.getId(), true, null);
            System.out.println("流程定义:" + qingjia.getId() + "挂起");
        }
    }
    
}

16.审批管理

1.审批类型设置

1.CRUD后台

@Api(value = "审批类型设置", tags = "审批类型管理设置")
@RestController
@RequestMapping("/admin/process/processType")
public class OaProcessTypeController {
    @Autowired
    private OaProcessTypeService processTypeService;

    /**
     * 新增审批类型
     *
     * @param processType
     * @return
     */
    @PreAuthorize("hasAuthority('bnt.processType.add')")
    @ApiOperation(value = "新增")
    @PostMapping("")
    public Result save(@RequestBody ProcessType processType) {
        processTypeService.save(processType);
        return Result.ok();
    }

    /**
     * 删除审批类型
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "删除")
    @DeleteMapping("/{id}")
    public Result remove(@PathVariable Long id) {
        processTypeService.removeById(id);
        return Result.ok();
    }

    /**
     * 修改审批类型
     *
     * @param processType
     * @return
     */
    @PreAuthorize("hasAuthority('bnt.processType.update')")
    @ApiOperation(value = "修改")
    @PutMapping("")
    public Result updateById(@RequestBody ProcessType processType) {
        processTypeService.updateById(processType);
        return Result.ok();
    }

    /**
     * 获取单个审批类型
     *
     * @param id
     * @return
     */
    @PreAuthorize("hasAuthority('bnt.processType.list')")
    @ApiOperation(value = "获取")
    @GetMapping("/{id}")
    public Result get(@PathVariable Long id) {
        ProcessType processType = processTypeService.getById(id);
        return Result.ok(processType);
    }

    /**
     * 获取全部审批类型
     *
     * @return
     */
    @ApiOperation(value = "获取全部审批分类")
    @GetMapping("findAll")
    public Result findAll() {
        return Result.ok(processTypeService.list());
    }

    /**
     * 获取审批类型分页列表
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @ApiOperation(value = "获取分页列表")
    @GetMapping("{pageNum}/{pageSize}")
    public Result index(@PathVariable Long pageNum, @PathVariable Long pageSize) {

        Page<ProcessType> pageInfo = new Page<>(pageNum, pageSize);
        Page<ProcessType> pageModel = processTypeService.page(pageInfo);

        return Result.ok(pageModel);
    }
}

2.整合前端

定义api接口

src/api/process/processType.js

import request from '@/utils/request'

const api_name = '/admin/process/processType'

// 新增审批类型
export function saveProcessType(data) {
  return request({
    url: `${api_name}`,
    method: 'post',
    data: data
  })
}

// 删除审批类型
export function removeProcessType(id) {
  return request({
    url: `${api_name}/${id}`,
    method: 'delete'
  })
}

// 修改审批类型
export function updateProcessType(data) {
  return request({
    url: `${api_name}`,
    method: 'put',
    data: data
  })
}

// 查询审批类型详细
export function getProcessType(id) {
  return request({
    url: `${api_name}/${id}`,
    method: 'get'
  })
}

// 获取全部审批类型
export function findAll() {
  return request({
    url: `${api_name}/findAll`,
    method: 'get'
  })
}

// 查询审批类型列表
export function pageProcessType(pageNum, pageSize, query) {
  return request({
    url: `${api_name}/${pageNum}/${pageSize}`,
    method: 'get',
    params: query
  })
}

页面展示

src/views/processSet/processType/index.vue

<template>
  <div class="app-container">
    <!-- CRUD -->
    <el-row :gutter="10" class="mb8" style="margin-bottom: 10px">
      <el-col :span="1.5">
        <el-button
          v-if="$hasBP('bnt.processType.add') "
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
        >新增
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          v-if="$hasBP('bnt.processType.update') "
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
        >修改
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          v-if="$hasBP('bnt.processType.remove') "
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
        >删除
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
        >导出
        </el-button>
      </el-col>
    </el-row>
    <!-- 类型列表 -->
    <el-table
      v-loading="loading"
      :data="processTypeList"
      border
      header-cell-style="background-color:#EEE;color:#444;height:41px;"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="50" align="center"/>
      <el-table-column label="序号" width="70" align="center">
        <template slot-scope="scope">
          {{
            (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1
          }}
        </template>
      </el-table-column>
      <el-table-column
        key="name"
        label="类型名称"
        align="center"
        prop="name"
        :show-overflow-tooltip="true"
      />
      <el-table-column
        key="description"
        label="描述"
        align="center"
        prop="description"
        :show-overflow-tooltip="true"
      />
      <el-table-column
        label="创建时间"
        align="center"
        prop="createTime"
        width="160"
        sortable
      />
      <el-table-column
        label="修改时间"
        align="center"
        prop="updateTime"
        width="160"
        sortable
      />
      <el-table-column
        label="操作"
        align="center"
        width="200"
        class-name="small-padding fixed-width"
      >
        <template slot-scope="scope">
          <el-button
            v-if="$hasBP('bnt.processType.update') "
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
          >修改
          </el-button>
          <el-button
            v-if="$hasBP('bnt.processType.remove') "
            size="mini"
            type="text"
            icon="el-icon-delete"
            :disabled="scope.row.ProcessTypename==='admin'"
            @click="handleDelete(scope.row)"
          >删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改审批类型对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="类型名称" prop="name">
          <el-input
            v-model="form.name"
            placeholder="请输入类型名称"
            maxlength="30"
            :disabled="form.id != undefined"
          />
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input
            v-model="form.description"
            placeholder="请输入类型描述"
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  pageProcessType,
  getProcessType,
  removeProcessType,
  updateProcessType,
  saveProcessType
} from '@/api/process/processType'

export default {
  name: 'ProcessType',
  data() {
    return {
      // 查询参数
      queryParams: {
        // 当前页码
        pageNum: 1,
        // 每页记录数
        pageSize: 10
      },
      // 数据是否正在加载
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 类型表格数据
      processTypeList: null,
      // 弹出层标题
      title: '',
      open: false,
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        name: [
          { required: true, message: '类型名称不能为空', trigger: 'blur' },
          {
            min: 2,
            max: 20,
            message: '类型名称长度必须介于 2 和 20 之间',
            trigger: 'blur'
          }
        ]
      }
    }
  },
  created() {
    this.getList()
  },
  methods: {
    /** 查询类型列表 */
    getList() {
      this.loading = true
      pageProcessType(
        this.queryParams.pageNum,
        this.queryParams.pageSize,
        this.queryParams
      ).then((response) => {
        this.processTypeList = response.data.records
        this.total = response.data.total
        this.loading = false
      })
    },
    // 表单重置
    reset() {
      this.form = {
        id: undefined,
        name: undefined,
        description: undefined
      }
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset()
      this.open = true
      this.title = '添加类型'
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset()
      const id = row.id || this.ids
      getProcessType(id).then((response) => {
        this.form = response.data
        this.open = true
        this.title = '修改类型'
      })
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids
      this.$confirm('您确定删除名称为[' + row.name + ']的类型吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          removeProcessType(ids)
            .then((res) => {
              this.$message.success('删除成功')
              this.getList()
            })
            .catch((err) => {
              this.$message.error('删除失败')
            })
        })
        .catch(() => {
          this.$message.info('已取消删除')
        })
    },
    /** 导出按钮操作 */
    handleExport() {
    },
    /** 导入按钮操作 */
    handleImport() {
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.id)
      this.single = selection.length != 1
      this.multiple = !selection.length
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          if (this.form.id != undefined) {
            updateProcessType(this.form).then((response) => {
              this.$message.success('修改成功')
              this.open = false
              this.getList()
            })
          } else {
            saveProcessType(this.form).then((response) => {
              this.$message.success('新增成功')
              this.open = false
              this.getList()
            })
          }
        }
      })
    },
    /** 取消按钮*/
    cancel() {
      this.open = false
      this.reset()
      this.$refs['form'].resetFields()
    }

  }
}
</script>

<style scoped>

</style>

2.审批模板管理

1.CRUD后台

@Api(value = "审批模板管理", tags = "审批模板管理")
@RestController
@RequestMapping("/admin/process/processTemplate")
public class OaProcessTemplateController {
    @Autowired
    private OaProcessTemplateService processTemplateService;

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

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

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

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

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

    /**
     * 上传流程定义(图片上传)
     *
     * @param file
     * @return
     * @throws FileNotFoundException
     */
    @ApiOperation(value = "上传流程定义")
    @PostMapping("/uploadProcessDefinition")
    public Result uploadProcessDefinition(MultipartFile file) throws FileNotFoundException {

        // 获取classes目录位置
        String path = new File(ResourceUtils.getURL("classpath:").getPath()).getAbsolutePath();
        // 设置上传文件夹
        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);
    }

    /**
     * 部署流程定义(发布)
      * @param id
     * @return
     */
    @ApiOperation(value = "发布审批模板")
    @GetMapping("/publish/{id}")
    public Result publish(@PathVariable Long id) {
        // 修改模板的发布状态 status==1 代表已发布
        // 流程定义部署
        processTemplateService.publish(id);
        return Result.ok();
    }
}

com.atguigu.process.service.impl.OaProcessTemplateServiceImpl

@Service
public class OaProcessTemplateServiceImpl extends ServiceImpl<OaProcessTemplateMapper, ProcessTemplate> implements OaProcessTemplateService {
    @Autowired
    private OaProcessTypeService processTypeService;

    @Autowired
    private OaProcessService processService;

    /**
     * 分页查询审批模板,把审批类型对应名称查询
     *
     * @param pageInfo
     * @return
     */
    @Override
    public IPage<ProcessTemplate> selectPageProcessTemplate(Page<ProcessTemplate> pageInfo) {

        // 1、调用mapper的方法实现分页查询
        Page<ProcessTemplate> processTemplatePage = baseMapper.selectPage(pageInfo, null);

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

        // 3、 遍历list集合,得到每个对象的审批类型id
        for (ProcessTemplate processTemplate : processTemplateList) {
            // 得到每个对象的审批类型id
            Long processTypeId = processTemplate.getProcessTypeId();

            // 4、 根据审批类型id,查询获取对应名称
            LambdaQueryWrapper<ProcessType> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ProcessType::getId, processTypeId);
            ProcessType processType = processTypeService.getOne(queryWrapper);
            if (processType == null) {
                continue;
            }

            // 5、 完成最终封装processTypeName
            processTemplate.setProcessTypeName(processType.getName());
        }

        return processTemplatePage;
    }

    /**
     * 流程定义部署:修改模板的发布状态 status==1 代表已发布
     *
     * @param id
     */
    @Override
    public void publish(Long id) {
        // 修改模板的发布状态 status==1 代表已发布
        ProcessTemplate processTemplate = baseMapper.selectById(id);
        processTemplate.setStatus(1);
        baseMapper.updateById(processTemplate);

        // 流程定义部署
        if (StringUtils.isEmpty(processTemplate.getProcessDefinitionPath())) {
            processService.deployByZip(processTemplate.getProcessDefinitionPath());
        }
    }

}

2.整合前端

定义api接口

src/api/process/processTemplate.js

import request from '@/utils/request'

const api_name = '/admin/process/processTemplate'

// 新增审批模板
export function saveProcessTemplate(data) {
  return request({
    url: `${api_name}`,
    method: 'post',
    data: data
  })
}

// 删除审批模板
export function removeProcessTemplate(id) {
  return request({
    url: `${api_name}/${id}`,
    method: 'delete'
  })
}

// 修改审批模板
export function updateProcessTemplate(data) {
  return request({
    url: `${api_name}`,
    method: 'put',
    data: data
  })
}

// 查询审批模板详细
export function getProcessTemplate(id) {
  return request({
    url: `${api_name}/${id}`,
    method: 'get'
  })
}

// 查询审批模板列表
export function pageProcessTemplate(pageNum, pageSize, query) {
  return request({
    url: `${api_name}/${pageNum}/${pageSize}`,
    method: 'get',
    params: query
  })
}

// 发布审批模板
export function publish(id) {
  return request({
    url: `${api_name}/publish/${id}`,
    method: 'get'
  })
}

页面展示

src/views/processSet/processTemplate/index.vue

<template>
  <div class="app-container">
    <!-- CRUD -->
    <el-row :gutter="10" class="mb8" style="margin-bottom: 10px">
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
        >添加审批模板
        </el-button>
      </el-col>
      <!-- <el-col :span="1.5">
         <el-button
           type="success"
           plain
           icon="el-icon-edit"
           size="mini"
           :disabled="single"
           @click="handleUpdate"
         >修改
         </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
           v-if="$hasBP('bnt.processTemplate.remove') "
           type="danger"
           plain
           icon="el-icon-delete"
           size="mini"
           :disabled="multiple"
           @click="handleDelete"
         >删除
         </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
           type="warning"
           plain
           icon="el-icon-download"
           size="mini"
           @click="handleExport"
         >导出
         </el-button>
       </el-col>-->
    </el-row>
    <!-- 审批列表 -->
    <el-table
      v-loading="loading"
      :data="processTemplateList"
      border
      header-cell-style="background-color:#EEE;color:#444;height:41px;"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="50" align="center" />
      <el-table-column label="序号" width="70" align="center">
        <template slot-scope="scope">
          {{
            (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1
          }}
        </template>
      </el-table-column>
      <el-table-column
        key="name"
        label="审批名称"
        align="center"
        prop="name"
        :show-overflow-tooltip="true"
      />
      <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
        key="processTypeName"
        label="审批类型"
        align="center"
        prop="processTypeName"
        :show-overflow-tooltip="true"
      />
      <el-table-column
        key="description"
        label="描述"
        align="center"
        prop="description"
        :show-overflow-tooltip="true"
      />
      <el-table-column
        label="创建时间"
        align="center"
        prop="createTime"
        width="160"
        sortable
      />
      <el-table-column
        label="修改时间"
        align="center"
        prop="updateTime"
        width="160"
        sortable
      />
      <el-table-column
        label="操作"
        align="center"
        width="300"
        class-name="small-padding fixed-width"
      >
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-view"
            @click="handleShow(scope.row)"
          >查看审批设置
          </el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
          >修改审批设置
          </el-button>
          <el-button
            v-if="$hasBP('bnt.processTemplate.remove') "
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
          >删除
          </el-button>
          <el-button v-if="scope.row.status == 0" type="text" size="mini" :disabled="$hasBP('bnt.processTemplate.publish') === false" @click="publish(scope.row)">发布</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 查看审批模板对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="35%" append-to-body>
      <h3>基本信息</h3>
      <el-divider />
      <el-form ref="form" :model="form" label-width="80px">
        <el-form-item label="审批类型" prop="processTypeName">{{ form.processTypeName }}</el-form-item>
        <el-form-item label="审批名称" prop="name">{{ form.name }}</el-form-item>
        <el-form-item label="创建时间" prop="createTime">{{ form.createTime }}</el-form-item>
      </el-form>
      <h3>表单信息</h3>
      <el-divider />
      <div>
        <form-create
          :rule="rule"
          :option="option"
        />
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="open = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  pageProcessTemplate, publish,
  removeProcessTemplate,
  saveProcessTemplate,
  updateProcessTemplate
} from '@/api/process/processTemplate'

export default {
  name: 'ProcessTemplate',
  data() {
    return {
      // 查询参数
      queryParams: {
        // 当前页码
        pageNum: 1,
        // 每页记录数
        pageSize: 10
      },
      // 数据是否正在加载
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 审批表格数据
      processTemplateList: null,
      // 弹出层标题
      title: '',
      open: false,
      form: {},
      rule: [],
      option: {}
    }
  },
  created() {
    this.getList()
  },
  methods: {
    /** 查询审批列表 */
    getList() {
      this.loading = true
      pageProcessTemplate(
        this.queryParams.pageNum,
        this.queryParams.pageSize,
        this.queryParams
      ).then((response) => {
        this.processTemplateList = response.data.records
        this.total = response.data.total
        this.loading = false
      })
    },
    // 表单重置
    reset() {
      this.form = {
        id: undefined,
        name: undefined,
        description: undefined
      }
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.$router.push('/processSet/templateSet')
    },
    /** 查看审批设置 */
    handleShow(row) {
      this.title = '查看审批设置'
      this.rule = JSON.parse(row.formProps)
      this.option = JSON.parse(row.formOptions)
      this.form = row
      this.open = true
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      const id = row.id || this.ids
      this.$router.push('/processSet/templateSet?id=' + id)
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids
      this.$confirm('您确定删除名称为[' + row.name + ']的审批模板吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          removeProcessTemplate(ids)
            .then((res) => {
              this.$message.success('删除成功')
              this.getList()
            })
            .catch((err) => {
              this.$message.error('删除失败')
            })
        })
        .catch(() => {
          this.$message.info('已取消删除')
        })
    },
    /** 发布审批模板*/
    publish(row) {
      const id = row.id || this.ids
      this.$confirm('是否确认发布[' + row.name + ']的审批模板吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          publish(id).then(response => {
            this.$message.success('发布成功')
            this.getList()
            // eslint-disable-next-line handle-callback-err
          }).catch(error => {
            this.$message.error('发布失败')
          })
        })
        .catch(() => {
        })
    },
    /** 导出按钮操作 */
    handleExport() {
    },
    /** 导入按钮操作 */
    handleImport() {
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.id)
      this.single = selection.length != 1
      this.multiple = !selection.length
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          if (this.form.id != undefined) {
            updateProcessTemplate(this.form).then((response) => {
              this.$message.success('修改成功')
              this.open = false
              this.getList()
            })
          } else {
            saveProcessTemplate(this.form).then((response) => {
              this.$message.success('新增成功')
              this.open = false
              this.getList()
            })
          }
        }
      })
    },
    /** 取消按钮*/
    cancel() {
      this.open = false
      this.reset()
      this.$refs['form'].resetFields()
    }

  }
}
</script>

<style scoped>

</style>

添加审批模板

1、添加依赖

在package.json文件dependencies添加依赖,

"@form-create/designer": "^1.0.10",
"@form-create/element-ui": "^2.5.33",

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

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

3、模板设置页面

src/views/processSet/processTemplate/templateSet.vue

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

    <div class="tools-div">
      <el-button v-if="stepIndex > 1" icon="el-icon-check" type="primary" size="small" round @click="pre()">上一步
      </el-button>
      <el-button icon="el-icon-check" type="primary" size="small" round @click="next()">{{
        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 v-for="item in processTypeList" :label="item.name" :value="item.id" />
          </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 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 ref="designer" class="form-build" />
    </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" />
        <div class="el-upload__text">将Activiti流程设计文件拖到此处,或<em>点击上传</em></div>
        <div slot="tip" class="el-upload__tip">只能上传zip压缩文件,且不超过2048kb</div>
      </el-upload>
    </div>
  </div>
</template>

<script>
import store from '@/store'
import { findAll } from '@/api/process/processType'
import { getProcessTemplate, saveProcessTemplate, updateProcessTemplate } from '@/api/process/processTemplate'

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() {
    const 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() {
      findAll().then(response => {
        this.processTypeList = response.data
      })
    },
    fetchDataById(id) {
      getProcessTemplate(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() {
      saveProcessTemplate(this.processTemplate).then(response => {
        this.$router.push('/processSet/processTemplate')
      })
    },

    // 根据id更新记录
    updateData() {
      updateProcessTemplate(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>

3.审批列表

1.CRUD后台

com.atguigu.process.controller.OaProcessController

@Api(value = "审批列表管理", tags = "审批列表管理")
@RestController
@RequestMapping(value = "/admin/process")
public class OaProcessController {
    @Autowired
    private OaProcessService processService;

    /**
     * 审批列表管理
     *
     * @param pageNum
     * @param pageSize
     * @param processQueryVo
     * @return
     */
    @ApiOperation(value = "获取分页列表")
    @GetMapping("/{pageNum}/{pageSize}")
    public Result index(@PathVariable Long pageNum,
                        @PathVariable Long pageSize,
                        ProcessQueryVo processQueryVo) {
        Page<ProcessVo> pageInfo = new Page<>(pageNum, pageSize);

        IPage<ProcessVo> pageModel = processService.selectPage(pageInfo, processQueryVo);

        return Result.ok(pageModel);
    }
}

com.atguigu.process.service.impl.OaProcessServiceImpl

@Service
public class OaProcessServiceImpl extends ServiceImpl<OaProcessMapper, Process> implements OaProcessService {
    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private OaProcessTemplateService processTemplateService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private OaProcessRecordService processRecordService;

    @Autowired
    private HistoryService historyService;

    /**
     * 审批管理列表
     *
     * @param pageInfo
     * @param processQueryVo
     * @return
     */
    @Override
    public IPage<ProcessVo> selectPage(Page<ProcessVo> pageInfo, ProcessQueryVo processQueryVo) {
        IPage<ProcessVo> pageModel = baseMapper.selectPage(pageInfo, processQueryVo);
        return pageModel;
    }

    /**
     * 流程定义部署
     *
     * @param deployPath
     */
    @Override
    public void deployByZip(String deployPath) {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(deployPath);
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        // 部署
        Deployment deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy();

        System.out.println("deployment.getId() = " + deployment.getId());
        System.out.println("deployment.getName() = " + deployment.getName());
    }
}

com.atguigu.process.mapper.OaProcessMapper

public interface OaProcessMapper extends BaseMapper<Process> {
    //审批管理列表
    IPage<ProcessVo> selectPage(Page<ProcessVo> pageInfo, @Param("vo") ProcessQueryVo processQueryVo);
}

src/main/resources/mapper/OaProcessMapper.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.atguigu.process.mapper.OaProcessMapper">
    <select id="selectPage" resultType="com.atguigu.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},'%'))
            </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 &lt;= #{vo.createTimeEnd}
            </if>
        </where>

    </select>
</mapper>

2.整合前端

定义api接口请求函数

src/api/process/process.js

import request from '@/utils/request'

const api_name = '/admin/process'

// 查询审批类型列表
export function pageProcess(pageNum, pageSize, query) {
  return request({
    url: `${api_name}/${pageNum}/${pageSize}`,
    method: 'get',
    params: query
  })
}

页面在展示

src/views/processMgr/process/index.vue

<template>
  <div class="app-container">
    <!-- 查询条件 -->
    <el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
      <el-form-item label="关键字" prop="keyword">
        <el-input
          v-model="queryParams.keyword"
          placeholder="审批编号/标题/手机号码/姓名"
          clearable
          style="width: 250px"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="状态">
        <el-select
          v-model="queryParams.status"
          placeholder="请选择状态"
        >
          <el-option
            v-for="item in statusList"
            :key="item.status"
            :label="item.name"
            :value="item.status"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="操作时间">
        <el-date-picker
          v-model="createTimes"
          type="datetimerange"
          :picker-options="pickerOptions"
          value-format="yyyy-MM-dd HH:mm:ss"
          range-separator=""
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          style="width: 360px"
        />
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          icon="el-icon-search"
          size="mini"
          @click="handleQuery"
        >搜索
        </el-button>
        <el-button
          icon="el-icon-refresh"
          size="mini"
          @click="resetQuery"
        >重置
        </el-button>
      </el-form-item>
    </el-form>

    <!-- 审批列表 -->
    <el-table
      v-loading="loading"
      :data="processList"
      border
      header-cell-style="background-color:#EEE;color:#444;height:41px;"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="50" align="center" />
      <el-table-column label="序号" width="70" align="center">
        <template slot-scope="scope">
          {{
            (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1
          }}
        </template>
      </el-table-column>
      <el-table-column
        key="processCode"
        label="审批编号"
        align="center"
        prop="processCode"
        :show-overflow-tooltip="true"
      />
      <el-table-column
        key="title"
        label="标题"
        align="center"
        prop="title"
        :show-overflow-tooltip="true"
      />
      <el-table-column
        key="name"
        label="审批"
        align="center"
        prop="name"
        :show-overflow-tooltip="true"
      />
      <el-table-column
        key="processTypeName"
        label="审批类型"
        align="center"
        prop="processTypeName"
        :show-overflow-tooltip="true"
      />
      <el-table-column
        key="processTemplateName"
        label="审批模板"
        align="center"
        prop="processTemplateName"
        :show-overflow-tooltip="true"
      />
      <el-table-column
        key="description"
        label="描述"
        align="center"
        prop="description"
        :show-overflow-tooltip="true"
      />

      <el-table-column key="status" label="状态" align="center">
        <template slot-scope="scope">
          <span> {{ scope.row.status === 1 ? '审批中' : scope.row.status === 2 ? '完成' : '驳回' }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="创建时间"
        align="center"
        prop="createTime"
        width="160"
        sortable
      />
      <el-table-column
        label="操作"
        align="center"
        width="120"
        class-name="small-padding fixed-width"
      >
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-view"
            @click="handleShow(scope.row)"
          >查看
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />
  </div>
</template>

<script>
import { pageProcess } from '@/api/process/process'

export default {
  name: 'Process',
  data() {
    return {
      // 查询参数
      queryParams: {
        // 当前页码
        pageNum: 1,
        // 每页记录数
        pageSize: 10,
        // 关键字
        keyword: undefined,
        status: undefined,
        createTimeBegin: undefined,
        createTimeEnd: undefined
      },
      // 状态选项
      statusList: [
        { 'status': '1', 'name': '进行中' },
        { 'status': '2', 'name': '已完成' },
        { 'status': '-1', 'name': '驳回' }
      ],
      // 创建时间
      createTimes: [],
      // 时间日期选择器快捷选项
      pickerOptions: {
        shortcuts: [{
          text: '最近一周',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近一个月',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近三个月',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近半年',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 183)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近一年',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 365)
            picker.$emit('pick', [start, end])
          }
        }
        ]
      },
      // 数据是否正在加载
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 审批表格数据
      processList: null,
      // 弹出层标题
      title: '',
      // 是否显示弹出层
      open: false,
      // 表单参数
      form: {}
    }
  },
  created() {
    this.getList()
  },
  methods: {
    /** 查询审批列表 */
    getList() {
      this.loading = true
      if (this.createTimes && this.createTimes.length === 2) {
        this.queryParams.createTimeBegin = this.createTimes[0]
        this.queryParams.createTimeEnd = this.createTimes[1]
      } else {
        this.queryParams.createTimeBegin = undefined
        this.queryParams.createTimeEnd = undefined
      }
      pageProcess(
        this.queryParams.pageNum,
        this.queryParams.pageSize,
        this.queryParams
      ).then((response) => {
        this.processList = response.data.records
        console.log('审批列表:', this.processList)
        this.total = response.data.total
        this.loading = false
      })
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.createTimes = []
      this.$refs['queryForm'].resetFields()
      this.handleQuery()
    },
    // 表单重置
    reset() {
      this.form = {
        id: undefined,
        username: undefined,
        name: undefined,
        password: undefined,
        phone: undefined,
        description: undefined
      }
    },
    /** 查看按钮操作 */
    handleShow(row) {
      this.reset()
      const id = row.id || this.ids
      // getUser(id).then((response) => {
      //   this.form = response.data
      //   this.open = true
      //   this.title = '查看审批详情'
      // })
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.id)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    }
  }
}
</script>

<style scoped>

</style>
根据引用的解释,云尚办公集成knife4j出现空指针异常的原因可能是无法找到knife4j的任何版本。解决方案是通过project structure配置libraries,并通过Maven从正确的依赖中安装knife4j。此外,根据引用,knife4j是一个为Java MVC框架集成Swagger生成Api文档的增强解决方案。因此,集成knife4j可以帮助你生成和管理Api文档。 另外,引用提到,作者在练习云尚办公项目时遇到了一些问题,并对项目提出了一些其他的见解。然而,具体关于云尚办公集成knife4j出现空指针异常的详细问题没有在提供的引用中找到。如果你能提供更多关于空指针异常的细节,我将能够更好地帮助你解决问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [尚硅谷-云尚办公-项目复盘](https://blog.csdn.net/qq_47168235/article/details/130468136)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [云尚办公系统学习笔记(1.基础设置)](https://blog.csdn.net/Kiritoasu/article/details/130726289)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值