Kaynağa Gözat

:zap: 增加我的事务列表页

smallchill 7 yıl önce
ebeveyn
işleme
4fda69bcfb

+ 79 - 0
src/api/work/work.js

@@ -0,0 +1,79 @@
+import request from '@/router/axios';
+
+export const startList = (current, size, params) => {
+  return request({
+    url: '/api/blade-flow/work/start-list',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+    }
+  })
+}
+
+export const claimList = (current, size, params) => {
+  return request({
+    url: '/api/blade-flow/work/claim-list',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+    }
+  })
+}
+
+export const todoList = (current, size, params) => {
+  return request({
+    url: '/api/blade-flow/work/todo-list',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+    }
+  })
+}
+
+export const sendList = (current, size, params) => {
+  return request({
+    url: '/api/blade-flow/work/send-list',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+    }
+  })
+}
+
+
+export const doneList = (current, size, params) => {
+  return request({
+    url: '/api/blade-flow/work/done-list',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+    }
+  })
+}
+
+export const claimTask = (params) => {
+  return request({
+    url: '/api/blade-flow/work/claim-task',
+    method: 'post',
+    params
+  })
+}
+
+
+export const completeTask = (data) => {
+  return request({
+    url: '/api/blade-flow/work/complete-task',
+    method: 'post',
+    data
+  })
+}

+ 4 - 0
src/views/flow/follow.vue

@@ -154,4 +154,8 @@
 </script>
 
 <style>
+  .none-border {
+    border: 0;
+    background-color: transparent!important;
+  }
 </style>

+ 12 - 4
src/views/flow/manager.vue

@@ -6,9 +6,6 @@
                v-model="form"
                :page="page"
                :permission="permissionList"
-               @row-del="rowDel"
-               @row-update="rowUpdate"
-               @row-save="rowSave"
                @search-change="searchChange"
                @search-reset="searchReset"
                @selection-change="selectionChange"
@@ -27,18 +24,21 @@
                    size="small"
                    v-if="permission.flow_manager_state"
                    plain
+                   class="none-border"
                    @click.stop="handleState(scope.row,scope.index)">变更状态
         </el-button>
         <el-button type="text"
                    size="small"
                    v-if="permission.flow_manager_image"
                    plain
+                   class="none-border"
                    @click.stop="handleImage(scope.row,scope.index)">流程图
         </el-button>
         <el-button type="text"
                    size="small"
                    v-if="permission.flow_manager_remove"
                    plain
+                   class="none-border"
                    @click.stop="handleSlotDelete(scope.row,scope.index)">删除
         </el-button>
       </template>
