linwei
2024-02-19 4ad3abe30fa55efbb0f7c27dbf43ebe74dabb273
维修基金审核优化
5 files modified
14 files added
4614 ■■■■ changed files
src/router/views/index.js 178 ●●●●● patch | view | raw | blame | history
src/views/gzll/process/leave/detail.vue 107 ●●●●● patch | view | raw | blame | history
src/views/gzll/process/leave/form.vue 112 ●●●●● patch | view | raw | blame | history
src/views/gzll/process/leave/handle.vue 169 ●●●●● patch | view | raw | blame | history
src/views/gzll/process/maintenanceFundApply/detail.vue 325 ●●●●● patch | view | raw | blame | history
src/views/gzll/process/maintenanceFundApply/edit.vue 419 ●●●●● patch | view | raw | blame | history
src/views/gzll/process/maintenanceFundApply/form.vue 267 ●●●●● patch | view | raw | blame | history
src/views/gzll/process/maintenanceFundApply/handle.vue 419 ●●●●● patch | view | raw | blame | history
src/views/gzll/todo.vue 395 ●●●● patch | view | raw | blame | history
src/views/property/process/leave/detail.vue 107 ●●●●● patch | view | raw | blame | history
src/views/property/process/leave/form.vue 112 ●●●●● patch | view | raw | blame | history
src/views/property/process/leave/handle.vue 169 ●●●●● patch | view | raw | blame | history
src/views/property/process/maintenanceFundApply/detail.vue 325 ●●●●● patch | view | raw | blame | history
src/views/property/process/maintenanceFundApply/edit.vue 419 ●●●●● patch | view | raw | blame | history
src/views/property/process/maintenanceFundApply/form.vue 267 ●●●●● patch | view | raw | blame | history
src/views/property/process/maintenanceFundApply/handle.vue 419 ●●●●● patch | view | raw | blame | history
src/views/property/todo.vue 395 ●●●● patch | view | raw | blame | history
src/views/work/process/maintenanceFundApply/edit.vue 6 ●●●● patch | view | raw | blame | history
src/views/work/process/maintenanceFundApply/handle.vue 4 ●●●● patch | view | raw | blame | history
src/router/views/index.js
@@ -1,19 +1,17 @@
import Layout from "@/page/index/";
export default [
  {
export default [{
    path: "/wel",
    component: Layout,
    redirect: "/wel/index",
    children: [
      {
    children: [{
        path: "index",
        name: "首页",
        meta: {
          i18n: "dashboard",
        },
        component: () =>
          import(/* webpackChunkName: "views" */ "@/views/wel/index"),
          import( /* webpackChunkName: "views" */ "@/views/wel/index"),
      },
      {
        path: "dashboard",
@@ -23,7 +21,7 @@
          menu: false,
        },
        component: () =>
          import(/* webpackChunkName: "views" */ "@/views/wel/dashboard"),
          import( /* webpackChunkName: "views" */ "@/views/wel/dashboard"),
      },
    ],
  },
@@ -31,76 +29,69 @@
    path: "/test",
    component: Layout,
    redirect: "/test/index",
    children: [
      {
        path: "index",
        name: "测试页",
        meta: {
          i18n: "test",
        },
        component: () =>
          import(/* webpackChunkName: "views" */ "@/views/util/test"),
    children: [{
      path: "index",
      name: "测试页",
      meta: {
        i18n: "test",
      },
    ],
      component: () =>
        import( /* webpackChunkName: "views" */ "@/views/util/test"),
    }, ],
  },
  {
    path: "/dict-horizontal",
    component: Layout,
    redirect: "/dict-horizontal/index",
    children: [
      {
        path: "index",
        name: "字典管理",
        meta: {
          i18n: "dict",
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */ "@/views/util/demo/dict-horizontal"
          ),
    children: [{
      path: "index",
      name: "字典管理",
      meta: {
        i18n: "dict",
      },
    ],
      component: () =>
        import(
          /* webpackChunkName: "views" */
          "@/views/util/demo/dict-horizontal"
        ),
    }, ],
  },
  {
    path: "/dict-vertical",
    component: Layout,
    redirect: "/dict-vertical/index",
    children: [
      {
        path: "index",
        name: "字典管理",
        meta: {
          i18n: "dict",
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */ "@/views/util/demo/dict-vertical"
          ),
    children: [{
      path: "index",
      name: "字典管理",
      meta: {
        i18n: "dict",
      },
    ],
      component: () =>
        import(
          /* webpackChunkName: "views" */
          "@/views/util/demo/dict-vertical"
        ),
    }, ],
  },
  {
    path: "/info",
    component: Layout,
    redirect: "/info/index",
    children: [
      {
        path: "index",
        name: "个人信息",
        meta: {
          i18n: "info",
        },
        component: () =>
          import(/* webpackChunkName: "views" */ "@/views/system/userinfo"),
    children: [{
      path: "index",
      name: "个人信息",
      meta: {
        i18n: "info",
      },
    ],
      component: () =>
        import( /* webpackChunkName: "views" */ "@/views/system/userinfo"),
    }, ],
  },
  {
    path: "/work/process/leave",
    component: Layout,
    redirect: "/work/process/leave/form",
    children: [
      {
    children: [{
        path: "form/:processDefinitionId",
        name: "请假流程",
        meta: {
@@ -108,7 +99,8 @@
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */ "@/views/work/process/leave/form"
            /* webpackChunkName: "views" */
            "@/views/work/process/leave/form"
          ),
      },
      {
@@ -119,7 +111,8 @@
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */ "@/views/work/process/leave/handle"
            /* webpackChunkName: "views" */
            "@/views/work/process/leave/handle"
          ),
      },
      {
@@ -130,17 +123,17 @@
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */ "@/views/work/process/leave/detail"
            /* webpackChunkName: "views" */
            "@/views/work/process/leave/detail"
          ),
      },
    ],
  },
  {
    path: "/work/process/maintenanceFundApply",
    path: "/property/process/maintenanceFundApply",
    component: Layout,
    redirect: "/work/process/maintenanceFundApply/form",
    children: [
      {
    children: [{
        path: "form/:processDefinitionId",
        name: "维修基金申请",
        meta: {
@@ -148,7 +141,8 @@
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */ "@/views/work/process/maintenanceFundApply/form"
            /* webpackChunkName: "views" */
            "@/views/work/process/maintenanceFundApply/form"
          ),
      },
      {
@@ -159,7 +153,8 @@
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */ "@/views/work/process/maintenanceFundApply/handle"
            /* webpackChunkName: "views" */
            "@/views/work/process/maintenanceFundApply/handle"
          ),
      },
      {
@@ -170,7 +165,8 @@
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */ "@/views/work/process/maintenanceFundApply/detail"
            /* webpackChunkName: "views" */
            "@/views/work/process/maintenanceFundApply/detail"
          ),
      },
      {
@@ -181,9 +177,65 @@
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */ "@/views/work/process/maintenanceFundApply/edit"
            /* webpackChunkName: "views" */
            "@/views/work/process/maintenanceFundApply/edit"
          ),
      },
    ],
  },
];
  {
    path: "/gzll/process/maintenanceFundApply",
    component: Layout,
    redirect: "/work/process/maintenanceFundApply/form",
    children: [{
        path: "form/:processDefinitionId",
        name: "维修基金申请",
        meta: {
          i18n: "work",
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */
            "@/views/work/process/maintenanceFundApply/form"
          ),
      },
      {
        path: "handle/:taskId/:processInstanceId/:businessId",
        name: "处理维修基金申请",
        meta: {
          i18n: "work",
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */
            "@/views/work/process/maintenanceFundApply/handle"
          ),
      },
      {
        path: "detail/:processInstanceId/:businessId",
        name: "维修基金申请详情",
        meta: {
          i18n: "work",
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */
            "@/views/work/process/maintenanceFundApply/detail"
          ),
      },
      {
        path: "edit/:taskId/:processInstanceId/:businessId",
        name: "调整维修基金申请",
        meta: {
          i18n: "work",
        },
        component: () =>
          import(
            /* webpackChunkName: "views" */
            "@/views/work/process/maintenanceFundApply/edit"
          ),
      },
    ],
  },
];
src/views/gzll/process/leave/detail.vue
New file
@@ -0,0 +1,107 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" label-width="80px">
      <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row>
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <el-form-item label="申请人">
          <el-input :disabled="true" v-model="form.flow.assigneeName" />
        </el-form-item>
        <el-row>
          <el-col :span="12">
            <el-form-item label="开始时间">
              <el-input :disabled="true" v-model="form.startTime" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="结束时间">
              <el-input :disabled="true" v-model="form.endTime" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="请假理由">
          <el-input :disabled="true" type="textarea" v-model="form.reason" />
        </el-form-item>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{flow.assigneeName}} 在 [{{flow.createTime}}] 开始处理 [{{flow.historyActivityName}}] 环节</p>
                <p v-if="flow.historyActivityDurationTime!==''">任务历时 [{{flow.historyActivityDurationTime}}]</p>
                <p v-if="flow.comment!==''">批复意见: [{{flow.comment}}]</p>
                <p v-if="flow.endTime!==''">结束时间: [{{flow.endTime}}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
  </basic-container>
</template>
<script>
  import {historyFlowList, leaveDetail} from "@/api/work/process";
  export default {
    data() {
      return {
        businessId: '',
        processInstanceId: '',
        src: '',
        flowList: [],
        form: {
          flow:{
            assigneeName:'',
          },
          startTime: '',
          endTime: '',
          reason: '',
        }
      }
    },
    created() {
      this.init();
    },
    methods: {
      init() {
        this.processInstanceId = this.$route.params.processInstanceId;
        this.businessId = this.$route.params.businessId;
        historyFlowList(this.processInstanceId).then(res => {
          const data = res.data;
          if (data.success) {
            this.flowList = data.data;
          }
        })
        leaveDetail(this.businessId).then(res => {
          const data = res.data;
          if (data.success) {
            this.form = data.data;
          }
        })
      },
      handleCancel() {
        this.$router.$avueRouter.closeTag();
        this.$router.push({path: `/work/start`});
      }
    }
  }
</script>
src/views/gzll/process/leave/form.vue
New file
@@ -0,0 +1,112 @@
<template>
  <div>
    <basic-container>
      <avue-form :option="option" v-model="form" @submit="handleSubmit"/>
    </basic-container>
    <basic-container>
      <flow-design :is-display="true" :process-definition-id="processDefinitionId"></flow-design>
    </basic-container>
  </div>
</template>
<script>
  import {leaveProcess} from "@/api/work/process";
  export default {
    data() {
      return {
        processDefinitionId: '',
        form: {},
        option: {
          group: [
            {
              icon: 'el-icon-info',
              label: '请假基础信息',
              prop: 'group1',
              column: [
                {
                  label: '审批人员',
                  prop: 'taskUser',
                  type: 'select',
                  dicUrl: `/api/blade-system/user/user-list`,
                  props: {
                    label: "account",
                    value: "id"
                  },
                  span: 24,
                  rules: [
                    {
                      required: true,
                      message: '请选择审批人员',
                      trigger: 'blur'
                    }
                  ]
                },
                {
                  label: '开始时间',
                  prop: 'startTime',
                  type: 'datetime',
                  valueFormat: 'yyyy-MM-dd HH:mm:ss',
                  rules: [
                    {
                      required: true,
                      message: '请选择开始时间',
                      trigger: 'blur'
                    }
                  ]
                },
                {
                  label: '结束时间',
                  prop: 'endTime',
                  type: 'datetime',
                  valueFormat: 'yyyy-MM-dd HH:mm:ss',
                  rules: [
                    {
                      required: true,
                      message: '请选择结束时间',
                      trigger: 'blur'
                    }
                  ]
                },
                {
                  label: '请假理由',
                  prop: 'reason',
                  type: 'textarea',
                  span: 24,
                  rules: [
                    {
                      required: true,
                      message: '请输入请假理由',
                      trigger: 'blur'
                    }
                  ]
                },
              ]
            },
          ],
        }
      }
    },
    created() {
      this.processDefinitionId = this.$route.params.processDefinitionId;
    },
    methods: {
      handleSubmit() {
        const params = {
          processDefinitionId: this.$route.params.processDefinitionId,
          ...this.form,
        };
        leaveProcess(params).then(resp => {
          const data = resp.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({path: `/work/start`});
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        });
      }
    }
  }
</script>
src/views/gzll/process/leave/handle.vue
New file
@@ -0,0 +1,169 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
      <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button type="primary" @click="handleAgree">同意</el-button>
          <el-button type="danger" @click="handleDisagree">驳回</el-button>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row>
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <el-form-item label="申请人">
          <el-input :disabled="true" v-model="form.flow.assigneeName"/>
        </el-form-item>
        <el-row>
          <el-col :span="12">
            <el-form-item label="开始时间">
              <el-input :disabled="true" v-model="form.startTime"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="结束时间">
              <el-input :disabled="true" v-model="form.endTime"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="请假理由">
          <el-input :disabled="true" type="textarea" v-model="form.reason"/>
        </el-form-item>
        <el-form-item label="批复意见">
          <el-input type="textarea" v-model="form.comment"/>
        </el-form-item>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{flow.assigneeName}} 在 [{{flow.createTime}}] 开始处理 [{{flow.historyActivityName}}] 环节</p>
                <p v-if="flow.historyActivityDurationTime!==''">任务历时 [{{flow.historyActivityDurationTime}}]</p>
                <p v-if="flow.comment!==''">批复意见: [{{flow.comment}}]</p>
                <p v-if="flow.endTime!==''">结束时间: [{{flow.endTime}}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
  </basic-container>
</template>
<script>
  import {historyFlowList, leaveDetail} from "@/api/work/process";
  import {completeTask} from "@/api/work/work";
  export default {
    data() {
      return {
        taskId: '',
        businessId: '',
        processInstanceId: '',
        src: '',
        flowList: [],
        form: {
          flow: {
            assigneeName: '',
          },
          startTime: '',
          endTime: '',
          reason: '',
          comment: '',
        },
      }
    },
    created() {
      this.init();
    },
    beforeRouteUpdate(to, from, next) {
      // 在当前路由改变,但是该组件被复用时调用
      // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候
      // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用
      // 可以访问组件实例 `this`
      if (to.fullPath !== from.fullPath) {
        next();
        this.init();
      }
    },
    methods: {
      init() {
        this.taskId = this.$route.params.taskId;
        this.processInstanceId = this.$route.params.processInstanceId;
        this.businessId = this.$route.params.businessId;
        historyFlowList(this.processInstanceId).then(res => {
          const data = res.data;
          if (data.success) {
            this.flowList = data.data;
          }
        })
        leaveDetail(this.businessId).then(res => {
          const data = res.data;
          if (data.success) {
            this.form = data.data;
          }
        })
      },
      handleAgree() {
        if (!this.form.comment) {
          this.$message.warning('请先填写批复意见');
          return;
        }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          flag: 'ok',
          comment: this.form.comment,
        };
        completeTask(params).then(res => {
          const data = res.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({path: `/work/start`});
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        })
      },
      handleDisagree() {
        if (!this.form.comment) {
          this.$message.warning('请先填写批复意见');
          return;
        }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          comment: this.form.comment,
        };
        completeTask(params).then(res => {
          const data = res.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({path: `/work/start`});
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        })
      },
      handleCancel() {
        this.$router.$avueRouter.closeTag();
        this.$router.push({path: `/work/start`});
      }
    }
  }
</script>
src/views/gzll/process/maintenanceFundApply/detail.vue
New file
@@ -0,0 +1,325 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" label-width="80px">
      <!-- <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row> -->
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <avue-form :option="option" :value="form"></avue-form>
        <!-- <el-form-item label="申请人">
          <el-input :disabled="true" v-model="form.flow.assigneeName" />
        </el-form-item>
        <el-row>
          <el-col :span="12">
            <el-form-item label="开始时间">
              <el-input :disabled="true" v-model="form.startTime" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="结束时间">
              <el-input :disabled="true" v-model="form.endTime" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="请假理由">
          <el-input :disabled="true" type="textarea" v-model="form.reason" />
        </el-form-item> -->
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{flow.assigneeName}} 在 [{{flow.createTime}}] 开始处理 [{{flow.historyActivityName}}] 环节</p>
                <p v-if="flow.historyActivityDurationTime!==''">任务历时 [{{flow.historyActivityDurationTime}}]</p>
                <p v-if="flow.comment!==''">批复意见: [{{flow.comment}}]</p>
                <p v-if="flow.endTime!==''">结束时间: [{{flow.endTime}}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
  </basic-container>
</template>
<script>
  import {
    historyFlowList,
    leaveDetail
  } from "@/api/work/process";
  import {
    getList,
    remove,
    update,
    add,
    getPropertyCapitalApply
  } from "@/api/property/propertyCapitalApply";
  export default {
    data() {
      return {
        businessId: '',
        processInstanceId: '',
        src: '',
        flowList: [],
        form: {
          flow: {
            assigneeName: '',
          },
          startTime: '',
          endTime: '',
          reason: '',
        },
        option: {
          height: "auto",
          calcHeight: 54,
          dialogWidth: 1150,
          tip: false,
          searchShow: true,
          searchMenuSpan: 3,
          menuWidth: 350,
          border: true,
          //stripe:true,
          submitBtn: false,
          emptyBtn: false,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          column: [{
              label: "小区",
              prop: "districtId",
              searchSpan: 5,
              search: true,
              type: 'tree',
              dicUrl: `/api/blade-district/district/getDistrictTree`,
              props: {
                label: "name",
                value: "id"
              },
              defaultExpandedKeys: ["361102003"],
              span: 12,
              labelWidth: 120,
              width: 220,
              overHidden: true,
              rules: [{
                required: true,
                message: "请选择小区",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: '维修项目名称',
              prop: 'name',
              searchLabelWidth: 120,
              searchSpan: 5,
              search: true,
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入维修项目名称",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "预计开工时间",
              prop: "runTime",
              span: 12,
              labelWidth: 140,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同开始时间",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "预计竣工时间",
              prop: "completedTime",
              labelWidth: 140,
              span: 12,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同结束时间",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "项目分摊方式",
              prop: "allocationWay",
              labelWidth: 140,
              value: '按建筑面积分摊',
              span: 12,
              row: true,
              disabled: true
            },
            {
              label: '联系人',
              prop: 'linkman',
              span: 12,
              labelWidth: 120,
              search: true,
              searchSpan: 4,
              rules: [{
                required: true,
                message: "请输入联系人",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: '联系方式',
              prop: 'linkPhone',
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入联系方式",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "项目预算总金额(元)",
              prop: "budgetAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "实际预算金额(元)",
              prop: "actualAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "自筹金额(元)",
              prop: "selfAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "预算应拨付金额(元)",
              prop: "budgetAppropriateAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "项目摘要",
              span: 24,
              hide: true,
              prop: "projectDigest",
              placeholder: "例如:“XX小区XX栋XX设施设备维修,总的预算金额是X,是否含有审价,本次维修涉及范围共XX户,总面积的建筑面积为XX平方米”",
              labelWidth: 140,
              type: "textarea",
              disabled: true
            },
            {
              label: "项目进度描述",
              span: 24,
              hide: true,
              prop: "projectDescribe",
              labelWidth: 140,
              type: "textarea",
              disabled: true
            },
            {
              label: '施工方案附件',
              prop: 'constructionSchemeUrls',
              type: 'upload',
              span: 24,
              hide: true,
              labelWidth: 140,
              multiple: true,
              // showFileList: true,
              propsHttp: {
                res: 'data',
                name: "originalName",
                url: "link"
              },
              action: '/api/blade-resource/oss/endpoint/put-file-attach',
              rules: [{
                required: true,
                message: "请上传施工方案",
                trigger: "blur",
              }, ],
            }
          ],
        }
      }
    },
    created() {
      this.init();
    },
    methods: {
      init() {
        this.processInstanceId = this.$route.params.processInstanceId;
        this.businessId = this.$route.params.businessId;
        historyFlowList(this.processInstanceId).then(res => {
          const data = res.data;
          if (data.success) {
            this.flowList = data.data;
          }
        })
        getPropertyCapitalApply(this.businessId).then(res => {
          const data = res.data;
          if (data.success) {
            this.form = data.data;
          }
        })
      },
      handleCancel() {
        this.$router.$avueRouter.closeTag();
        this.$router.push({
          path: `/work/start`
        });
      }
    }
  }
</script>
src/views/gzll/process/maintenanceFundApply/edit.vue
New file
@@ -0,0 +1,419 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
      <!--  <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row> -->
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <avue-form ref="crud" :option="option" v-model="form" @submit="handleSubmit">
          <template slot-scope="{size}" slot="menuForm">
            <el-button type="primary" :size="size" @click="$refs.crud.submit()">保存信息</el-button>
            <!-- <el-button :size="size" @click="$refs.form.resetForm()">自定义清空</el-button> -->
          </template>
        </avue-form>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{flow.assigneeName}} 在 [{{flow.createTime}}] 开始处理 [{{flow.historyActivityName}}] 环节</p>
                <p v-if="flow.historyActivityDurationTime!==''">任务历时 [{{flow.historyActivityDurationTime}}]</p>
                <p v-if="flow.comment!==''">批复意见: [{{flow.comment}}]</p>
                <p v-if="flow.endTime!==''">结束时间: [{{flow.endTime}}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
    <div style="text-align: center;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 10px;">
      <el-button type="primary" @click="handleAgree">重新提交</el-button>
      <el-button type="danger" @click="handleDisagree">关闭申请</el-button>
    </div>
  </basic-container>
</template>
<script>
  import {
    historyFlowList,
    leaveDetail
  } from "@/api/work/process";
  import {
    getList,
    remove,
    update,
    add,
    getPropertyCapitalApply
  } from "@/api/property/propertyCapitalApply";
  import {
    completeTask
  } from "@/api/work/work";
  export default {
    data() {
      return {
        taskId: '',
        businessId: '',
        processInstanceId: '',
        src: '',
        flowList: [],
        form: {
          flow: {
            assigneeName: '',
          },
          startTime: '',
          endTime: '',
          reason: '',
          comment: '',
        },
        option: {
          height: "auto",
          calcHeight: 54,
          dialogWidth: 1150,
          tip: false,
          searchShow: true,
          searchMenuSpan: 3,
          menuWidth: 350,
          border: true,
          //stripe:true,
          submitBtn: false,
          emptyBtn: false,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          column: [{
              label: "小区",
              prop: "districtId",
              searchSpan: 5,
              search: true,
              type: 'tree',
              dicUrl: `/api/blade-district/district/getDistrictTree`,
              props: {
                label: "name",
                value: "id"
              },
              defaultExpandedKeys: ["361102003"],
              span: 12,
              labelWidth: 120,
              width: 220,
              overHidden: true,
              rules: [{
                required: true,
                message: "请选择小区",
                trigger: "blur",
              }, ],
            },
            {
              label: '维修项目名称',
              prop: 'name',
              searchLabelWidth: 120,
              searchSpan: 5,
              search: true,
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入维修项目名称",
                trigger: "blur",
              }, ],
            },
            {
              label: "预计开工时间",
              prop: "runTime",
              span: 12,
              labelWidth: 140,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同开始时间",
                trigger: "blur",
              }, ],
            },
            {
              label: "预计竣工时间",
              prop: "completedTime",
              labelWidth: 140,
              span: 12,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同结束时间",
                trigger: "blur",
              }, ],
            },
            {
              label: "项目分摊方式",
              prop: "allocationWay",
              labelWidth: 140,
              value: '按建筑面积分摊',
              span: 12,
              row: true,
            },
            {
              label: '联系人',
              prop: 'linkman',
              span: 12,
              labelWidth: 120,
              search: true,
              searchSpan: 4,
              rules: [{
                required: true,
                message: "请输入联系人",
                trigger: "blur",
              }, ],
            },
            {
              label: '联系方式',
              prop: 'linkPhone',
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入联系方式",
                trigger: "blur",
              }, ],
            },
            {
              label: "项目预算总金额(元)",
              prop: "budgetAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "实际预算金额(元)",
              prop: "actualAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "自筹金额(元)",
              prop: "selfAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "预算应拨付金额(元)",
              prop: "budgetAppropriateAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "项目摘要",
              span: 24,
              hide: true,
              prop: "projectDigest",
              placeholder: "例如:“XX小区XX栋XX设施设备维修,总的预算金额是X,是否含有审价,本次维修涉及范围共XX户,总面积的建筑面积为XX平方米”",
              labelWidth: 140,
              type: "textarea",
            },
            {
              label: "项目进度描述",
              span: 24,
              hide: true,
              prop: "projectDescribe",
              labelWidth: 140,
              type: "textarea",
            },
            // {
            //   label: "批复意见",
            //   span: 24,
            //   hide: true,
            //   prop: "comment",
            //   labelWidth: 140,
            //   type: "textarea",
            //   rules: [{
            //     required: true,
            //     message: "请输入批复意见",
            //     trigger: "blur",
            //   }, ],
            // },
            {
              label: '施工方案附件',
              prop: 'constructionSchemeUrls',
              type: 'upload',
              span: 24,
              hide: true,
              labelWidth: 140,
              multiple: true,
              // showFileList: true,
              propsHttp: {
                res: 'data',
                name: "originalName",
                url: "link"
              },
              action: '/api/blade-resource/oss/endpoint/put-file-attach',
              rules: [{
                required: true,
                message: "请上传施工方案",
                trigger: "blur",
              }, ],
            }
          ],
        }
      }
    },
    created() {
      this.init();
    },
    beforeRouteUpdate(to, from, next) {
      // 在当前路由改变,但是该组件被复用时调用
      // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候
      // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用
      // 可以访问组件实例 `this`
      if (to.fullPath !== from.fullPath) {
        next();
        this.init();
      }
    },
    methods: {
      handleSubmit(form, done, loading) {
        if (form.constructionSchemeUrls.length > 0) {
          var urls = []
          var split = form.constructionSchemeUrls.split(",");
          split.forEach(url => {
            var names = url.split("jczz/");
            urls.push(names[1])
          })
          form.constructionSchemeUrls = urls.join(",")
        }
        update(form).then(
          () => {
            this.onLoad(this.page);
            this.$message({
              type: "success",
              message: "操作成功!",
            });
            done();
          },
          (error) => {
            window.console.log(error);
            loading();
          }
        );
      },
      init() {
        this.taskId = this.$route.params.taskId;
        this.processInstanceId = this.$route.params.processInstanceId;
        this.businessId = this.$route.params.businessId;
        historyFlowList(this.processInstanceId).then(res => {
          const data = res.data;
          if (data.success) {
            this.flowList = data.data;
          }
        })
        getPropertyCapitalApply(this.businessId).then(res => {
          const data = res.data;
          if (data.success) {
            this.form = data.data;
          }
        })
      },
      handleAgree() {
        // if (!this.form.comment) {
        //   this.$message.warning('请先填写批复意见');
        //   return;
        // }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          flag: 'ok',
          comment: this.form.comment,
        };
        completeTask(params).then(res => {
          const data = res.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({
              path: `/property/propertyCapitalApply`
            });
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        })
      },
      handleDisagree() {
        this.form.comment = '关闭申请'
        if (!this.form.comment) {
          this.$message.warning('请先填写批复意见');
          return;
        }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          comment: this.form.comment,
        };
        completeTask(params).then(res => {
          const data = res.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({
              path: `/property/propertyCapitalApply`
            });
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        })
      },
      handleCancel() {
        this.$router.$avueRouter.closeTag();
        this.$router.push({
          path: `/gzll/todo`
        });
      }
    }
  }
