Files
school-developer/src/views/jsonflow/run-job/do-job.vue
吴红兵 1f645dad3e init
2025-12-02 10:37:49 +08:00

410 lines
21 KiB
Vue

<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<el-row v-show="showSearch">
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
<el-form-item :label="$t('runFlow.initiatorId')" prop="initiatorId" >
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
<el-select v-model="state.queryForm.initiatorId" :placeholder="t('runFlow.inputInitiatorIdTip')" clearable filterable style="max-width: 180px"
remote :remote-method="remoteMethod" :reserve-keyword="false">
<el-option v-for="(item, index) in dicData.initiatorId" :key="index" :label="item.name" :value="item.userId"></el-option>
</el-select>
</el-tooltip>
</el-form-item>
<el-form-item :label="$t('runFlow.code')" prop="flowInstId" >
<el-select v-model="state.queryForm.flowInstId" :placeholder="t('runFlow.inputCodeTip')" clearable filterable
@change="cascadeChange('flowInstId', ['runNodeId'])" style="max-width: 180px">
<el-option v-for="(item, index) in dicData.flowInstId" :key="index" :label="item.code" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('runJob.runNodeId')" prop="runNodeId" >
<el-select v-model="state.queryForm.runNodeId" :placeholder="t('runJob.inputRunNodeIdTip')" clearable filterable style="max-width: 180px"
@change="cascadeChange('runNodeId', ['runJobId'])">
<el-option v-for="(item, index) in cascadeDic.runNodeId" :key="index" :label="item.nodeName" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('runJob.id')" prop="id" >
<el-select v-model="state.queryForm.id" :placeholder="t('runJob.inputIdTip')" clearable filterable style="max-width: 180px">
<el-option v-for="(item, index) in cascadeDic.runJobId" :key="index" :label="item.jobName" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('runJob.status')" prop="status" >
<el-select v-model="state.queryForm.status" :placeholder="t('runJob.inputStatusTip')" clearable filterable style="max-width: 180px">
<el-option v-for="(item, index) in DIC_PROP.NODE_STATUS" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="getDataList">
{{ $t('common.queryBtn') }}
</el-button>
<el-button icon="Refresh" @click="resetQuery">{{ $t('common.resetBtn') }}</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="mb8" style="width: 100%">
<el-tabs v-model="data.activeName" class="demo-tabs" @tab-click="methods.handleTabClick">
<el-tab-pane label="全部" name="-1"></el-tab-pane>
<el-tab-pane label="待办理" name="0"></el-tab-pane>
<el-tab-pane label="被抄送" name="1"></el-tab-pane>
<el-tab-pane label="待阅" name="2"></el-tab-pane>
<el-tab-pane label="被加签" name="3"></el-tab-pane>
</el-tabs>
<right-toolbar v-model:showSearch="showSearch" :export="'jsonflow_runjob_export'"
@exportExcel="exportExcel" class="ml10" style="float: right;margin-right: 20px"
@queryTable="getDataList"></right-toolbar>
</div>
</el-row>
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
:row-class-name="tableRowClassName"
@sort-change="sortChangeHandle">
<el-table-column type="index" :label="t('runJob.index')" width="40"/>
<el-table-column prop="initiatorId" :label="t('runFlow.initiatorId')" show-overflow-tooltip>
<template #default="scope">
<convert-name :options="state.dicData.initiatorId" :value="scope.row.initiatorId"
:valueKey="'userId'" :showKey="'name'"></convert-name>
</template>
</el-table-column>
<el-table-column prop="code" :label="t('runFlow.code')" show-overflow-tooltip/>
<el-table-column prop="flowName" :label="t('runJob.defFlowId')" show-overflow-tooltip>
</el-table-column>
<el-table-column prop="orderId" :label="t('flowApplication.formName')" show-overflow-tooltip>
<template #default="scope">
<convert-name :options="state.dicData.orderId" :value="scope.row.orderId"
:valueKey="'id'" :showKey="'formName'"></convert-name>
</template>
</el-table-column>
<!-- <el-table-column prop="runNodeId" :label="t('runJob.runNodeId')" show-overflow-tooltip>
<template #default="scope">
<convert-name :options="state.dicData.runNodeId" :value="scope.row.runNodeId"
:valueKey="'id'" :showKey="'nodeName'"></convert-name>
</template>
</el-table-column>-->
<el-table-column prop="jobName" :label="t('runJob.jobName')" show-overflow-tooltip/>
<el-table-column prop="jobType" :label="t('runJob.jobType')" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="DIC_PROP.JOB_USER_TYPE" :value="scope.row.jobType"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="roleId" :label="t('runJob.roleId')">
<template #default="scope">
<convert-role-name :options="{users: state.dicData.users, roles: state.dicData.roles, posts: state.dicData.posts, depts: state.dicData.depts}"
:value="scope.row"></convert-role-name>
</template>
</el-table-column>
<el-table-column prop="receiveTime" :label="t('runJob.startTime')" show-overflow-tooltip width="160px"/>
<el-table-column prop="timeLimit" :label="t('runJob.timeLimit')" show-overflow-tooltip/>
<el-table-column prop="status" :label="t('runJob.status')" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="DIC_PROP.NODE_STATUS" :value="scope.row.status"></dict-tag>
</template>
</el-table-column>
<!-- <el-table-column prop="suspension" :label="t('runJob.suspension')" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="DIC_PROP.YES_OR_NO" :value="scope.row.suspension"></dict-tag>
</template>
</el-table-column>-->
<!-- <el-table-column prop="isRead" :label="t('runJob.isRead')" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="DIC_PROP.YES_OR_NO" :value="scope.row.isRead"></dict-tag>
</template>
</el-table-column>-->
<el-table-column prop="suspensionReason" :label="t('runJob.suspensionReason')" show-overflow-tooltip/>
<el-table-column prop="parFlowInstId" :label="t('runJob.parFlowInstId')" show-overflow-tooltip>
<template #default="scope">
<el-tooltip placement="top" content="点击可查看关联父流程工单信息" v-if="scope.row.parFlowInstId">
<convert-name :options="state.dicData.parFlowInstId" :value="scope.row.parFlowInstId"
:valueKey="'id'" :showKey="'flowName'"
:elTagType="'primary'" @click="methods.handleJobByFlowInstId(scope.row, '1')"></convert-name>
</el-tooltip>
</template>
</el-table-column>
<el-table-column :label="$t('common.action')" width="150">
<template #default="scope">
<el-dropdown style="vertical-align: middle; margin-right: 10px">
<span>
功能
<el-icon class="el-icon--right">
<arrow-down/>
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
@click.native="methods.handleComment(scope.row)">查看审批过程
</el-dropdown-item>
<el-dropdown-item
divided
@click.native="methods.handleFlowPic(scope.row)">查看流程图
</el-dropdown-item>
<el-dropdown-item
v-if="scope.row.jobType !== DIC_PROP.JOB_USER_TYPE[0].value"
divided
@click.native="methods.handleSignForJob(scope.row, '1')"
>签收任务
</el-dropdown-item>
<el-dropdown-item
v-if="scope.row.jobType === DIC_PROP.JOB_USER_TYPE[0].value && scope.row.roleId === userInfo.userInfos.user.userId"
divided
@click.native="methods.handleSignForJob(scope.row, '0')"
>反签收任务
</el-dropdown-item>
<el-dropdown-item
v-if="scope.row.suspension === '1'"
divided
@click.native="methods.handleSuspension(scope.row,'0')"
>激活任务
</el-dropdown-item>
<el-dropdown-item
v-if="scope.row.suspension !== '1'"
divided
@click.native="methods.handleSuspension(scope.row,'1')"
>挂起任务
</el-dropdown-item>
<el-dropdown-item
v-if="scope.row.suspension !== '1'"
divided
@click.native="methods.handleJobRoleUserId(scope.row,'0')">
转办任务
</el-dropdown-item>
<el-dropdown-item divided
@click.native="methods.handleEarlyComplete(scope.row)">
提前结束流程
</el-dropdown-item>
<el-dropdown-item divided
@click.native="methods.handleTerminateFlow(scope.row)">
终止流程
</el-dropdown-item>
<el-dropdown-item divided
@click.native="methods.handleInvalidFlow(scope.row)">
作废流程
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-button icon="Stamp" text type="primary"
v-if="scope.row.suspension !== '1' && (scope.row.status === '0' || scope.row.status === '9') && scope.row.belongType !== '2'"
@click="methods.handleJob(scope.row)">审批
</el-button>
<el-button icon="Stamp" text type="primary"
v-if="scope.row.suspension !== '1' && scope.row.belongType === '2' && scope.row.isRead === '0'"
@click="methods.handleJob(scope.row, '0', '1')">查看
</el-button>
</template>
</el-table-column>
</el-table>
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
v-bind="state.pagination"/>
</div>
<!-- 查看审批过程 -->
<el-dialog
v-model="data.showComment" v-if="data.showComment"
top="20px"
width="90%"
title="查看审批过程"
append-to-body>
<comment :curr-job="data.currJob"></comment>
</el-dialog>
<!-- 查看流程图 -->
<el-drawer
class="flow-overflow-drawer" direction="rtl"
append-to-body size="90%"
v-model="data.showFlowPic"
>
<flow-photo v-if="data.showFlowPic" :curr-job="data.currJob"></flow-photo>
</el-drawer>
<user-role-picker ref="userRolePicker" :isOnlyOne="true" @onSelectItems="methods.onSelectItems">
</user-role-picker>
</div>
</template>
<script setup lang="ts" name="DoJob">
import {BasicTableProps, useTable} from "/@/hooks/table";
import {useMessage} from "/@/hooks/message";
import {useI18n} from "vue-i18n";
import {onCascadeChange, onLoadDicUrl, onLoaded, remoteMethodByKey} from "/@/flow/components/convert-name/convert";
import * as doJob from '/@/api/jsonflow/do-job'
import {useFlowJob} from "/@/flow/stores/flowJob";
import {useUserInfo} from "/@/stores/userInfo";
import {handleFlowPreview} from "/@/flow/support/extend";
import {PROP_CONST} from "/@/flow/support/prop-const";
import {
handleEarlyComplete, handleInvalidFlow,
handleSignForJob,
handleSuspension, handleTerminateFlow,
onSignForJob, onTurnRunJob
} from "/@/flow/components/handle-job";
const $route = useRoute();
const userInfo = useUserInfo();
const $message = useMessage();
const {proxy} = getCurrentInstance();
// 引入组件
const UserRolePicker = defineAsyncComponent(() => import('../../../flow/components/user-role/picker.vue'));
const Comment = defineAsyncComponent(() => import('../comment/timeline.vue'));
const FlowPhoto = defineAsyncComponent(() => import('../flow-design/view.vue'));
const flowJob = useFlowJob()
const {t} = useI18n()
const $router = useRouter();
// 定义查询字典
const dicData = reactive({});
const cascadeDic = reactive({});
const onLoad = onLoadDicUrl({key: "flowInstId"});
const onCascade = onCascadeChange(cascadeDic, {key: "flowInstId", cascades: ["runNodeId"]}, {key: "runNodeId", cascades: ["runJobId"]});
onMounted(async () => {
let belongType = $route.query.belongType;
if (belongType) {
state.queryForm.belongType = belongType
data.activeName = belongType
}
await onLoad(dicData);
});
function cascadeChange(key, cascades){
onCascade(state.queryForm, {key: key, cascades: cascades});
}
// 搜索变量
const queryRef = ref()
const showSearch = ref(true)
const data = reactive({
// 0、转办
nodeUserType: undefined,
currJob: undefined,
queryForm: {},
showComment: false,
showFlowPic: false,
activeName: '-1'
});
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {belongType: data.activeName},
pageList: doJob.fetchTodoPage,
onLoaded: onLoaded({key: "initiatorId"}, {key: "parFlowInstId"}, {key: "orderId"}, {key: "runNodeId"}, ...PROP_CONST.LOAD_USER_ROLE),
descs: ["receive_time"]
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
downBlobFile
} = useTable(state)
// 清空搜索条件
const resetQuery = () => {
// 清空搜索条件
queryRef.value?.resetFields()
getDataList()
}
// 导出excel
const exportExcel = () => {
downBlobFile('/jsonflow/run-job/export', state.queryForm, 'run-job.xlsx')
}
const tableRowClassName = ({row, rowIndex}) => {
if (row.isRead !== '1') {
return 'row-custom-warning'
}
return ''
}
function remoteMethod(query: string) {
remoteMethodByKey(query, onLoad, dicData, 'userName', "initiatorId")
}
const methods = {
handleTabClick(tab) {
if (data.activeName === tab.paneName) return
state.queryForm.signatureType = null
state.queryForm.belongType = null
if (tab.paneName !== '3') {
state.queryForm.belongType = tab.paneName
} else {
state.queryForm.belongType = '0'
// 仅标识
state.queryForm.signatureType = '-1'
}
getDataList(true)
},
handleJobByFlowInstId(row, type) {
let find;
if (type === '1') {
find = state.dicData.parFlowInstId.find(f => f.id === row.parFlowInstId);
}
methods.handleJob({flowInstId: find.id}, '1', '0')
},
handleJob(row, isView?, isRead?) {
handleFlowPreview($router, row, isView, isRead, $message, flowJob, getDataList)
},
handleJobRoleUserId(row, type) {
data.currJob = row
methods.openJobRoleUserId(type)
},
handleComment(row) {
data.currJob = row
data.showComment = true
},
handleFlowPic(row) {
data.currJob = row
data.showFlowPic = true
},
// 签收反签收任务
handleSignForJob(row, type) {
handleSignForJob(methods, $message, getDataList, row, type)
},
// 反签收任务
onSignForJob(obj) {
onSignForJob($message, flowJob, getDataList, obj)
},
// 挂起激活任务
handleSuspension(row, suspension) {
handleSuspension($message, getDataList, row, suspension)
},
// 选择参与者
openJobRoleUserId(type) {
data.nodeUserType = type
proxy.$refs.userRolePicker.onOpen();
},
onSelectItems(items) {
if (data.nodeUserType === '0') {
methods.onTurnRunJob(items[0])
}
},
// 提前结束流程
handleEarlyComplete(row) {
handleEarlyComplete($message, flowJob, getDataList, row)
},
// 终止流程
handleTerminateFlow(row) {
handleTerminateFlow($message, flowJob, getDataList, row)
},
// 作废流程
handleInvalidFlow(row) {
handleInvalidFlow($message, flowJob, getDataList, row)
},
// 转办任务
onTurnRunJob(role) {
onTurnRunJob($message, flowJob, getDataList, data, role)
}
}
</script>
<style lang="scss">
@import "../../../flow/components/style/flow-drawer.scss";
.el-table .row-custom-warning {
--el-table-tr-bg-color: var(--el-color-warning-light-9);
}
</style>