@@ -290,7 +290,11 @@
         this.flowBox = true;
       },
       onLoad(page, params = {}) {
-        managerList(page.currentPage, page.pageSize, params).then(res => {
+        const values = {
+          ...params,
+          category: (params.category) ? `flow_${params.category}` : null
+        }
+        managerList(page.currentPage, page.pageSize, values).then(res => {
           const data = res.data.data;
           this.page.total = data.total;
           this.data = data.records;
@@ -301,4 +305,8 @@
 </script>
 
 <style>
+  .none-border {
+    border: 0;
+    background-color: transparent!important;
+  }
 </style>

+ 8 - 0
src/views/flow/model.vue

@@ -30,24 +30,28 @@
                    size="small"
                    v-if="permission.flow_model_update"
                    plain
+                   class="none-border"
                    @click.stop="handleUpdate(scope.row,scope.index)">配置
         </el-button>
         <el-button type="text"
                    size="small"
                    v-if="permission.flow_model_deploy"
                    plain
+                   class="none-border"
                    @click.stop="handleDeploy(scope.row,scope.index)">部署
         </el-button>
         <el-button type="text"
                    size="small"
                    v-if="permission.flow_model_download"
                    plain
+                   class="none-border"
                    @click.stop="handleDownload(scope.row,scope.index)">下载
         </el-button>
         <el-button type="text"
                    size="small"
                    v-if="permission.flow_model_delete"
                    plain
+                   class="none-border"
                    @click.stop="handleSlotDelete(scope.row,scope.index)">删除
         </el-button>
       </template>
@@ -289,4 +293,8 @@
 </script>
 
 <style>
+  .none-border {
+    border: 0;
+    background-color: transparent!important;
+  }
 </style>

+ 179 - 0
src/views/work/claim.vue

@@ -0,0 +1,179 @@
+<template>
+  <basic-container>
+    <avue-crud :option="option"
+               :data="data"
+               ref="crud"
+               v-model="form"
+               :page="page"
+               @search-change="searchChange"
+               @search-reset="searchReset"
+               @selection-change="selectionChange"
+               @on-load="onLoad">
+      <template slot-scope="scope" slot="menu">
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_claim_sign"
+                   plain
+                   class="none-border"
+                   @click.stop="handleClaim(scope.row)">签收
+        </el-button>
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_claim_detail"
+                   plain
+                   class="none-border"
+                   @click.stop="handleDetail(scope.row)">详情
+        </el-button>
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_claim_follow"
+                   plain
+                   class="none-border"
+                   @click.stop="handleImage(scope.row,scope.index)">跟踪
+        </el-button>
+      </template>
+      <template slot-scope="{row}"
+                slot="processDefinitionVersion">
+        <el-tag>v{{row.processDefinitionVersion}}</el-tag>
+      </template>
+    </avue-crud>
+    <el-dialog title="流程图"
+               :visible.sync="flowBox"
+               fullscreen=true>
+      <iframe
+        :src=flowUrl
+        width="100%"
+        height="700"
+        title="流程图"
+        frameBorder="no"
+        border="0"
+        marginWidth="0"
+        marginHeight="0"
+        scrolling="no"
+        allowTransparency="yes">
+      </iframe>
+      <span slot="footer"
+            class="dialog-footer">
+        <el-button @click="flowBox = false">关 闭</el-button>
+      </span>
+    </el-dialog>
+  </basic-container>
+</template>
+
+<script>
+  import {claimList} from "@/api/work/work";
+  import {mapGetters} from "vuex";
+
+  export default {
+    data() {
+      return {
+        form: {},
+        selectionId: '',
+        selectionList: [],
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        flowBox: false,
+        flowUrl: '',
+        workBox: false,
+        option: {
+          tip: false,
+          border: true,
+          index: true,
+          selection: true,
+          editBtn: false,
+          addBtn: false,
+          viewBtn: false,
+          delBtn: false,
+          dialogWidth: 300,
+          dialogHeight: 400,
+          column: [
+            {
+              label: "流程分类",
+              type: "select",
+              row: true,
+              dicUrl: "/api/blade-system/dict/dictionary?code=flow",
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              slot: true,
+              prop: "category",
+              search: true,
+              hide: true,
+            },
+            {
+              label: '流程名称',
+              prop: 'processDefinitionName',
+            },
+            {
+              label: '当前步骤',
+              prop: 'taskName',
+            },
+            {
+              label: '流程版本',
+              prop: 'processDefinitionVersion',
+              slot: true,
+            },
+            {
+              label: '申请时间',
+              prop: 'createTime',
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      },
+    },
+    methods: {
+      searchReset() {
+        this.onLoad(this.page);
+      },
+      searchChange(params) {
+        this.onLoad(this.page, params);
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      handleClaim(row) {
+
+      },
+      handleDetail(row) {
+        this.$router.push({path: `/work/process/${this.routes[row.category]}/detail?processInstanceId=${row.processInstanceId}&businessId=${row.businessId}`});
+      },
+      handleImage(row) {
+        this.flowUrl = `/api/blade-flow/process/diagram-view?processInstanceId=${row.processInstanceId}`;
+        this.flowBox = true;
+      },
+      onLoad(page, params = {}) {
+        const values = {
+          ...params,
+          category: (params.category) ? `flow_${params.category}` : null
+        }
+        claimList(page.currentPage, page.pageSize, values).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+        });
+      }
+    }
+  };
+</script>
+
+<style>
+  .none-border {
+    border: 0;
+    background-color: transparent !important;
+  }
+</style>

+ 169 - 0
src/views/work/done.vue

@@ -0,0 +1,169 @@
+<template>
+  <basic-container>
+    <avue-crud :option="option"
+               :data="data"
+               ref="crud"
+               v-model="form"
+               :page="page"
+               @search-change="searchChange"
+               @search-reset="searchReset"
+               @selection-change="selectionChange"
+               @on-load="onLoad">
+      <template slot-scope="scope" slot="menu">
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_done_detail"
+                   plain
+                   class="none-border"
+                   @click.stop="handleDetail(scope.row)">详情
+        </el-button>
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_done_follow"
+                   plain
+                   class="none-border"
+                   @click.stop="handleImage(scope.row,scope.index)">跟踪
+        </el-button>
+      </template>
+      <template slot-scope="{row}"
+                slot="processDefinitionVersion">
+        <el-tag>v{{row.processDefinitionVersion}}</el-tag>
+      </template>
+    </avue-crud>
+    <el-dialog title="流程图"
+               :visible.sync="flowBox"
+               fullscreen=true>
+      <iframe
+        :src=flowUrl
+        width="100%"
+        height="700"
+        title="流程图"
+        frameBorder="no"
+        border="0"
+        marginWidth="0"
+        marginHeight="0"
+        scrolling="no"
+        allowTransparency="yes">
+      </iframe>
+      <span slot="footer"
+            class="dialog-footer">
+        <el-button @click="flowBox = false">关 闭</el-button>
+      </span>
+    </el-dialog>
+  </basic-container>
+</template>
+
+<script>
+  import {doneList} from "@/api/work/work";
+  import {mapGetters} from "vuex";
+
+  export default {
+    data() {
+      return {
+        form: {},
+        selectionId: '',
+        selectionList: [],
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        flowBox: false,
+        flowUrl: '',
+        workBox: false,
+        option: {
+          tip: false,
+          border: true,
+          index: true,
+          selection: true,
+          editBtn: false,
+          addBtn: false,
+          viewBtn: false,
+          delBtn: false,
+          dialogWidth: 300,
+          dialogHeight: 400,
+          column: [
+            {
+              label: "流程分类",
+              type: "select",
+              row: true,
+              dicUrl: "/api/blade-system/dict/dictionary?code=flow",
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              slot: true,
+              prop: "category",
+              search: true,
+              hide: true,
+            },
+            {
+              label: '流程名称',
+              prop: 'processDefinitionName',
+            },
+            {
+              label: '当前步骤',
+              prop: 'taskName',
+            },
+            {
+              label: '流程版本',
+              prop: 'processDefinitionVersion',
+              slot: true,
+            },
+            {
+              label: '申请时间',
+              prop: 'createTime',
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      },
+    },
+    methods: {
+      searchReset() {
+        this.onLoad(this.page);
+      },
+      searchChange(params) {
+        this.onLoad(this.page, params);
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      handleDetail(row) {
+        this.$router.push({path: `/work/process/${this.routes[row.category]}/detail?processInstanceId=${row.processInstanceId}&businessId=${row.businessId}`});
+      },
+      handleImage(row) {
+        this.flowUrl = `/api/blade-flow/process/diagram-view?processInstanceId=${row.processInstanceId}`;
+        this.flowBox = true;
+      },
+      onLoad(page, params = {}) {
+        const values = {
+          ...params,
+          category: (params.category) ? `flow_${params.category}` : null
+        }
+        doneList(page.currentPage, page.pageSize, values).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+        });
+      }
+    }
+  };
+</script>
+
+<style>
+  .none-border {
+    border: 0;
+    background-color: transparent !important;
+  }
+</style>

+ 65 - 0
src/views/work/process/leave/detail.vue

@@ -0,0 +1,65 @@
+<template>
+  <basic-container>
+    <avue-form :option="option" v-model="form" :upload-before="uploadBefore" :upload-after="uploadAfter"></avue-form>
+  </basic-container>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        form: {
+          imgUrl: [],
+        },
+        option: {
+          labelWidth: 120,
+          column: [
+            {
+              label: '流程类型',
+              prop: 'flowCategory',
+              type: 'select',
+              dicUrl: `/api/blade-system/dict/dictionary?code=flow`,
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              rules: [
+                {
+                  required: true,
+                  message: '请选择流程类型',
+                  trigger: 'blur'
+                }
+              ]
+            },
+            {
+              label: '附件上传',
+              prop: 'imgUrl',
+              type: 'upload',
+              loadText: '附件上传中,请稍等',
+              span: 24,
+              propsHttp: {
+                res: 'data.0'
+              },
+              tip: '请上传 bpmn20.xml 标准格式文件',
+            },
+          ]
+        }
+      }
+    },
+    methods: {
+      uploadBefore(file, done, loading) {
+        console.log(file)
+        done()
+        this.$message.success('上传前的方法')
+      },
+      uploadAfter(res, done, loading) {
+        console.log(res)
+        done()
+        this.$message.success('上传后的方法')
+      },
+      submit() {
+        this.$message.success('当前数据' + JSON.stringify(this.form))
+      }
+    }
+  }
+</script>

+ 65 - 0
src/views/work/process/leave/form.vue

@@ -0,0 +1,65 @@
+<template>
+  <basic-container>
+    <avue-form :option="option" v-model="form" :upload-before="uploadBefore" :upload-after="uploadAfter"></avue-form>
+  </basic-container>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        form: {
+          imgUrl: [],
+        },
+        option: {
+          labelWidth: 120,
+          column: [
+            {
+              label: '流程类型',
+              prop: 'flowCategory',
+              type: 'select',
+              dicUrl: `/api/blade-system/dict/dictionary?code=flow`,
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              rules: [
+                {
+                  required: true,
+                  message: '请选择流程类型',
+                  trigger: 'blur'
+                }
+              ]
+            },
+            {
+              label: '附件上传',
+              prop: 'imgUrl',
+              type: 'upload',
+              loadText: '附件上传中,请稍等',
+              span: 24,
+              propsHttp: {
+                res: 'data.0'
+              },
+              tip: '请上传 bpmn20.xml 标准格式文件',
+            },
+          ]
+        }
+      }
+    },
+    methods: {
+      uploadBefore(file, done, loading) {
+        console.log(file)
+        done()
+        this.$message.success('上传前的方法')
+      },
+      uploadAfter(res, done, loading) {
+        console.log(res)
+        done()
+        this.$message.success('上传后的方法')
+      },
+      submit() {
+        this.$message.success('当前数据' + JSON.stringify(this.form))
+      }
+    }
+  }
+</script>

+ 65 - 0
src/views/work/process/leave/handle.vue

@@ -0,0 +1,65 @@
+<template>
+  <basic-container>
+    <avue-form :option="option" v-model="form" :upload-before="uploadBefore" :upload-after="uploadAfter"></avue-form>
+  </basic-container>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        form: {
+          imgUrl: [],
+        },
+        option: {
+          labelWidth: 120,
+          column: [
+            {
+              label: '流程类型',
+              prop: 'flowCategory',
+              type: 'select',
+              dicUrl: `/api/blade-system/dict/dictionary?code=flow`,
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              rules: [
+                {
+                  required: true,
+                  message: '请选择流程类型',
+                  trigger: 'blur'
+                }
+              ]
+            },
+            {
+              label: '附件上传',
+              prop: 'imgUrl',
+              type: 'upload',
+              loadText: '附件上传中,请稍等',
+              span: 24,
+              propsHttp: {
+                res: 'data.0'
+              },
+              tip: '请上传 bpmn20.xml 标准格式文件',
+            },
+          ]
+        }
+      }
+    },
+    methods: {
+      uploadBefore(file, done, loading) {
+        console.log(file)
+        done()
+        this.$message.success('上传前的方法')
+      },
+      uploadAfter(res, done, loading) {
+        console.log(res)
+        done()
+        this.$message.success('上传后的方法')
+      },
+      submit() {
+        this.$message.success('当前数据' + JSON.stringify(this.form))
+      }
+    }
+  }
+</script>