</script>
src/views/gzll/process/maintenanceFundApply/form.vue
New file
@@ -0,0 +1,267 @@
<template>
  <div>
    <basic-container>
      <avue-form :option="option" v-model="form" @submit="handleSubmit" />
    </basic-container>
    <basic-container>
      <flow-design :is-display="true" :process-definition-id="processDefinitionId"></flow-design>
    </basic-container>
  </div>
</template>
<script>
  import {
    leaveProcess
  } from "@/api/work/process";
  export default {
    data() {
      return {
        processDefinitionId: '',
        form: {},
        option: {
          height: "auto",
          calcHeight: 54,
          dialogWidth: 1150,
          tip: false,
          searchShow: true,
          searchMenuSpan: 3,
          menuWidth: 350,
          border: true,
          //stripe:true,
          // submitBtn: false,
          // emptyBtn: false,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          column: [{
              label: "小区",
              prop: "districtId",
              searchSpan: 5,
              search: true,
              type: 'tree',
              dicUrl: `/api/blade-district/district/getDistrictTree`,
              props: {
                label: "name",
                value: "id"
              },
              defaultExpandedKeys: ["361102003"],
              span: 12,
              labelWidth: 120,
              width: 220,
              overHidden: true,
              rules: [{
                required: true,
                message: "请选择小区",
                trigger: "blur",
              }, ],
            },
            {
              label: '维修项目名称',
              prop: 'name',
              searchLabelWidth: 120,
              searchSpan: 5,
              search: true,
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入维修项目名称",
                trigger: "blur",
              }, ],
            },
            {
              label: "预计开工时间",
              prop: "runTime",
              span: 12,
              labelWidth: 140,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同开始时间",
                trigger: "blur",
              }, ],
            },
            {
              label: "预计竣工时间",
              prop: "completedTime",
              labelWidth: 140,
              span: 12,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同结束时间",
                trigger: "blur",
              }, ],
            },
            {
              label: "项目分摊方式",
              prop: "allocationWay",
              labelWidth: 140,
              value: '按建筑面积分摊',
              span: 12,
              row: true,
            },
            {
              label: '联系人',
              prop: 'linkman',
              span: 12,
              labelWidth: 120,
              search: true,
              searchSpan: 4,
              rules: [{
                required: true,
                message: "请输入联系人",
                trigger: "blur",
              }, ],
            },
            {
              label: '联系方式',
              prop: 'linkPhone',
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入联系方式",
                trigger: "blur",
              }, ],
            },
            {
              label: "项目预算总金额(元)",
              prop: "budgetAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "实际预算金额(元)",
              prop: "actualAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "自筹金额(元)",
              prop: "selfAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "预算应拨付金额(元)",
              prop: "budgetAppropriateAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "项目摘要",
              span: 24,
              hide: true,
              prop: "projectDigest",
              placeholder: "例如:“XX小区XX栋XX设施设备维修,总的预算金额是X,是否含有审价,本次维修涉及范围共XX户,总面积的建筑面积为XX平方米”",
              labelWidth: 140,
              type: "textarea",
            },
            {
              label: "项目进度描述",
              span: 24,
              hide: true,
              prop: "projectDescribe",
              labelWidth: 140,
              type: "textarea",
            },
            {
              label: '施工方案附件',
              prop: 'constructionSchemeUrls',
              type: 'upload',
              span: 24,
              hide: true,
              labelWidth: 140,
              multiple: true,
              // showFileList: true,
              propsHttp: {
                res: 'data',
                name: "originalName",
                url: "link"
              },
              action: '/api/blade-resource/oss/endpoint/put-file-attach',
              rules: [{
                required: true,
                message: "请上传施工方案",
                trigger: "blur",
              }, ],
            }
          ],
        },
      }
    },
    created() {
      this.processDefinitionId = this.$route.params.processDefinitionId;
    },
    methods: {
      handleSubmit(form, done, loading) {
        form.constructionSchemeUrls = func.join(form.constructionSchemeUrls)
        if (form.constructionSchemeUrls.length > 0) {
          var urls = []
          var split = form.constructionSchemeUrls.split(",");
          split.forEach(url => {
            var names = url.split("jczz/");
            urls.push(names[1])
          })
          form.constructionSchemeUrls = urls.join(",")
        }
        add(form).then(
          () => {
            this.onLoad(this.page);
            this.$message({
              type: "success",
              message: "操作成功!",
            });
            done();
          },
          (error) => {
            window.console.log(error);
            loading();
          }
        );
      },
      handleSubmit() {
        const params = {
          processDefinitionId: this.$route.params.processDefinitionId,
          ...this.form,
        };
        leaveProcess(params).then(resp => {
          const data = resp.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({
              path: `/work/start`
            });
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        });
      }
    }
  }
</script>
src/views/gzll/process/maintenanceFundApply/handle.vue
New file
@@ -0,0 +1,419 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
      <!-- <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row> -->
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <avue-form :option="option" v-model="form"></avue-form>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{ flow.assigneeName }} 在 [{{ flow.createTime }}] 开始处理 [{{ flow.historyActivityName }}]
                  环节</p>
                <p v-if="flow.historyActivityDurationTime !== ''">任务历时 [{{ flow.historyActivityDurationTime
                                }}]
                </p>
                <p v-if="flow.comment !== ''">批复意见: [{{ flow.comment }}]</p>
                <p v-if="flow.endTime !== ''">结束时间: [{{ flow.endTime }}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
    <!-- <div style="">
      <el-button type="primary" @click="handleAgree">同意</el-button>
      <el-button type="danger" @click="handleDisagree">驳回</el-button>
    </div> -->
    <div style="text-align: center;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 10px;">
      <el-button type="primary" @click="handleAgree">同意</el-button>
      <el-button type="danger" @click="handleDisagree">驳回</el-button>
    </div>
  </basic-container>
</template>
<script>
  import {
    historyFlowList,
    leaveDetail
  } from "@/api/work/process"
  import {
    getList,
    remove,
    update,
    add,
    getPropertyCapitalApply
  } from "@/api/property/propertyCapitalApply"
  import {
    completeTask
  } from "@/api/work/work"
  import website from '@/config/website'
  export default {
    data() {
      return {
        taskId: '',
        businessId: '',
        processInstanceId: '',
        src: '',
        flowList: [],
        form: {
          flow: {
            assigneeName: '',
          },
          startTime: '',
          endTime: '',
          reason: '',
        },
        option: {
          height: "auto",
          calcHeight: 54,
          dialogWidth: 1150,
          tip: false,
          searchShow: true,
          searchMenuSpan: 3,
          menuWidth: 350,
          border: true,
          //stripe:true,
          submitBtn: false,
          emptyBtn: false,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          column: [{
              label: "小区",
              prop: "districtId",
              searchSpan: 5,
              search: true,
              type: 'tree',
              dicUrl: `/api/blade-district/district/getDistrictTree`,
              props: {
                label: "name",
                value: "id"
              },
              defaultExpandedKeys: ["361102003"],
              span: 12,
              labelWidth: 120,
              width: 220,
              overHidden: true,
              rules: [{
                required: true,
                message: "请选择小区",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: '维修项目名称',
              prop: 'name',
              searchLabelWidth: 120,
              searchSpan: 5,
              search: true,
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入维修项目名称",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "预计开工时间",
              prop: "runTime",
              span: 12,
              labelWidth: 140,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同开始时间",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "预计竣工时间",
              prop: "completedTime",
              labelWidth: 140,
              span: 12,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同结束时间",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "项目分摊方式",
              prop: "allocationWay",
              labelWidth: 140,
              value: '按建筑面积分摊',
              span: 12,
              row: true,
              disabled: true
            },
            {
              label: '联系人',
              prop: 'linkman',
              span: 12,
              labelWidth: 120,
              search: true,
              searchSpan: 4,
              rules: [{
                required: true,
                message: "请输入联系人",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: '联系方式',
              prop: 'linkPhone',
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入联系方式",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "项目预算总金额(元)",
              prop: "budgetAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "实际预算金额(元)",
              prop: "actualAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "自筹金额(元)",
              prop: "selfAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "预算应拨付金额(元)",
              prop: "budgetAppropriateAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "项目摘要",
              span: 24,
              hide: true,
              prop: "projectDigest",
              placeholder: "例如:“XX小区XX栋XX设施设备维修,总的预算金额是X,是否含有审价,本次维修涉及范围共XX户,总面积的建筑面积为XX平方米”",
              labelWidth: 140,
              type: "textarea",
              disabled: true
            },
            {
              label: "项目进度描述",
              span: 24,
              hide: true,
              prop: "projectDescribe",
              labelWidth: 140,
              type: "textarea",
              disabled: true
            }, {
              label: "批复意见",
              span: 24,
              hide: true,
              prop: "comment",
              labelWidth: 140,
              type: "textarea",
              rules: [{
                required: true,
                message: "请输入批复意见",
                trigger: "blur",
              }, ],
            },
            {
              label: '施工方案附件',
              prop: 'constructionSchemeUrls',
              type: 'upload',
              listType: 'picture-img',
              span: 24,
              hide: true,
              labelWidth: 140,
              multiple: true,
              // showFileList: true,
              propsHttp: {
                res: 'data',
                name: "originalName",
                url: "link"
              },
              action: '/api/blade-resource/oss/endpoint/put-file-attach',
              rules: [{
                required: true,
                message: "请上传施工方案",
                trigger: "blur",
              }, ],
            }
          ],
        }
      }
    },
    created() {
      this.init()
    },
    beforeRouteUpdate(to, from, next) {
      // 在当前路由改变,但是该组件被复用时调用
      // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候
      // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用
      // 可以访问组件实例 `this`
      if (to.fullPath !== from.fullPath) {
        next()
        this.init()
      }
    },
    methods: {
      init() {
        this.taskId = this.$route.params.taskId
        this.processInstanceId = this.$route.params.processInstanceId
        this.businessId = this.$route.params.businessId
        historyFlowList(this.processInstanceId).then(res => {
          const data = res.data
          if (data.success) {
            this.flowList = data.data
          }
        })
        getPropertyCapitalApply(this.businessId).then(res => {
          const data = res.data
          if (data.success) {
            data.data.constructionSchemeUrls = website.minioUrl + data.data.constructionSchemeUrls
            this.form = data.data
          }
        })
      },
      handleAgree() {
        if (!this.form.comment) {
          this.$message.warning('请先填写批复意见')
          return
        }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          flag: 'ok',
          comment: this.form.comment,
        }
        completeTask(params).then(res => {
          const data = res.data
          if (data.success) {
            this.$message.success(data.msg)
            this.$router.$avueRouter.closeTag()
            this.$router.push({
              path: `/gzll/todo`
            })
          } else {
            this.$message.error(data.msg || '提交失败')
          }
        })
      },
      handleDisagree() {
        if (!this.form.comment) {
          this.$message.warning('请先填写批复意见')
          return
        }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          comment: this.form.comment,
        }
        completeTask(params).then(res => {
          const data = res.data
          if (data.success) {
            this.$message.success(data.msg)
            this.$router.$avueRouter.closeTag()
            this.$router.push({
              path: `/gzll/todo`
            })
          } else {
            this.$message.error(data.msg || '提交失败')
          }
        })
      },
      handleCancel() {
        this.$router.$avueRouter.closeTag()
        this.$router.push({
          path: `/gzll/todo`
        })
      }
    }
  }
</script>
<style scoped>
  .container {
    position: relative;
    /* 确保按钮相对于该元素定位 */
  }
  #myButton {
    position: fixed;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  }
</style>
src/views/gzll/todo.vue
@@ -1,216 +1,215 @@
<template>
    <basic-container>
        <avue-crud :option="option" :table-loading="loading" :data="data" ref="crud" v-model="form"
            @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
            @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
            <template slot-scope="{row, size, index}" slot="menu">
                <el-button type="text" :size="size" icon="el-icon-s-check" v-if="permission.gzll_todo_handle"
                    @click.stop="handleWork(row)">处理
                </el-button>
                <el-button type="text" :size="size" icon="el-icon-info" v-if="permission.gzll_todo_detail"
                    @click.stop="handleDetail(row)">详情
                </el-button>
                <el-button type="text" :size="size" icon="el-icon-search" v-if="permission.gzll_todo_follow"
                    @click.stop="handleImage(row, index)">流程图
                </el-button>
            </template>
            <template slot-scope="{row, size}" slot="processDefinitionVersion">
                <el-tag :size="size">v{{ row.processDefinitionVersion }}</el-tag>
            </template>
        </avue-crud>
        <flow-design is-dialog :is-display.sync="flowBox" :process-instance-id="processInstanceId"></flow-design>
    </basic-container>
  <basic-container>
    <avue-crud :option="option" :table-loading="loading" :data="data" ref="crud" v-model="form"
      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
      @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
      <template slot-scope="{row, size, index}" slot="menu">
        <el-button type="text" :size="size" icon="el-icon-s-check" v-if="permission.gzll_todo_handle"
          @click.stop="handleWork(row)">处理
        </el-button>
        <el-button type="text" :size="size" icon="el-icon-info" v-if="permission.gzll_todo_detail"
          @click.stop="handleDetail(row)">详情
        </el-button>
        <el-button type="text" :size="size" icon="el-icon-search" v-if="permission.gzll_todo_follow"
          @click.stop="handleImage(row, index)">流程图
        </el-button>
      </template>
      <template slot-scope="{row, size}" slot="processDefinitionVersion">
        <el-tag :size="size">v{{ row.processDefinitionVersion }}</el-tag>
      </template>
    </avue-crud>
    <flow-design is-dialog :is-display.sync="flowBox" :process-instance-id="processInstanceId"></flow-design>
  </basic-container>
</template>
<script>
import {
  import {
    mapGetters
} from "vuex"
import {
  } from "vuex"
  import {
    todoList
} from "@/api/work/work"
import {
  } from "@/api/work/work"
  import {
    flowCategory,
    flowRoute
} from "@/util/flow"
  } from "@/util/flow"
export default {
    data () {
        return {
            form: {},
            selectionId: '',
            selectionList: [],
            query: {},
            loading: true,
            page: {
                pageSize: 10,
                currentPage: 1,
                total: 0
            },
            processInstanceId: '',
            flowBox: false,
            workBox: false,
            option: {
                labelWidth: 120,
                searchLabelWidth: 96,
                searchShow: true,
                searchMenuSpan: 3,
                menuWidth: 210,
  export default {
    data() {
      return {
        form: {},
        selectionId: '',
        selectionList: [],
        query: {},
        loading: true,
        page: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        processInstanceId: '',
        flowBox: false,
        workBox: false,
        option: {
          labelWidth: 120,
          searchLabelWidth: 96,
          searchShow: true,
          searchMenuSpan: 3,
          menuWidth: 210,
                height: 'auto',
                calcHeight: 30,
                tip: false,
                simplePage: true,
                border: true,
                index: true,
                // selection: true,
                editBtn: false,
                addBtn: false,
                viewBtn: false,
                delBtn: false,
                dialogWidth: 900,
                dialogClickModal: false,
                column: [
                    {
                        label: "流程分类",
                        type: "select",
                        row: true,
                        dicUrl: "/api/blade-system/dict/dictionary?code=flow",
                        props: {
                            label: "dictValue",
                            value: "dictKey"
                        },
                        dataType: "number",
                        slot: true,
                        prop: "category",
                        // search: true,
                        hide: true,
                        width: 100,
                    },
                    {
                        width: 100,
                        label: '申请类型',
                        prop: 'categoryName',
                        // search: true,
                    },
                    {
                        width: 220,
                        overHidden: true,
                        label: "小区",
                        prop: "districtId",
                        // search: true,
                        type: 'tree',
                        dicUrl: `/api/blade-district/district/getDistrictTree`,
                        props: {
                            label: "name",
                            value: "id"
                        },
                        defaultExpandedKeys: ["361102003"],
                        searchSpan: 5,
                        span: 12,
                    },
                    {
                        width: 110,
                        label: '联系人',
                        prop: 'linkman',
                        // search: true,
                    },
                    {
                        width: 120,
                        label: '联系电话',
                        prop: 'linkPhone',
                        // search: true,
                    },
                    {
                        label: '项目名称',
                        prop: 'name',
                        // search: true,
                    },
                    {
                        label: '当前步骤',
                        prop: 'taskName',
                    },
                    // {
                    //   label: '流程版本',
                    //   prop: 'processDefinitionVersion',
                    //   // slot: true,
                    //   width: 80,
                    // },
                    {
                        width: 144,
                        label: '申请时间',
                        prop: 'createTime',
                    },
                ]
          height: 'auto',
          calcHeight: 30,
          tip: false,
          simplePage: true,
          border: true,
          index: true,
          // selection: true,
          editBtn: false,
          addBtn: false,
          viewBtn: false,
          delBtn: false,
          dialogWidth: 900,
          dialogClickModal: false,
          column: [{
              label: "流程分类",
              type: "select",
              row: true,
              dicUrl: "/api/blade-system/dict/dictionary?code=flow",
              props: {
                label: "dictValue",
                value: "dictKey"
              },
              dataType: "number",
              slot: true,
              prop: "category",
              // search: true,
              hide: true,
              width: 100,
            },
            data: []
        }
            {
              width: 100,
              label: '申请类型',
              prop: 'categoryName',
              // search: true,
            },
            {
              width: 220,
              overHidden: true,
              label: "小区",
              prop: "districtId",
              // search: true,
              type: 'tree',
              dicUrl: `/api/blade-district/district/getDistrictTree`,
              props: {
                label: "name",
                value: "id"
              },
              defaultExpandedKeys: ["361102003"],
              searchSpan: 5,
              span: 12,
            },
            {
              width: 110,
              label: '联系人',
              prop: 'linkman',
              // search: true,
            },
            {
              width: 120,
              label: '联系电话',
              prop: 'linkPhone',
              // search: true,
            },
            {
              label: '项目名称',
              prop: 'name',
              // search: true,
            },
            {
              label: '当前步骤',
              prop: 'taskName',
            },
            // {
            //   label: '流程版本',
            //   prop: 'processDefinitionVersion',
            //   // slot: true,
            //   width: 80,
            // },
            {
              width: 144,
              label: '申请时间',
              prop: 'createTime',
            },
          ]
        },
        data: []
      }
    },
    computed: {
        ...mapGetters(["permission", "flowRoutes"]),
        ids () {
            let ids = []
            this.selectionList.forEach(ele => {
                ids.push(ele.id)
            })
            return ids.join(",")
        },
      ...mapGetters(["permission", "flowRoutes"]),
      ids() {
        let ids = []
        this.selectionList.forEach(ele => {
          ids.push(ele.id)
        })
        return ids.join(",")
      },
    },
    methods: {
        searchReset () {
            this.query = {}
            this.onLoad(this.page)
        },
        searchChange (params, done) {
            this.query = params
            this.page.currentPage = 1
            this.onLoad(this.page, params)
            done()
        },
        selectionChange (list) {
            this.selectionList = list
        },
        selectionClear () {
            this.selectionList = []
            this.$refs.crud.toggleSelection()
        },
        handleWork (row) {
            this.$router.push({
                path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/handle/${row.taskId}/${row.processInstanceId}/${row.businessId}`
            })
        },
        handleDetail (row) {
            this.$router.push({
                path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}`
            })
        },
        handleImage (row) {
            this.processInstanceId = row.processInstanceId
            this.flowBox = true
        },
        currentChange (currentPage) {
            this.page.currentPage = currentPage
        },
        sizeChange (pageSize) {
            this.page.pageSize = pageSize
        },
        refreshChange () {
            this.onLoad(this.page, this.query)
        },
        onLoad (page, params = {}) {
            const query = {
                ...this.query,
                category: (params.category) ? flowCategory(params.category) : null
            }
            this.loading = true
            todoList(page.currentPage, page.pageSize, Object.assign(params, query)).then(res => {
                const data = res.data.data
                this.page.total = data.total
                this.data = data.records
                this.loading = false
                this.selectionClear()
            })
      searchReset() {
        this.query = {}
        this.onLoad(this.page)
      },
      searchChange(params, done) {
        this.query = params
        this.page.currentPage = 1
        this.onLoad(this.page, params)
        done()
      },
      selectionChange(list) {
        this.selectionList = list
      },
      selectionClear() {
        this.selectionList = []
        this.$refs.crud.toggleSelection()
      },
      handleWork(row) {
        this.$router.push({
          path: `/gzll/process/${flowRoute(this.flowRoutes, row.category)}/handle/${row.taskId}/${row.processInstanceId}/${row.businessId}`
        })
      },
      handleDetail(row) {
        this.$router.push({
          path: `/gzll/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}`
        })
      },
      handleImage(row) {
        this.processInstanceId = row.processInstanceId
        this.flowBox = true
      },
      currentChange(currentPage) {
        this.page.currentPage = currentPage
      },
      sizeChange(pageSize) {
        this.page.pageSize = pageSize
      },
      refreshChange() {
        this.onLoad(this.page, this.query)
      },
      onLoad(page, params = {}) {
        const query = {
          ...this.query,
          category: (params.category) ? flowCategory(params.category) : null
        }
        this.loading = true
        todoList(page.currentPage, page.pageSize, Object.assign(params, query)).then(res => {
          const data = res.data.data
          this.page.total = data.total
          this.data = data.records
          this.loading = false
          this.selectionClear()
        })
      }
    }
}
  }
</script>
src/views/property/process/leave/detail.vue
New file
@@ -0,0 +1,107 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" label-width="80px">
      <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row>
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <el-form-item label="申请人">
          <el-input :disabled="true" v-model="form.flow.assigneeName" />
        </el-form-item>
        <el-row>
          <el-col :span="12">
            <el-form-item label="开始时间">
              <el-input :disabled="true" v-model="form.startTime" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="结束时间">
              <el-input :disabled="true" v-model="form.endTime" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="请假理由">
          <el-input :disabled="true" type="textarea" v-model="form.reason" />
        </el-form-item>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{flow.assigneeName}} 在 [{{flow.createTime}}] 开始处理 [{{flow.historyActivityName}}] 环节</p>
                <p v-if="flow.historyActivityDurationTime!==''">任务历时 [{{flow.historyActivityDurationTime}}]</p>
                <p v-if="flow.comment!==''">批复意见: [{{flow.comment}}]</p>
                <p v-if="flow.endTime!==''">结束时间: [{{flow.endTime}}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
  </basic-container>
</template>
<script>
  import {historyFlowList, leaveDetail} from "@/api/work/process";
  export default {
    data() {
      return {
        businessId: '',
        processInstanceId: '',
        src: '',
        flowList: [],
        form: {
          flow:{
            assigneeName:'',
          },
          startTime: '',
          endTime: '',
          reason: '',
        }
      }
    },
    created() {
      this.init();
    },
    methods: {
      init() {
        this.processInstanceId = this.$route.params.processInstanceId;
        this.businessId = this.$route.params.businessId;
        historyFlowList(this.processInstanceId).then(res => {
          const data = res.data;
          if (data.success) {
            this.flowList = data.data;
          }
        })
        leaveDetail(this.businessId).then(res => {
          const data = res.data;
          if (data.success) {
            this.form = data.data;
          }
        })
      },
      handleCancel() {
        this.$router.$avueRouter.closeTag();
        this.$router.push({path: `/work/start`});
      }
    }
  }
</script>
src/views/property/process/leave/form.vue
New file
@@ -0,0 +1,112 @@
<template>
  <div>
    <basic-container>
      <avue-form :option="option" v-model="form" @submit="handleSubmit"/>
    </basic-container>
    <basic-container>
      <flow-design :is-display="true" :process-definition-id="processDefinitionId"></flow-design>
    </basic-container>
  </div>
</template>
<script>
  import {leaveProcess} from "@/api/work/process";
  export default {
    data() {
      return {
        processDefinitionId: '',
        form: {},
        option: {
          group: [
            {
              icon: 'el-icon-info',
              label: '请假基础信息',
              prop: 'group1',
              column: [
                {
                  label: '审批人员',
                  prop: 'taskUser',
                  type: 'select',
                  dicUrl: `/api/blade-system/user/user-list`,
                  props: {
                    label: "account",
                    value: "id"
                  },
                  span: 24,
                  rules: [
                    {
                      required: true,
                      message: '请选择审批人员',
                      trigger: 'blur'
                    }
                  ]
                },
                {
                  label: '开始时间',
                  prop: 'startTime',
                  type: 'datetime',
                  valueFormat: 'yyyy-MM-dd HH:mm:ss',
                  rules: [
                    {
                      required: true,
                      message: '请选择开始时间',
                      trigger: 'blur'
                    }
                  ]
                },
                {
                  label: '结束时间',
                  prop: 'endTime',
                  type: 'datetime',
                  valueFormat: 'yyyy-MM-dd HH:mm:ss',
                  rules: [
                    {
                      required: true,
                      message: '请选择结束时间',
                      trigger: 'blur'
                    }
                  ]
                },
                {
                  label: '请假理由',
                  prop: 'reason',
                  type: 'textarea',
                  span: 24,
                  rules: [
                    {
                      required: true,
                      message: '请输入请假理由',
                      trigger: 'blur'
                    }
                  ]
                },
              ]
            },
          ],
        }
      }
    },
    created() {
      this.processDefinitionId = this.$route.params.processDefinitionId;
    },
    methods: {
      handleSubmit() {
        const params = {
          processDefinitionId: this.$route.params.processDefinitionId,
          ...this.form,
        };
        leaveProcess(params).then(resp => {
          const data = resp.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({path: `/work/start`});
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        });
      }
    }
  }
</script>
src/views/property/process/leave/handle.vue
New file
@@ -0,0 +1,169 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
      <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button type="primary" @click="handleAgree">同意</el-button>
          <el-button type="danger" @click="handleDisagree">驳回</el-button>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row>
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <el-form-item label="申请人">
          <el-input :disabled="true" v-model="form.flow.assigneeName"/>
        </el-form-item>
        <el-row>
          <el-col :span="12">
            <el-form-item label="开始时间">
              <el-input :disabled="true" v-model="form.startTime"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="结束时间">
              <el-input :disabled="true" v-model="form.endTime"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="请假理由">
          <el-input :disabled="true" type="textarea" v-model="form.reason"/>
        </el-form-item>
        <el-form-item label="批复意见">
          <el-input type="textarea" v-model="form.comment"/>
        </el-form-item>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{flow.assigneeName}} 在 [{{flow.createTime}}] 开始处理 [{{flow.historyActivityName}}] 环节</p>
                <p v-if="flow.historyActivityDurationTime!==''">任务历时 [{{flow.historyActivityDurationTime}}]</p>
                <p v-if="flow.comment!==''">批复意见: [{{flow.comment}}]</p>
                <p v-if="flow.endTime!==''">结束时间: [{{flow.endTime}}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
  </basic-container>
</template>
<script>
  import {historyFlowList, leaveDetail} from "@/api/work/process";
  import {completeTask} from "@/api/work/work";
  export default {
    data() {
      return {
        taskId: '',
        businessId: '',
        processInstanceId: '',
        src: '',
        flowList: [],
        form: {
          flow: {
            assigneeName: '',
          },
          startTime: '',
          endTime: '',
          reason: '',
          comment: '',
        },
      }
    },
    created() {
      this.init();
    },
    beforeRouteUpdate(to, from, next) {
      // 在当前路由改变,但是该组件被复用时调用
      // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候
      // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用
      // 可以访问组件实例 `this`
      if (to.fullPath !== from.fullPath) {
        next();
        this.init();
      }
    },
    methods: {
      init() {
        this.taskId = this.$route.params.taskId;
        this.processInstanceId = this.$route.params.processInstanceId;
        this.businessId = this.$route.params.businessId;
        historyFlowList(this.processInstanceId).then(res => {
          const data = res.data;
          if (data.success) {
            this.flowList = data.data;
          }
        })
        leaveDetail(this.businessId).then(res => {
          const data = res.data;
          if (data.success) {
            this.form = data.data;
          }
        })
      },
      handleAgree() {
        if (!this.form.comment) {
          this.$message.warning('请先填写批复意见');
          return;
        }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          flag: 'ok',
          comment: this.form.comment,
        };
        completeTask(params).then(res => {
          const data = res.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({path: `/work/start`});
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        })
      },
      handleDisagree() {
        if (!this.form.comment) {
          this.$message.warning('请先填写批复意见');
          return;
        }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          comment: this.form.comment,
        };
        completeTask(params).then(res => {
          const data = res.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({path: `/work/start`});
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        })
      },
      handleCancel() {
        this.$router.$avueRouter.closeTag();
        this.$router.push({path: `/work/start`});
      }
    }
  }
</script>
src/views/property/process/maintenanceFundApply/detail.vue
New file
@@ -0,0 +1,325 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" label-width="80px">
      <!-- <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row> -->
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <avue-form :option="option" :value="form"></avue-form>
        <!-- <el-form-item label="申请人">
          <el-input :disabled="true" v-model="form.flow.assigneeName" />
        </el-form-item>
        <el-row>
          <el-col :span="12">
            <el-form-item label="开始时间">
              <el-input :disabled="true" v-model="form.startTime" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="结束时间">
              <el-input :disabled="true" v-model="form.endTime" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="请假理由">
          <el-input :disabled="true" type="textarea" v-model="form.reason" />
        </el-form-item> -->
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{flow.assigneeName}} 在 [{{flow.createTime}}] 开始处理 [{{flow.historyActivityName}}] 环节</p>
                <p v-if="flow.historyActivityDurationTime!==''">任务历时 [{{flow.historyActivityDurationTime}}]</p>
                <p v-if="flow.comment!==''">批复意见: [{{flow.comment}}]</p>
                <p v-if="flow.endTime!==''">结束时间: [{{flow.endTime}}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
  </basic-container>
</template>
<script>
  import {
    historyFlowList,
    leaveDetail
  } from "@/api/work/process";
  import {
    getList,
    remove,
    update,
    add,
    getPropertyCapitalApply
  } from "@/api/property/propertyCapitalApply";
  export default {
    data() {
      return {
        businessId: '',
        processInstanceId: '',
        src: '',
        flowList: [],
        form: {
          flow: {
            assigneeName: '',
          },
          startTime: '',
          endTime: '',
          reason: '',
        },
        option: {
          height: "auto",
          calcHeight: 54,
          dialogWidth: 1150,
          tip: false,
          searchShow: true,
          searchMenuSpan: 3,
          menuWidth: 350,
          border: true,
          //stripe:true,
          submitBtn: false,
          emptyBtn: false,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          column: [{
              label: "小区",
              prop: "districtId",
              searchSpan: 5,
              search: true,
              type: 'tree',
              dicUrl: `/api/blade-district/district/getDistrictTree`,
              props: {
                label: "name",
                value: "id"
              },
              defaultExpandedKeys: ["361102003"],
              span: 12,
              labelWidth: 120,
              width: 220,
              overHidden: true,
              rules: [{
                required: true,
                message: "请选择小区",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: '维修项目名称',
              prop: 'name',
              searchLabelWidth: 120,
              searchSpan: 5,
              search: true,
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入维修项目名称",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "预计开工时间",
              prop: "runTime",
              span: 12,
              labelWidth: 140,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同开始时间",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "预计竣工时间",
              prop: "completedTime",
              labelWidth: 140,
              span: 12,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同结束时间",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "项目分摊方式",
              prop: "allocationWay",
              labelWidth: 140,
              value: '按建筑面积分摊',
              span: 12,
              row: true,
              disabled: true
            },
            {
              label: '联系人',
              prop: 'linkman',
              span: 12,
              labelWidth: 120,
              search: true,
              searchSpan: 4,
              rules: [{
                required: true,
                message: "请输入联系人",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: '联系方式',
              prop: 'linkPhone',
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入联系方式",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "项目预算总金额(元)",
              prop: "budgetAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "实际预算金额(元)",
              prop: "actualAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "自筹金额(元)",
              prop: "selfAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "预算应拨付金额(元)",
              prop: "budgetAppropriateAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "项目摘要",
              span: 24,
              hide: true,
              prop: "projectDigest",
              placeholder: "例如:“XX小区XX栋XX设施设备维修,总的预算金额是X,是否含有审价,本次维修涉及范围共XX户,总面积的建筑面积为XX平方米”",
              labelWidth: 140,
              type: "textarea",
              disabled: true
            },
            {
              label: "项目进度描述",
              span: 24,
              hide: true,
              prop: "projectDescribe",
              labelWidth: 140,
              type: "textarea",
              disabled: true
            },
            {
              label: '施工方案附件',
              prop: 'constructionSchemeUrls',
              type: 'upload',
              span: 24,
              hide: true,
              labelWidth: 140,
              multiple: true,
              // showFileList: true,
              propsHttp: {
                res: 'data',
                name: "originalName",
                url: "link"
              },
              action: '/api/blade-resource/oss/endpoint/put-file-attach',
              rules: [{
                required: true,
                message: "请上传施工方案",
                trigger: "blur",
              }, ],
            }
          ],
        }
      }
    },
    created() {
      this.init();
    },
    methods: {
      init() {
        this.processInstanceId = this.$route.params.processInstanceId;
        this.businessId = this.$route.params.businessId;
        historyFlowList(this.processInstanceId).then(res => {
          const data = res.data;
          if (data.success) {
            this.flowList = data.data;
          }
        })
        getPropertyCapitalApply(this.businessId).then(res => {
          const data = res.data;
          if (data.success) {
            this.form = data.data;
          }
        })
      },
      handleCancel() {
        this.$router.$avueRouter.closeTag();
        this.$router.push({
          path: `/work/start`
        });
      }
    }
  }
</script>
src/views/property/process/maintenanceFundApply/edit.vue
New file
@@ -0,0 +1,419 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
      <!--  <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row> -->
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <avue-form ref="crud" :option="option" v-model="form" @submit="handleSubmit">
          <template slot-scope="{size}" slot="menuForm">
            <el-button type="primary" :size="size" @click="$refs.crud.submit()">保存信息</el-button>
            <!-- <el-button :size="size" @click="$refs.form.resetForm()">自定义清空</el-button> -->
          </template>
        </avue-form>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{flow.assigneeName}} 在 [{{flow.createTime}}] 开始处理 [{{flow.historyActivityName}}] 环节</p>
                <p v-if="flow.historyActivityDurationTime!==''">任务历时 [{{flow.historyActivityDurationTime}}]</p>
                <p v-if="flow.comment!==''">批复意见: [{{flow.comment}}]</p>
                <p v-if="flow.endTime!==''">结束时间: [{{flow.endTime}}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
    <div style="text-align: center;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 10px;">
      <el-button type="primary" @click="handleAgree">重新提交</el-button>
      <el-button type="danger" @click="handleDisagree">关闭申请</el-button>
    </div>
  </basic-container>
</template>
<script>
  import {
    historyFlowList,
    leaveDetail
  } from "@/api/work/process";
  import {
    getList,
    remove,
    update,
    add,
    getPropertyCapitalApply
  } from "@/api/property/propertyCapitalApply";
  import {
    completeTask
  } from "@/api/work/work";
  export default {
    data() {
      return {
        taskId: '',
        businessId: '',
        processInstanceId: '',
        src: '',
        flowList: [],
        form: {
          flow: {
            assigneeName: '',
          },
          startTime: '',
          endTime: '',
          reason: '',
          comment: '',
        },
        option: {
          height: "auto",
          calcHeight: 54,
          dialogWidth: 1150,
          tip: false,
          searchShow: true,
          searchMenuSpan: 3,
          menuWidth: 350,
          border: true,
          //stripe:true,
          submitBtn: false,
          emptyBtn: false,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          column: [{
              label: "小区",
              prop: "districtId",
              searchSpan: 5,
              search: true,
              type: 'tree',
              dicUrl: `/api/blade-district/district/getDistrictTree`,
              props: {
                label: "name",
                value: "id"
              },
              defaultExpandedKeys: ["361102003"],
              span: 12,
              labelWidth: 120,
              width: 220,
              overHidden: true,
              rules: [{
                required: true,
                message: "请选择小区",
                trigger: "blur",
              }, ],
            },
            {
              label: '维修项目名称',
              prop: 'name',
              searchLabelWidth: 120,
              searchSpan: 5,
              search: true,
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入维修项目名称",
                trigger: "blur",
              }, ],
            },
            {
              label: "预计开工时间",
              prop: "runTime",
              span: 12,
              labelWidth: 140,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同开始时间",
                trigger: "blur",
              }, ],
            },
            {
              label: "预计竣工时间",
              prop: "completedTime",
              labelWidth: 140,
              span: 12,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同结束时间",
                trigger: "blur",
              }, ],
            },
            {
              label: "项目分摊方式",
              prop: "allocationWay",
              labelWidth: 140,
              value: '按建筑面积分摊',
              span: 12,
              row: true,
            },
            {
              label: '联系人',
              prop: 'linkman',
              span: 12,
              labelWidth: 120,
              search: true,
              searchSpan: 4,
              rules: [{
                required: true,
                message: "请输入联系人",
                trigger: "blur",
              }, ],
            },
            {
              label: '联系方式',
              prop: 'linkPhone',
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入联系方式",
                trigger: "blur",
              }, ],
            },
            {
              label: "项目预算总金额(元)",
              prop: "budgetAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "实际预算金额(元)",
              prop: "actualAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "自筹金额(元)",
              prop: "selfAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "预算应拨付金额(元)",
              prop: "budgetAppropriateAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "项目摘要",
              span: 24,
              hide: true,
              prop: "projectDigest",
              placeholder: "例如:“XX小区XX栋XX设施设备维修,总的预算金额是X,是否含有审价,本次维修涉及范围共XX户,总面积的建筑面积为XX平方米”",
              labelWidth: 140,
              type: "textarea",
            },
            {
              label: "项目进度描述",
              span: 24,
              hide: true,
              prop: "projectDescribe",
              labelWidth: 140,
              type: "textarea",
            },
            // {
            //   label: "批复意见",
            //   span: 24,
            //   hide: true,
            //   prop: "comment",
            //   labelWidth: 140,
            //   type: "textarea",
            //   rules: [{
            //     required: true,
            //     message: "请输入批复意见",
            //     trigger: "blur",
            //   }, ],
            // },
            {
              label: '施工方案附件',
              prop: 'constructionSchemeUrls',
              type: 'upload',
              span: 24,
              hide: true,
              labelWidth: 140,
              multiple: true,
              // showFileList: true,
              propsHttp: {
                res: 'data',
                name: "originalName",
                url: "link"
              },
              action: '/api/blade-resource/oss/endpoint/put-file-attach',
              rules: [{
                required: true,
                message: "请上传施工方案",
                trigger: "blur",
              }, ],
            }
          ],
        }
      }
    },
    created() {
      this.init();
    },
    beforeRouteUpdate(to, from, next) {
      // 在当前路由改变,但是该组件被复用时调用
      // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候
      // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用
      // 可以访问组件实例 `this`
      if (to.fullPath !== from.fullPath) {
        next();
        this.init();
      }
    },
    methods: {
      handleSubmit(form, done, loading) {
        if (form.constructionSchemeUrls.length > 0) {
          var urls = []
          var split = form.constructionSchemeUrls.split(",");
          split.forEach(url => {
            var names = url.split("jczz/");
            urls.push(names[1])
          })
          form.constructionSchemeUrls = urls.join(",")
        }
        update(form).then(
          () => {
            this.onLoad(this.page);
            this.$message({
              type: "success",
              message: "操作成功!",
            });
            done();
          },
          (error) => {
            window.console.log(error);
            loading();
          }
        );
      },
      init() {
        this.taskId = this.$route.params.taskId;
        this.processInstanceId = this.$route.params.processInstanceId;
        this.businessId = this.$route.params.businessId;
        historyFlowList(this.processInstanceId).then(res => {
          const data = res.data;
          if (data.success) {
            this.flowList = data.data;
          }
        })
        getPropertyCapitalApply(this.businessId).then(res => {
          const data = res.data;
          if (data.success) {
            this.form = data.data;
          }
        })
      },
      handleAgree() {
        // if (!this.form.comment) {
        //   this.$message.warning('请先填写批复意见');
        //   return;
        // }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          flag: 'ok',
          comment: this.form.comment,
        };
        completeTask(params).then(res => {
          const data = res.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({
              path: `/property/propertyCapitalApply`
            });
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        })
      },
      handleDisagree() {
        this.form.comment = '关闭申请'
        if (!this.form.comment) {
          this.$message.warning('请先填写批复意见');
          return;
        }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          comment: this.form.comment,
        };
        completeTask(params).then(res => {
          const data = res.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({
              path: `/property/propertyCapitalApply`
            });
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        })
      },
      handleCancel() {
        this.$router.$avueRouter.closeTag();
        this.$router.push({
          path: `/property/todo`
        });
      }
    }
  }