+ 178 - 0
src/views/work/send.vue

@@ -0,0 +1,178 @@
+<template>
+  <basic-container>
+    <avue-crud :option="option"
+               :data="data"
+               ref="crud"
+               v-model="form"
+               :page="page"
+               @search-change="searchChange"
+               @search-reset="searchReset"
+               @selection-change="selectionChange"
+               @on-load="onLoad">
+      <template slot-scope="scope" slot="menu">
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_send_detail"
+                   plain
+                   class="none-border"
+                   @click.stop="handleDetail(scope.row)">详情
+        </el-button>
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_send_follow"
+                   plain
+                   class="none-border"
+                   @click.stop="handleImage(scope.row,scope.index)">跟踪
+        </el-button>
+      </template>
+      <template slot-scope="{row}"
+                slot="processDefinitionVersion">
+        <el-tag>v{{row.processDefinitionVersion}}</el-tag>
+      </template>
+      <template slot-scope="{row}"
+                slot="processIsFinished">
+        <el-tag>{{row.processIsFinished==='finished' ? '已完成' : '未完成'}}</el-tag>
+      </template>
+    </avue-crud>
+    <el-dialog title="流程图"
+               :visible.sync="flowBox"
+               fullscreen=true>
+      <iframe
+        :src=flowUrl
+        width="100%"
+        height="700"
+        title="流程图"
+        frameBorder="no"
+        border="0"
+        marginWidth="0"
+        marginHeight="0"
+        scrolling="no"
+        allowTransparency="yes">
+      </iframe>
+      <span slot="footer"
+            class="dialog-footer">
+        <el-button @click="flowBox = false">关 闭</el-button>
+      </span>
+    </el-dialog>
+  </basic-container>
+</template>
+
+<script>
+  import {sendList} from "@/api/work/work";
+  import {mapGetters} from "vuex";
+
+  export default {
+    data() {
+      return {
+        form: {},
+        selectionId: '',
+        selectionList: [],
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        flowBox: false,
+        flowUrl: '',
+        workBox: false,
+        option: {
+          tip: false,
+          border: true,
+          index: true,
+          selection: true,
+          editBtn: false,
+          addBtn: false,
+          viewBtn: false,
+          delBtn: false,
+          dialogWidth: 300,
+          dialogHeight: 400,
+          column: [
+            {
+              label: "流程分类",
+              type: "select",
+              row: true,
+              dicUrl: "/api/blade-system/dict/dictionary?code=flow",
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              slot: true,
+              prop: "category",
+              search: true,
+              hide: true,
+            },
+            {
+              label: '流程名称',
+              prop: 'processDefinitionName',
+            },
+            {
+              label: '当前步骤',
+              prop: 'taskName',
+            },
+            {
+              label: '流程版本',
+              prop: 'processDefinitionVersion',
+              slot: true,
+            },
+            {
+              label: '流程进度',
+              prop: 'processIsFinished',
+              slot: true,
+            },
+            {
+              label: '申请时间',
+              prop: 'createTime',
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      },
+    },
+    methods: {
+      searchReset() {
+        this.onLoad(this.page);
+      },
+      searchChange(params) {
+        this.onLoad(this.page, params);
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      handleDetail(row) {
+        this.$router.push({path: `/work/process/${this.routes[row.category]}/detail?processInstanceId=${row.processInstanceId}&businessId=${row.businessId}`});
+      },
+      handleImage(row) {
+        this.flowUrl = `/api/blade-flow/process/diagram-view?processInstanceId=${row.processInstanceId}`;
+        this.flowBox = true;
+      },
+      onLoad(page, params = {}) {
+        const values = {
+          ...params,
+          category: (params.category) ? `flow_${params.category}` : null
+        }
+        sendList(page.currentPage, page.pageSize, values).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+        });
+      }
+    }
+  };
+</script>
+
+<style>
+  .none-border {
+    border: 0;
+    background-color: transparent !important;
+  }
+</style>

+ 185 - 0
src/views/work/start.vue

@@ -0,0 +1,185 @@
+<template>
+  <basic-container>
+    <avue-crud :option="option"
+               :data="data"
+               ref="crud"
+               v-model="form"
+               :page="page"
+               @search-change="searchChange"
+               @search-reset="searchReset"
+               @selection-change="selectionChange"
+               @on-load="onLoad">
+      <template slot-scope="scope" slot="menu">
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_start_flow"
+                   plain
+                   class="none-border"
+                   @click.stop="handleStart(scope.row)">发起
+        </el-button>
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_start_image"
+                   plain
+                   class="none-border"
+                   @click.stop="handleImage(scope.row,scope.index)">流程图
+        </el-button>
+      </template>
+      <template slot-scope="{row}"
+                slot="version">
+        <el-tag>v{{row.version}}</el-tag>
+      </template>
+      <template slot-scope="{row}"
+                slot="suspensionState">
+        <el-tag>{{row.suspensionState===1?'激活':'挂起'}}</el-tag>
+      </template>
+      <template slot-scope="{row}"
+                slot="category">
+        <el-tag>{{row.categoryName}}</el-tag>
+      </template>
+    </avue-crud>
+    <el-dialog title="流程图"
+               :visible.sync="flowBox"
+               fullscreen=true>
+      <iframe
+        :src=flowUrl
+        width="100%"
+        height="700"
+        title="流程图"
+        frameBorder="no"
+        border="0"
+        marginWidth="0"
+        marginHeight="0"
+        scrolling="no"
+        allowTransparency="yes">
+      </iframe>
+      <span slot="footer"
+            class="dialog-footer">
+        <el-button @click="flowBox = false">关 闭</el-button>
+      </span>
+    </el-dialog>
+  </basic-container>
+</template>
+
+<script>
+  import {startList} from "@/api/work/work";
+  import {mapGetters} from "vuex";
+
+  export default {
+    data() {
+      return {
+        routes: {
+          flow_1: 'leave',
+          flow_2: 'expense',
+        },
+        form: {},
+        selectionId: '',
+        selectionList: [],
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        flowBox: false,
+        flowUrl: '',
+        workBox: false,
+        option: {
+          tip: false,
+          border: true,
+          index: true,
+          selection: true,
+          editBtn: false,
+          addBtn: false,
+          viewBtn: false,
+          delBtn: false,
+          dialogWidth: 300,
+          dialogHeight: 400,
+          column: [
+            {
+              label: "流程分类",
+              type: "select",
+              row: true,
+              dicUrl: "/api/blade-system/dict/dictionary?code=flow",
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              slot: true,
+              prop: "category",
+              search: true,
+            },
+            {
+              label: '流程标识',
+              prop: 'key',
+            },
+            {
+              label: '流程名称',
+              prop: 'name',
+            },
+            {
+              label: '流程版本',
+              prop: 'version',
+              slot: true,
+            },
+            {
+              label: '状态',
+              prop: 'suspensionState',
+              slot: true,
+            },
+            {
+              label: '部署时间',
+              prop: 'deploymentTime',
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      },
+    },
+    methods: {
+      searchReset() {
+        this.onLoad(this.page);
+      },
+      searchChange(params) {
+        this.onLoad(this.page, params);
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      handleStart(row) {
+        this.$router.push({ path: `/work/process/${this.routes[row.category]}/form?id=${row.id}` });
+      },
+      handleImage(row) {
+        this.flowUrl = `/api/blade-flow/process/resource-view?processDefinitionId=${row.id}`;
+        this.flowBox = true;
+      },
+      onLoad(page, params = {}) {
+        const values = {
+          ...params,
+          category: (params.category) ? `flow_${params.category}` : null
+        }
+        startList(page.currentPage, page.pageSize, values).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+        });
+      }
+    }
+  };
+</script>
+
+<style>
+  .none-border {
+    border: 0;
+    background-color: transparent !important;
+  }
+</style>

+ 179 - 0
src/views/work/todo.vue

@@ -0,0 +1,179 @@
+<template>
+  <basic-container>
+    <avue-crud :option="option"
+               :data="data"
+               ref="crud"
+               v-model="form"
+               :page="page"
+               @search-change="searchChange"
+               @search-reset="searchReset"
+               @selection-change="selectionChange"
+               @on-load="onLoad">
+      <template slot-scope="scope" slot="menu">
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_todo_handle"
+                   plain
+                   class="none-border"
+                   @click.stop="handleWork(scope.row)">处理
+        </el-button>
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_todo_detail"
+                   plain
+                   class="none-border"
+                   @click.stop="handleDetail(scope.row)">详情
+        </el-button>
+        <el-button type="text"
+                   size="small"
+                   v-if="permission.work_todo_follow"
+                   plain
+                   class="none-border"
+                   @click.stop="handleImage(scope.row,scope.index)">跟踪
+        </el-button>
+      </template>
+      <template slot-scope="{row}"
+                slot="processDefinitionVersion">
+        <el-tag>v{{row.processDefinitionVersion}}</el-tag>
+      </template>
+    </avue-crud>
+    <el-dialog title="流程图"
+               :visible.sync="flowBox"
+               fullscreen=true>
+      <iframe
+        :src=flowUrl
+        width="100%"
+        height="700"
+        title="流程图"
+        frameBorder="no"
+        border="0"
+        marginWidth="0"
+        marginHeight="0"
+        scrolling="no"
+        allowTransparency="yes">
+      </iframe>
+      <span slot="footer"
+            class="dialog-footer">
+        <el-button @click="flowBox = false">关 闭</el-button>
+      </span>
+    </el-dialog>
+  </basic-container>
+</template>
+
+<script>
+  import {todoList} from "@/api/work/work";
+  import {mapGetters} from "vuex";
+
+  export default {
+    data() {
+      return {
+        form: {},
+        selectionId: '',
+        selectionList: [],
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        flowBox: false,
+        flowUrl: '',
+        workBox: false,
+        option: {
+          tip: false,
+          border: true,
+          index: true,
+          selection: true,
+          editBtn: false,
+          addBtn: false,
+          viewBtn: false,
+          delBtn: false,
+          dialogWidth: 300,
+          dialogHeight: 400,
+          column: [
+            {
+              label: "流程分类",
+              type: "select",
+              row: true,
+              dicUrl: "/api/blade-system/dict/dictionary?code=flow",
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              slot: true,
+              prop: "category",
+              search: true,
+              hide: true,
+            },
+            {
+              label: '流程名称',
+              prop: 'processDefinitionName',
+            },
+            {
+              label: '当前步骤',
+              prop: 'taskName',
+            },
+            {
+              label: '流程版本',
+              prop: 'processDefinitionVersion',
+              slot: true,
+            },
+            {
+              label: '申请时间',
+              prop: 'createTime',
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      },
+    },
+    methods: {
+      searchReset() {
+        this.onLoad(this.page);
+      },
+      searchChange(params) {
+        this.onLoad(this.page, params);
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      handleWork(row) {
+
+      },
+      handleDetail(row) {
+        this.$router.push({ path: `/work/process/${this.routes[row.category]}/detail?processInstanceId=${row.processInstanceId}&businessId=${row.businessId}` });
+      },
+      handleImage(row) {
+        this.flowUrl = `/api/blade-flow/process/diagram-view?processInstanceId=${row.processInstanceId}`;
+        this.flowBox = true;
+      },
+      onLoad(page, params = {}) {
+        const values = {
+          ...params,
+          category: (params.category) ? `flow_${params.category}` : null
+        }
+        todoList(page.currentPage, page.pageSize, values).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+        });
+      }
+    }
+  };
+</script>
+
+<style>
+  .none-border {
+    border: 0;
+    background-color: transparent !important;
+  }
+</style>