</script>
src/views/property/process/maintenanceFundApply/form.vue
New file
@@ -0,0 +1,267 @@
<template>
  <div>
    <basic-container>
      <avue-form :option="option" v-model="form" @submit="handleSubmit" />
    </basic-container>
    <basic-container>
      <flow-design :is-display="true" :process-definition-id="processDefinitionId"></flow-design>
    </basic-container>
  </div>
</template>
<script>
  import {
    leaveProcess
  } from "@/api/work/process";
  export default {
    data() {
      return {
        processDefinitionId: '',
        form: {},
        option: {
          height: "auto",
          calcHeight: 54,
          dialogWidth: 1150,
          tip: false,
          searchShow: true,
          searchMenuSpan: 3,
          menuWidth: 350,
          border: true,
          //stripe:true,
          // submitBtn: false,
          // emptyBtn: false,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          column: [{
              label: "小区",
              prop: "districtId",
              searchSpan: 5,
              search: true,
              type: 'tree',
              dicUrl: `/api/blade-district/district/getDistrictTree`,
              props: {
                label: "name",
                value: "id"
              },
              defaultExpandedKeys: ["361102003"],
              span: 12,
              labelWidth: 120,
              width: 220,
              overHidden: true,
              rules: [{
                required: true,
                message: "请选择小区",
                trigger: "blur",
              }, ],
            },
            {
              label: '维修项目名称',
              prop: 'name',
              searchLabelWidth: 120,
              searchSpan: 5,
              search: true,
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入维修项目名称",
                trigger: "blur",
              }, ],
            },
            {
              label: "预计开工时间",
              prop: "runTime",
              span: 12,
              labelWidth: 140,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同开始时间",
                trigger: "blur",
              }, ],
            },
            {
              label: "预计竣工时间",
              prop: "completedTime",
              labelWidth: 140,
              span: 12,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同结束时间",
                trigger: "blur",
              }, ],
            },
            {
              label: "项目分摊方式",
              prop: "allocationWay",
              labelWidth: 140,
              value: '按建筑面积分摊',
              span: 12,
              row: true,
            },
            {
              label: '联系人',
              prop: 'linkman',
              span: 12,
              labelWidth: 120,
              search: true,
              searchSpan: 4,
              rules: [{
                required: true,
                message: "请输入联系人",
                trigger: "blur",
              }, ],
            },
            {
              label: '联系方式',
              prop: 'linkPhone',
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入联系方式",
                trigger: "blur",
              }, ],
            },
            {
              label: "项目预算总金额(元)",
              prop: "budgetAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "实际预算金额(元)",
              prop: "actualAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "自筹金额(元)",
              prop: "selfAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "预算应拨付金额(元)",
              prop: "budgetAppropriateAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
            },
            {
              label: "项目摘要",
              span: 24,
              hide: true,
              prop: "projectDigest",
              placeholder: "例如:“XX小区XX栋XX设施设备维修,总的预算金额是X,是否含有审价,本次维修涉及范围共XX户,总面积的建筑面积为XX平方米”",
              labelWidth: 140,
              type: "textarea",
            },
            {
              label: "项目进度描述",
              span: 24,
              hide: true,
              prop: "projectDescribe",
              labelWidth: 140,
              type: "textarea",
            },
            {
              label: '施工方案附件',
              prop: 'constructionSchemeUrls',
              type: 'upload',
              span: 24,
              hide: true,
              labelWidth: 140,
              multiple: true,
              // showFileList: true,
              propsHttp: {
                res: 'data',
                name: "originalName",
                url: "link"
              },
              action: '/api/blade-resource/oss/endpoint/put-file-attach',
              rules: [{
                required: true,
                message: "请上传施工方案",
                trigger: "blur",
              }, ],
            }
          ],
        },
      }
    },
    created() {
      this.processDefinitionId = this.$route.params.processDefinitionId;
    },
    methods: {
      handleSubmit(form, done, loading) {
        form.constructionSchemeUrls = func.join(form.constructionSchemeUrls)
        if (form.constructionSchemeUrls.length > 0) {
          var urls = []
          var split = form.constructionSchemeUrls.split(",");
          split.forEach(url => {
            var names = url.split("jczz/");
            urls.push(names[1])
          })
          form.constructionSchemeUrls = urls.join(",")
        }
        add(form).then(
          () => {
            this.onLoad(this.page);
            this.$message({
              type: "success",
              message: "操作成功!",
            });
            done();
          },
          (error) => {
            window.console.log(error);
            loading();
          }
        );
      },
      handleSubmit() {
        const params = {
          processDefinitionId: this.$route.params.processDefinitionId,
          ...this.form,
        };
        leaveProcess(params).then(resp => {
          const data = resp.data;
          if (data.success) {
            this.$message.success(data.msg);
            this.$router.$avueRouter.closeTag();
            this.$router.push({
              path: `/work/start`
            });
          } else {
            this.$message.error(data.msg || '提交失败');
          }
        });
      }
    }
  }
</script>
src/views/property/process/maintenanceFundApply/handle.vue
New file
@@ -0,0 +1,419 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
      <!-- <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row> -->
      <el-card shadow="hover">
        <div slot="header">
          <span>审批信息</span>
        </div>
        <avue-form :option="option" v-model="form"></avue-form>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程信息</span>
        </div>
        <el-row type="flex" class="row-bg">
          <el-timeline>
            <el-timeline-item :key="flow.id" :timestamp="flow.createTime" v-for="flow in flowList" placement="top">
              <el-card shadow="hover">
                <p>{{ flow.assigneeName }} 在 [{{ flow.createTime }}] 开始处理 [{{ flow.historyActivityName }}]
                  环节</p>
                <p v-if="flow.historyActivityDurationTime !== ''">任务历时 [{{ flow.historyActivityDurationTime
                                }}]
                </p>
                <p v-if="flow.comment !== ''">批复意见: [{{ flow.comment }}]</p>
                <p v-if="flow.endTime !== ''">结束时间: [{{ flow.endTime }}]</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </el-row>
      </el-card>
      <el-card shadow="hover">
        <div slot="header">
          <span>流程跟踪</span>
        </div>
        <el-row class="row-bg">
          <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
        </el-row>
      </el-card>
    </el-form>
    <!-- <div style="">
      <el-button type="primary" @click="handleAgree">同意</el-button>
      <el-button type="danger" @click="handleDisagree">驳回</el-button>
    </div> -->
    <div style="text-align: center;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 10px;">
      <el-button type="primary" @click="handleAgree">同意</el-button>
      <el-button type="danger" @click="handleDisagree">驳回</el-button>
    </div>
  </basic-container>
</template>
<script>
  import {
    historyFlowList,
    leaveDetail
  } from "@/api/work/process"
  import {
    getList,
    remove,
    update,
    add,
    getPropertyCapitalApply
  } from "@/api/property/propertyCapitalApply"
  import {
    completeTask
  } from "@/api/work/work"
  import website from '@/config/website'
  export default {
    data() {
      return {
        taskId: '',
        businessId: '',
        processInstanceId: '',
        src: '',
        flowList: [],
        form: {
          flow: {
            assigneeName: '',
          },
          startTime: '',
          endTime: '',
          reason: '',
        },
        option: {
          height: "auto",
          calcHeight: 54,
          dialogWidth: 1150,
          tip: false,
          searchShow: true,
          searchMenuSpan: 3,
          menuWidth: 350,
          border: true,
          //stripe:true,
          submitBtn: false,
          emptyBtn: false,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          column: [{
              label: "小区",
              prop: "districtId",
              searchSpan: 5,
              search: true,
              type: 'tree',
              dicUrl: `/api/blade-district/district/getDistrictTree`,
              props: {
                label: "name",
                value: "id"
              },
              defaultExpandedKeys: ["361102003"],
              span: 12,
              labelWidth: 120,
              width: 220,
              overHidden: true,
              rules: [{
                required: true,
                message: "请选择小区",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: '维修项目名称',
              prop: 'name',
              searchLabelWidth: 120,
              searchSpan: 5,
              search: true,
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入维修项目名称",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "预计开工时间",
              prop: "runTime",
              span: 12,
              labelWidth: 140,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同开始时间",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "预计竣工时间",
              prop: "completedTime",
              labelWidth: 140,
              span: 12,
              type: "date",
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd",
              rules: [{
                required: true,
                message: "请选择合同结束时间",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "项目分摊方式",
              prop: "allocationWay",
              labelWidth: 140,
              value: '按建筑面积分摊',
              span: 12,
              row: true,
              disabled: true
            },
            {
              label: '联系人',
              prop: 'linkman',
              span: 12,
              labelWidth: 120,
              search: true,
              searchSpan: 4,
              rules: [{
                required: true,
                message: "请输入联系人",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: '联系方式',
              prop: 'linkPhone',
              span: 12,
              labelWidth: 140,
              rules: [{
                required: true,
                message: "请输入联系方式",
                trigger: "blur",
              }, ],
              disabled: true
            },
            {
              label: "项目预算总金额(元)",
              prop: "budgetAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "实际预算金额(元)",
              prop: "actualAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "自筹金额(元)",
              prop: "selfAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "预算应拨付金额(元)",
              prop: "budgetAppropriateAmount",
              span: 12,
              hide: true,
              labelWidth: 140,
              type: 'number',
              precision: 2,
              value: '0.00',
              disabled: true
            },
            {
              label: "项目摘要",
              span: 24,
              hide: true,
              prop: "projectDigest",
              placeholder: "例如:“XX小区XX栋XX设施设备维修,总的预算金额是X,是否含有审价,本次维修涉及范围共XX户,总面积的建筑面积为XX平方米”",
              labelWidth: 140,
              type: "textarea",
              disabled: true
            },
            {
              label: "项目进度描述",
              span: 24,
              hide: true,
              prop: "projectDescribe",
              labelWidth: 140,
              type: "textarea",
              disabled: true
            }, {
              label: "批复意见",
              span: 24,
              hide: true,
              prop: "comment",
              labelWidth: 140,
              type: "textarea",
              rules: [{
                required: true,
                message: "请输入批复意见",
                trigger: "blur",
              }, ],
            },
            {
              label: '施工方案附件',
              prop: 'constructionSchemeUrls',
              type: 'upload',
              listType: 'picture-img',
              span: 24,
              hide: true,
              labelWidth: 140,
              multiple: true,
              // showFileList: true,
              propsHttp: {
                res: 'data',
                name: "originalName",
                url: "link"
              },
              action: '/api/blade-resource/oss/endpoint/put-file-attach',
              rules: [{
                required: true,
                message: "请上传施工方案",
                trigger: "blur",
              }, ],
            }
          ],
        }
      }
    },
    created() {
      this.init()
    },
    beforeRouteUpdate(to, from, next) {
      // 在当前路由改变,但是该组件被复用时调用
      // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候
      // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用
      // 可以访问组件实例 `this`
      if (to.fullPath !== from.fullPath) {
        next()
        this.init()
      }
    },
    methods: {
      init() {
        this.taskId = this.$route.params.taskId
        this.processInstanceId = this.$route.params.processInstanceId
        this.businessId = this.$route.params.businessId
        historyFlowList(this.processInstanceId).then(res => {
          const data = res.data
          if (data.success) {
            this.flowList = data.data
          }
        })
        getPropertyCapitalApply(this.businessId).then(res => {
          const data = res.data
          if (data.success) {
            data.data.constructionSchemeUrls = website.minioUrl + data.data.constructionSchemeUrls
            this.form = data.data
          }
        })
      },
      handleAgree() {
        if (!this.form.comment) {
          this.$message.warning('请先填写批复意见')
          return
        }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          flag: 'ok',
          comment: this.form.comment,
        }
        completeTask(params).then(res => {
          const data = res.data
          if (data.success) {
            this.$message.success(data.msg)
            this.$router.$avueRouter.closeTag()
            this.$router.push({
              path: `/property/todo`
            })
          } else {
            this.$message.error(data.msg || '提交失败')
          }
        })
      },
      handleDisagree() {
        if (!this.form.comment) {
          this.$message.warning('请先填写批复意见')
          return
        }
        const params = {
          taskId: this.taskId,
          processInstanceId: this.processInstanceId,
          comment: this.form.comment,
        }
        completeTask(params).then(res => {
          const data = res.data
          if (data.success) {
            this.$message.success(data.msg)
            this.$router.$avueRouter.closeTag()
            this.$router.push({
              path: `/property/todo`
            })
          } else {
            this.$message.error(data.msg || '提交失败')
          }
        })
      },
      handleCancel() {
        this.$router.$avueRouter.closeTag()
        this.$router.push({
          path: `/property/todo`
        })
      }
    }
  }
</script>
<style scoped>
  .container {
    position: relative;
    /* 确保按钮相对于该元素定位 */
  }
  #myButton {
    position: fixed;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  }
</style>
src/views/property/todo.vue
@@ -1,216 +1,215 @@
<template>
    <basic-container>
        <avue-crud :option="option" :table-loading="loading" :data="data" ref="crud" v-model="form"
            @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
            @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
            <template slot-scope="{row, size, index}" slot="menu">
                <el-button type="text" :size="size" icon="el-icon-s-check" v-if="permission.property_todo_handle"
                    @click.stop="handleWork(row)">处理
                </el-button>
                <el-button type="text" :size="size" icon="el-icon-info" v-if="permission.property_todo_detail"
                    @click.stop="handleDetail(row)">详情
                </el-button>
                <el-button type="text" :size="size" icon="el-icon-search" v-if="permission.property_todo_follow"
                    @click.stop="handleImage(row, index)">流程图
                </el-button>
            </template>
            <template slot-scope="{row, size}" slot="processDefinitionVersion">
                <el-tag :size="size">v{{ row.processDefinitionVersion }}</el-tag>
            </template>
        </avue-crud>
        <flow-design is-dialog :is-display.sync="flowBox" :process-instance-id="processInstanceId"></flow-design>
    </basic-container>
  <basic-container>
    <avue-crud :option="option" :table-loading="loading" :data="data" ref="crud" v-model="form"
      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
      @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
      <template slot-scope="{row, size, index}" slot="menu">
        <el-button type="text" :size="size" icon="el-icon-s-check" v-if="permission.property_todo_handle"
          @click.stop="handleWork(row)">处理
        </el-button>
        <el-button type="text" :size="size" icon="el-icon-info" v-if="permission.property_todo_detail"
          @click.stop="handleDetail(row)">详情
        </el-button>
        <el-button type="text" :size="size" icon="el-icon-search" v-if="permission.property_todo_follow"
          @click.stop="handleImage(row, index)">流程图
        </el-button>
      </template>
      <template slot-scope="{row, size}" slot="processDefinitionVersion">
        <el-tag :size="size">v{{ row.processDefinitionVersion }}</el-tag>
      </template>
    </avue-crud>
    <flow-design is-dialog :is-display.sync="flowBox" :process-instance-id="processInstanceId"></flow-design>
  </basic-container>
</template>
<script>
import {
  import {
    mapGetters
} from "vuex"
import {
  } from "vuex"
  import {
    todoList
} from "@/api/work/work"
import {
  } from "@/api/work/work"
  import {
    flowCategory,
    flowRoute
} from "@/util/flow"
  } from "@/util/flow"
export default {
    data () {
        return {
            form: {},
            selectionId: '',
            selectionList: [],
            query: {},
            loading: true,
            page: {
                pageSize: 10,
                currentPage: 1,
                total: 0
            },
            processInstanceId: '',
            flowBox: false,
            workBox: false,
            option: {
                labelWidth: 120,
                searchLabelWidth: 96,
                searchShow: true,
                searchMenuSpan: 3,
                menuWidth: 210,
  export default {
    data() {
      return {
        form: {},
        selectionId: '',
        selectionList: [],
        query: {},
        loading: true,
        page: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        processInstanceId: '',
        flowBox: false,
        workBox: false,
        option: {
          labelWidth: 120,
          searchLabelWidth: 96,
          searchShow: true,
          searchMenuSpan: 3,
          menuWidth: 210,
                height: 'auto',
                calcHeight: 30,
                tip: false,
                simplePage: true,
                border: true,
                index: true,
                // selection: true,
                editBtn: false,
                addBtn: false,
                viewBtn: false,
                delBtn: false,
                dialogWidth: 900,
                dialogClickModal: false,
                column: [
                    {
                        label: "流程分类",
                        type: "select",
                        row: true,
                        dicUrl: "/api/blade-system/dict/dictionary?code=flow",
                        props: {
                            label: "dictValue",
                            value: "dictKey"
                        },
                        dataType: "number",
                        slot: true,
                        prop: "category",
                        // search: true,
                        hide: true,
                        width: 100,
                    },
                    {
                        width: 100,
                        label: '申请类型',
                        prop: 'categoryName',
                        // search: true,
                    },
                    {
                        width: 220,
                        overHidden: true,
                        label: "小区",
                        prop: "districtId",
                        // search: true,
                        type: 'tree',
                        dicUrl: `/api/blade-district/district/getDistrictTree`,
                        props: {
                            label: "name",
                            value: "id"
                        },
                        defaultExpandedKeys: ["361102003"],
                        searchSpan: 5,
                        span: 12,
                    },
                    {
                        width: 110,
                        label: '联系人',
                        prop: 'linkman',
                        // search: true,
                    },
                    {
                        width: 120,
                        label: '联系电话',
                        prop: 'linkPhone',
                        // search: true,
                    },
                    {
                        label: '项目名称',
                        prop: 'name',
                        // search: true,
                    },
                    {
                        label: '当前步骤',
                        prop: 'taskName',
                    },
                    // {
                    //   label: '流程版本',
                    //   prop: 'processDefinitionVersion',
                    //   // slot: true,
                    //   width: 80,
                    // },
                    {
                        width: 144,
                        label: '申请时间',
                        prop: 'createTime',
                    },
                ]
          height: 'auto',
          calcHeight: 30,
          tip: false,
          simplePage: true,
          border: true,
          index: true,
          // selection: true,
          editBtn: false,
          addBtn: false,
          viewBtn: false,
          delBtn: false,
          dialogWidth: 900,
          dialogClickModal: false,
          column: [{
              label: "流程分类",
              type: "select",
              row: true,
              dicUrl: "/api/blade-system/dict/dictionary?code=flow",
              props: {
                label: "dictValue",
                value: "dictKey"
              },
              dataType: "number",
              slot: true,
              prop: "category",
              // search: true,
              hide: true,
              width: 100,
            },
            data: []
        }
            {
              width: 100,
              label: '申请类型',
              prop: 'categoryName',
              // search: true,
            },
            {
              width: 220,
              overHidden: true,
              label: "小区",
              prop: "districtId",
              // search: true,
              type: 'tree',
              dicUrl: `/api/blade-district/district/getDistrictTree`,
              props: {
                label: "name",
                value: "id"
              },
              defaultExpandedKeys: ["361102003"],
              searchSpan: 5,
              span: 12,
            },
            {
              width: 110,
              label: '联系人',
              prop: 'linkman',
              // search: true,
            },
            {
              width: 120,
              label: '联系电话',
              prop: 'linkPhone',
              // search: true,
            },
            {
              label: '项目名称',
              prop: 'name',
              // search: true,
            },
            {
              label: '当前步骤',
              prop: 'taskName',
            },
            // {
            //   label: '流程版本',
            //   prop: 'processDefinitionVersion',
            //   // slot: true,
            //   width: 80,
            // },
            {
              width: 144,
              label: '申请时间',
              prop: 'createTime',
            },
          ]
        },
        data: []
      }
    },
    computed: {
        ...mapGetters(["permission", "flowRoutes"]),
        ids () {
            let ids = []
            this.selectionList.forEach(ele => {
                ids.push(ele.id)
            })
            return ids.join(",")
        },
      ...mapGetters(["permission", "flowRoutes"]),
      ids() {
        let ids = []
        this.selectionList.forEach(ele => {
          ids.push(ele.id)
        })
        return ids.join(",")
      },
    },
    methods: {
        searchReset () {
            this.query = {}
            this.onLoad(this.page)
        },
        searchChange (params, done) {
            this.query = params
            this.page.currentPage = 1
            this.onLoad(this.page, params)
            done()
        },
        selectionChange (list) {
            this.selectionList = list
        },
        selectionClear () {
            this.selectionList = []
            this.$refs.crud.toggleSelection()
        },
        handleWork (row) {
            this.$router.push({
                path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/handle/${row.taskId}/${row.processInstanceId}/${row.businessId}`
            })
        },
        handleDetail (row) {
            this.$router.push({
                path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}`
            })
        },
        handleImage (row) {
            this.processInstanceId = row.processInstanceId
            this.flowBox = true
        },
        currentChange (currentPage) {
            this.page.currentPage = currentPage
        },
        sizeChange (pageSize) {
            this.page.pageSize = pageSize
        },
        refreshChange () {
            this.onLoad(this.page, this.query)
        },
        onLoad (page, params = {}) {
            const query = {
                ...this.query,
                category: (params.category) ? flowCategory(params.category) : null
            }
            this.loading = true
            todoList(page.currentPage, page.pageSize, Object.assign(params, query)).then(res => {
                const data = res.data.data
                this.page.total = data.total
                this.data = data.records
                this.loading = false
                this.selectionClear()
            })
      searchReset() {
        this.query = {}
        this.onLoad(this.page)
      },
      searchChange(params, done) {
        this.query = params
        this.page.currentPage = 1
        this.onLoad(this.page, params)
        done()
      },
      selectionChange(list) {
        this.selectionList = list
      },
      selectionClear() {
        this.selectionList = []
        this.$refs.crud.toggleSelection()
      },
      handleWork(row) {
        this.$router.push({
          path: `/property/process/${flowRoute(this.flowRoutes, row.category)}/handle/${row.taskId}/${row.processInstanceId}/${row.businessId}`
        })
      },
      handleDetail(row) {
        this.$router.push({
          path: `/property/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}`
        })
      },
      handleImage(row) {
        this.processInstanceId = row.processInstanceId
        this.flowBox = true
      },
      currentChange(currentPage) {
        this.page.currentPage = currentPage
      },
      sizeChange(pageSize) {
        this.page.pageSize = pageSize
      },
      refreshChange() {
        this.onLoad(this.page, this.query)
      },
      onLoad(page, params = {}) {
        const query = {
          ...this.query,
          category: (params.category) ? flowCategory(params.category) : null
        }
        this.loading = true
        todoList(page.currentPage, page.pageSize, Object.assign(params, query)).then(res => {
          const data = res.data.data
          this.page.total = data.total
          this.data = data.records
          this.loading = false
          this.selectionClear()
        })
      }
    }
}
  }
</script>
src/views/work/process/maintenanceFundApply/edit.vue
@@ -1,11 +1,11 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
      <el-row type="flex" class="row-bg" justify="end">
      <!--  <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <!-- <el-button @click="handleCancel">关闭</el-button> -->
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row>
      </el-row> -->
src/views/work/process/maintenanceFundApply/handle.vue
@@ -1,11 +1,11 @@
<template>
  <basic-container>
    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
      <el-row type="flex" class="row-bg" justify="end">
      <!-- <el-row type="flex" class="row-bg" justify="end">
        <el-form-item>
          <el-button @click="handleCancel">关闭</el-button>
        </el-form-item>
      </el-row>
      </el-row> -->
      <el-card shadow="hover">
        <div slot="header">