first commit
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<!--流程图弹窗-->
|
||||
<BasicModal v-bind="$attrs" :bodyStyle="bodyStyle" :width="900" destroyOnClose :footer="null" @register="registerModal" title="流程图">
|
||||
<BpmGraphic :instanceId="procInsId"></BpmGraphic>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, unref, reactive, toRaw } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/src/components/Modal';
|
||||
import BpmGraphic from '/src/views/super/bpm/process/components/BpmGraphic.vue';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { getProcessInfo } from './bpm.api';
|
||||
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register']);
|
||||
// 提示声明
|
||||
const $message = useMessage();
|
||||
// 流程实例id
|
||||
const procInsId = ref('');
|
||||
//样式
|
||||
const bodyStyle = {
|
||||
'overflow-y': 'auto',
|
||||
'overflow-x': 'auto',
|
||||
};
|
||||
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (params) => {
|
||||
//初始化数据
|
||||
await initData(params);
|
||||
});
|
||||
|
||||
/**
|
||||
* 初始化流程数据
|
||||
* @param params
|
||||
*/
|
||||
async function initData(params) {
|
||||
let res = await getProcessInfo(params);
|
||||
if (res.success) {
|
||||
procInsId.value = res.result.processInstanceId;
|
||||
} else {
|
||||
$message.warning(res.message);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<!-- 历史流程任务处理弹出框 -->
|
||||
<a-modal
|
||||
width="80%"
|
||||
style="top: 20px"
|
||||
destroyOnClose
|
||||
:title="data.title"
|
||||
v-model:open="data.visible"
|
||||
:bodyStyle="data.bodyStyle"
|
||||
:footer="null"
|
||||
@cancel="handleModalCancel"
|
||||
>
|
||||
<a-tabs defaultActiveKey="1" tabPosition="left">
|
||||
<a-tab-pane key="1">
|
||||
<template #tab>
|
||||
<Icon icon="ant-design:file-text-outlined" />
|
||||
<span>附加单据</span>
|
||||
</template>
|
||||
<div class="component_div">
|
||||
<template v-if="data.compType == 'comp'">
|
||||
<DynamicLink :path="path" :formData="formData"></DynamicLink>
|
||||
</template>
|
||||
<template v-else-if="data.compType == 'iframe'">
|
||||
<iframe :src="data.iframeUrl" frameborder="0" width="100%" :height="data.height" scrolling="auto"></iframe>
|
||||
</template>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="2">
|
||||
<template #tab>
|
||||
<Icon icon="ant-design:file-text-outlined" />
|
||||
<span>审批记录</span>
|
||||
</template>
|
||||
<HisTaskModule :formData="formData"></HisTaskModule>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="3">
|
||||
<template #tab>
|
||||
<Icon icon="ant-design:sliders-outlined" />
|
||||
<span>流程跟踪</span>
|
||||
</template>
|
||||
<ProcessDiagram :formData="formData"></ProcessDiagram>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, unref, reactive } from 'vue';
|
||||
import {getBpmFormUrl, isUrl} from '/@/utils/is';
|
||||
import { getToken } from '/@/utils/auth';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import DynamicLink from './DynamicLink.vue';
|
||||
import ProcessDiagram from './ProcessDiagram.vue';
|
||||
import HisTaskModule from './HisTaskModule.vue';
|
||||
import { getBizHisProcessNodeInfo } from './bpm.api';
|
||||
const { domainUrl } = useGlobSetting();
|
||||
//数据
|
||||
const data = reactive({
|
||||
loading: false,
|
||||
title: '流程',
|
||||
visible: false,
|
||||
bodyStyle: {
|
||||
padding: '0',
|
||||
height: window.innerHeight - 80 + 'px',
|
||||
'overflow-y': 'auto',
|
||||
},
|
||||
height: window.innerHeight - 120 + 'px',
|
||||
iframeUrl: '',
|
||||
compType: '',
|
||||
});
|
||||
|
||||
const formData = ref({});
|
||||
const path = ref('');
|
||||
/**
|
||||
* 关闭弹窗
|
||||
*/
|
||||
function handleModalCancel() {
|
||||
data.visible = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开弹窗前处理
|
||||
* @param record
|
||||
*/
|
||||
async function handleTrack(params) {
|
||||
let res = await getBizHisProcessNodeInfo(params);
|
||||
if (res.success) {
|
||||
console.log('获取流程节点信息', res);
|
||||
formData.value = {
|
||||
dataId: res.result.dataId,
|
||||
procInsId: res.result.procInsId,
|
||||
tableName: res.result.tableName,
|
||||
vars: res.result.records,
|
||||
};
|
||||
console.log('------获取流程节点信息', unref(formData));
|
||||
path.value = res.result.formUrl;
|
||||
console.log('获取流程节点信息', path);
|
||||
let TOKEN = getToken();
|
||||
let DOMAIN_URL = domainUrl;
|
||||
let TASKID = unref(formData).taskDefKey;
|
||||
|
||||
//let URL = (unref(path) || '').replace(/{{([^}}]+)?}}/g, (s1, s2) => eval(s2)); // URL支持{{ window.xxx }}占位符变量
|
||||
//获取流程审批url
|
||||
let URL = getBpmFormUrl(unref(path), TOKEN, DOMAIN_URL, TASKID);
|
||||
if (isUrl(URL)) {
|
||||
data.iframeUrl = URL;
|
||||
data.compType = 'iframe';
|
||||
} else {
|
||||
data.compType = 'comp';
|
||||
}
|
||||
data.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
handleTrack,
|
||||
data,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ant-tabs-left-content {
|
||||
padding-top: 10px !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<!--委派弹窗-->
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
@register="registerModal"
|
||||
destroyOnClose
|
||||
:bodyStyle="{ minHeight: '100px', maxHeight: '100px' }"
|
||||
:title="title"
|
||||
@ok="handleSubmit"
|
||||
:width="700"
|
||||
>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { delegateFormSchema } from './bpm.data';
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
//组件接受传参
|
||||
const props = defineProps({
|
||||
title: { type: String, default: '请选择委托人', required: false },
|
||||
});
|
||||
|
||||
//表单配置
|
||||
const [registerForm, { resetFields, validate }] = useForm({
|
||||
labelWidth: 90,
|
||||
schemas: delegateFormSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
await resetFields();
|
||||
});
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success', values);
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*update-begin---author:wangshuai ---date:20230703 for:【QQYUN-5685】3、租户角色下,查询居左显示*/
|
||||
:deep(.ant-form-item-control-input-content){
|
||||
text-align: left;
|
||||
}
|
||||
/*update-end---author:wangshuai ---date:20230703 for:【QQYUN-5685】3、租户角色下,查询居左显示*/
|
||||
</style>
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div>
|
||||
<Suspense v-if="comp">
|
||||
<template #default>
|
||||
<component :is="comp" :formData="formData" v-if="comp" form-bpm></component>
|
||||
</template>
|
||||
<template #fallback>
|
||||
<div style="width: 100%; text-align: center; padding-top: 60px">
|
||||
<a-spin spinning tip="表单加载中..." />
|
||||
</div>
|
||||
</template>
|
||||
</Suspense>
|
||||
<div v-else>表单地址不存在</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { defineAsyncComponent, computed, markRaw } from 'vue';
|
||||
import { importViewsFile } from '/@/utils';
|
||||
//组件接受传参
|
||||
const props = defineProps({
|
||||
path: { type: String },
|
||||
formData: { type: Object },
|
||||
});
|
||||
// 表单地址兼容vue2
|
||||
const FORM_PATH_MAP = {
|
||||
'modules/bpm/task/form/OnlineFormDetail': 'super/bpm/process/components/OnlineFormDetail',
|
||||
'modules/bpm/task/form/OnlineFormOpt': 'super/bpm/process/components/OnlineFormOpt',
|
||||
//借款申请表单
|
||||
'modules/extbpm/joa/modules/JoaLoanApplyForm': 'super/bpm/example/joa/loan/components/LoanApplyForm',
|
||||
//借款表单
|
||||
'modules/extbpm/joa/modules/JoaLoanForm': 'super/bpm/example/joa/loan/components/LoanForm',
|
||||
//出差表单
|
||||
'modules/extbpm/joa/modules/JoaBusinesStripForm': 'super/bpm/example/joa/businessTrip/components/BusinessTripForm',
|
||||
//请假表单
|
||||
'modules/extbpm/joa/modules/JoaEmployeeLeaveForm': 'super/bpm/example/joa/leave/components/LeaveForm',
|
||||
//公文表单
|
||||
'modules/extbpm/joa/modules/JoaDocSendingForm': 'super/bpm/example/joa/docSend/components/DocSendForm',
|
||||
//批量请假单
|
||||
'modules/extbpm/biz/modules/ExtBizLeaveForm': 'super/bpm/example/batch/components/BizLeaveForm',
|
||||
};
|
||||
//组件路径
|
||||
/**
|
||||
* 获取组件
|
||||
* @type {ComputedRef<function(): *>}
|
||||
*/
|
||||
const comp = computed(() => {
|
||||
let temp = props.path;
|
||||
if (FORM_PATH_MAP[temp]) {
|
||||
temp = FORM_PATH_MAP[temp];
|
||||
}
|
||||
console.log('bpm组件名称:', temp);
|
||||
console.log('bpm组件数据:', props.formData);
|
||||
return defineAsyncComponent(() => importViewsFile(temp));
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<!-- 历史流程任务处理弹出框 -->
|
||||
<a-modal
|
||||
width="100%"
|
||||
style="top: 0"
|
||||
wrapClassName="full-modal"
|
||||
destroyOnClose
|
||||
:title="data.title"
|
||||
v-model:open="data.visible"
|
||||
:bodyStyle="data.bodyStyle"
|
||||
:footer="null"
|
||||
@cancel="handleModalCancel"
|
||||
>
|
||||
<a-tabs defaultActiveKey="1" tabPosition="left">
|
||||
<a-tab-pane key="1">
|
||||
<template #tab>
|
||||
<Icon icon="ant-design:file-text-outlined" />
|
||||
<span>附加单据</span>
|
||||
</template>
|
||||
<div class="component_div">
|
||||
<template v-if="isComp">
|
||||
<DynamicLink v-if="path" :path="path" :formData="formData"></DynamicLink>
|
||||
<div v-else>表单地址不存在</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<iframe :src="data.iframeUrl" frameborder="0" width="100%" :height="data.height" scrolling="auto"></iframe>
|
||||
</template>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="2">
|
||||
<template #tab>
|
||||
<Icon icon="ant-design:user-outlined" />
|
||||
<span>任务处理</span>
|
||||
</template>
|
||||
<HisTaskModule :formData="formData"></HisTaskModule>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="3">
|
||||
<template #tab>
|
||||
<Icon icon="ant-design:sliders-outlined" />
|
||||
<span>流程图</span>
|
||||
</template>
|
||||
<ProcessDiagram :formData="formData"></ProcessDiagram>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, reactive } from 'vue';
|
||||
import { getBpmFormUrl, isUrl} from '/@/utils/is';
|
||||
import { getToken } from '/@/utils/auth';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import DynamicLink from './DynamicLink.vue';
|
||||
import ProcessDiagram from './ProcessDiagram.vue';
|
||||
import HisTaskModule from './HisTaskModule.vue';
|
||||
|
||||
const globSetting = useGlobSetting();
|
||||
//组件接受传参
|
||||
const props = defineProps({
|
||||
path: { type: String },
|
||||
formData: { type: Object },
|
||||
});
|
||||
//数据
|
||||
const data = reactive({
|
||||
loading: false,
|
||||
title: '流程',
|
||||
visible: false,
|
||||
bodyStyle: {
|
||||
padding: '0',
|
||||
height: window.innerHeight - 80 + 'px',
|
||||
'overflow-y': 'auto',
|
||||
},
|
||||
height: window.innerHeight - 120 + 'px',
|
||||
iframeUrl: '',
|
||||
});
|
||||
|
||||
let TOKEN = getToken();
|
||||
let DOMAIN_URL = globSetting.domainUrl;
|
||||
let TASKID = props?.formData?.taskDefKey;
|
||||
|
||||
//是否组件
|
||||
const isComp = computed(() => {
|
||||
//获取流程审批url
|
||||
//let URL = (props.path || '').replace(/{{([^}}]+)?}}/g, (s1, s2) => eval(s2)); // URL支持{{ window.xxx }}占位符变量
|
||||
let URL = getBpmFormUrl(props.path, TOKEN, DOMAIN_URL, TASKID);
|
||||
|
||||
if (isUrl(URL)) {
|
||||
data.iframeUrl = URL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
/**
|
||||
* 关闭弹窗
|
||||
*/
|
||||
function handleModalCancel() {
|
||||
data.visible = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开弹窗前处理
|
||||
* @param record
|
||||
*/
|
||||
function deal(record) {
|
||||
data.visible = true;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
deal,
|
||||
data,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.component_div {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
:deep(.ant-modal) {
|
||||
top: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<!--流程任务历史-->
|
||||
<div>
|
||||
<!-- 步骤条 -->
|
||||
<a-spin :spinning="loading">
|
||||
<a-card>
|
||||
<a-steps progressDot :current="stepIndex" style="padding: 10px" size="default">
|
||||
<template v-if="resultObj.bpmLogListCount > 3">
|
||||
<a-step>
|
||||
<template #title>
|
||||
<div class="task-title">...</div>
|
||||
</template>
|
||||
</a-step>
|
||||
</template>
|
||||
<template v-for="(item, index) in resultObj.bpmLogStepList">
|
||||
<a-step>
|
||||
<template #title>
|
||||
<div class="task-title">{{ item.taskName }}</div>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="descriptionDiv">
|
||||
<span>
|
||||
<a-avatar shape="square" style="background-color: #40a9ff">
|
||||
<template #icon><UserOutlined /></template>
|
||||
</a-avatar>
|
||||
</span>
|
||||
<span style="margin-left: 5px">
|
||||
<div class="task-date" style="text-align: left">
|
||||
<a-tooltip placement="top">
|
||||
<template #title
|
||||
><span>{{ item.opTime }}</span></template
|
||||
>
|
||||
<span> {{ item.opTime ? item.opTime.substr(0, 10) : item.opTime }}</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div class="task-user" style="text-align: left"
|
||||
><span> {{ item.opUserName }}</span></div
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-step>
|
||||
</template>
|
||||
<template v-if="resultObj.currTaskName && resultObj.currTaskName != ''">
|
||||
<a-step>
|
||||
<template #title>
|
||||
<div class="task-title">{{ resultObj.currTaskName }}</div>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="descriptionDiv">
|
||||
<a-avatar style="background-color: #faad14eb">
|
||||
<template #icon><UserOutlined /></template>
|
||||
</a-avatar>
|
||||
<span style="margin-left: 5px">
|
||||
<div class="task-date" style="text-align: left">
|
||||
<a-tooltip placement="top">
|
||||
<template #title
|
||||
><span>{{ resultObj.currTaskNameStartTime }}</span></template
|
||||
>
|
||||
<span style="color: #ff6d75">
|
||||
{{
|
||||
resultObj.currTaskNameStartTime ? resultObj.currTaskNameStartTime.substr(0, 10) : resultObj.currTaskNameStartTime
|
||||
}}</span
|
||||
>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div class="task-user" style="text-align: left"
|
||||
><span> {{ resultObj.currTaskNameAssignee }}</span></div
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-step>
|
||||
<a-step>
|
||||
<template #title>
|
||||
<div class="task-title">...</div>
|
||||
</template>
|
||||
</a-step>
|
||||
</template>
|
||||
</a-steps>
|
||||
</a-card>
|
||||
<!-- 意见 -->
|
||||
<a-card title="意见信息" :bodyStyle="{ padding: '0 20px' }" size="default" style="margin-top: 20px">
|
||||
<a-list itemLayout="vertical">
|
||||
<template v-for="(item, index) in resultObj.bpmLogList">
|
||||
<a-list-item>
|
||||
<a-list-item-meta :description="item.remarks||'无意见信息'">
|
||||
<template #title>
|
||||
<a
|
||||
><p>{{ item.opUserName }}</p
|
||||
><span style="color: #ff6d75">[{{ item.taskName }}]</span> {{ item.opTime }}</a
|
||||
>
|
||||
</template>
|
||||
<template #avatar>
|
||||
<a-avatar :size="36" style="background-color: #51cbff">
|
||||
<template #icon><UserOutlined /></template>
|
||||
</a-avatar>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
<template v-for="(file, index) in item.bpmFiles" :key="index">
|
||||
<div class="ant-upload-list ant-upload-list-text">
|
||||
<div class="ant-upload-list-item ant-upload-list-item-done">
|
||||
<div class="ant-upload-list-item-info">
|
||||
<span>
|
||||
<PaperClipOutlined />
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
:title="file.fileName"
|
||||
:href="getFileAccessHttpUrl(file.filePath)"
|
||||
class="ant-upload-list-item-name"
|
||||
>{{ file.fileName }}</a
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
</a-card>
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref, onMounted, computed } from 'vue';
|
||||
import JEllipsis from '/@/components/Form/src/jeecg/components/JEllipsis.vue';
|
||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { getHisProcessTaskTransInfo } from './bpm.api';
|
||||
import { UserOutlined, PaperClipOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
//组件接受传参
|
||||
const props = defineProps({
|
||||
formData: { type: Object },
|
||||
});
|
||||
//组件接受传参
|
||||
const resultObj = ref({});
|
||||
const loading = ref(false);
|
||||
//步骤点
|
||||
const stepIndex = computed(() => {
|
||||
if (unref(resultObj).bpmLogListCount > 3) {
|
||||
return unref(resultObj).bpmLogStepListCount + 1;
|
||||
}
|
||||
return unref(resultObj).bpmLogStepListCount;
|
||||
});
|
||||
|
||||
/**
|
||||
* 加载数据
|
||||
* @param formData
|
||||
*/
|
||||
async function loadData(formData) {
|
||||
var params = { procInstId: formData.procInsId }; //查询条件
|
||||
loading.value = true;
|
||||
const res = await getHisProcessTaskTransInfo(params);
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
resultObj.value = res.result;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadData(props.formData);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.task-info {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.task-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.task-date {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ant-steps-item-description {
|
||||
max-width: 200px !important;
|
||||
}
|
||||
|
||||
/** Button按钮间距 */
|
||||
.ant-btn {
|
||||
margin-left: 3px;
|
||||
}
|
||||
/** 标题和描述对齐 */
|
||||
:deep(.ant-steps-item-content) {
|
||||
text-align: left;
|
||||
margin-left: 50px;
|
||||
}
|
||||
/** 描述的样式 */
|
||||
.descriptionDiv {
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="graphic">
|
||||
<!--流程图 -->
|
||||
<BpmGraphic :instanceId="formData.procInsId" @task="getTaskList"></BpmGraphic>
|
||||
</div>
|
||||
<a-card title="流程历史跟踪">
|
||||
<a-table rowKey="taskId" :loading="loading" :dataSource="dataSource" :columns="columns" size="small">
|
||||
<!-- 字符串超长截取省略号显示-->
|
||||
<template #remarks="{ record }">
|
||||
<JEllipsis :value="getNodeInfo(record)" :length="25" />
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref, onMounted } from 'vue';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import JEllipsis from '/@/components/Form/src/jeecg/components/JEllipsis.vue';
|
||||
import BpmGraphic from '/@/views/super/bpm/process/components/BpmGraphic.vue';
|
||||
import { getProcessHistoryList } from './bpm.api';
|
||||
//组件接受传参
|
||||
const props = defineProps({
|
||||
formData: { type: Object },
|
||||
});
|
||||
//提示
|
||||
const { createMessage } = useMessage();
|
||||
const loading = ref(false);
|
||||
//列表数据
|
||||
const dataSource = ref([]);
|
||||
const taskList = ref([]);
|
||||
|
||||
// 查询数据
|
||||
async function loadData() {
|
||||
loading.value = true;
|
||||
let params = { processInstanceId: props.formData.procInsId };
|
||||
const res = await getProcessHistoryList(params);
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
dataSource.value = res.result.records;
|
||||
} else {
|
||||
createMessage.warning('加载失败');
|
||||
}
|
||||
}
|
||||
|
||||
function getTaskList(result) {
|
||||
taskList.value = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节点备注信息
|
||||
* @param record
|
||||
*/
|
||||
function getNodeInfo(record) {
|
||||
let arr = taskList.value;
|
||||
if (arr && arr.length > 0) {
|
||||
for (let item of arr) {
|
||||
if (item.id == record.id) {
|
||||
return item.remarks;
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
taskList.value = [];
|
||||
loadData();
|
||||
});
|
||||
//定义列
|
||||
const columns = [
|
||||
{
|
||||
title: '#',
|
||||
dataIndex: '#',
|
||||
width: 40,
|
||||
customRender: ({ text, index }) => {
|
||||
return parseInt(index) + 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
customRender: ({ text }) => {
|
||||
if (text == 'start1') {
|
||||
return '开始';
|
||||
} else if (text == 'end') {
|
||||
return '结束';
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '流程实例ID',
|
||||
dataIndex: 'processInstanceId',
|
||||
},
|
||||
{
|
||||
title: '开始时间',
|
||||
dataIndex: 'startTime',
|
||||
},
|
||||
{
|
||||
title: '结束时间',
|
||||
dataIndex: 'endTime',
|
||||
},
|
||||
{
|
||||
title: '负责人',
|
||||
dataIndex: 'assigneeName',
|
||||
},
|
||||
{
|
||||
title: '处理结果',
|
||||
dataIndex: 'deleteReason',
|
||||
},
|
||||
{
|
||||
title: '处理意见',
|
||||
fixed: 'right',
|
||||
width: 350,
|
||||
dataIndex: 'remarks',
|
||||
slots: { customRender: 'remarks' },
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.graphic {
|
||||
margin-bottom: 20px;
|
||||
height: 400px;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,53 @@
|
||||
<!--选择跳转节点弹窗-->
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
@register="registerModal"
|
||||
destroyOnClose
|
||||
:bodyStyle="{ minHeight: '100px', maxHeight: '100px' }"
|
||||
title="选择跳转节点"
|
||||
@ok="handleSubmit"
|
||||
:width="700"
|
||||
>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { skipNode } from './bpm.api';
|
||||
import { taskNodeFormSchema } from './bpm.data';
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
//表单配置
|
||||
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: taskNodeFormSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false });
|
||||
await setFieldsValue({
|
||||
...data,
|
||||
});
|
||||
});
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交跳转
|
||||
await skipNode(values);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,133 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
hisProcessNodeInfo = '/act/process/extActProcessNode/getHisProcessNodeInfo',
|
||||
processHistoryList = '/act/task/processHistoryList',
|
||||
hisProcessTaskTransInfo = '/act/task/getHisProcessTaskTransInfo',
|
||||
skipNode = '/act/processInstance/skipNode',
|
||||
taskEntrust = '/act/task/taskEntrust',
|
||||
getAllTask = '/act/processInstance/getAllTask',
|
||||
reassign = '/act/processInstance/reassign',
|
||||
bizHisProcessNodeInfo = '/act/process/extActProcessNode/getBizHisProcessNodeInfo',
|
||||
getNotifyList = '/act/process/extActTaskNotification/mylist',
|
||||
notifyMeList = '/act/process/extActTaskNotification/list',
|
||||
taskNotification = '/act/process/extActTaskNotification/taskNotification',
|
||||
getBizProcessNodeInfo = '/act/process/extActProcessNode/getBizProcessNodeInfo',
|
||||
getProcessTaskTransInfo = '/act/task/getProcessTaskTransInfo',
|
||||
processComplete = '/act/task/processComplete',
|
||||
suspend = '/act/processInstance/suspend',
|
||||
restart = '/act/processInstance/restart',
|
||||
claim = '/act/task/claim',
|
||||
getProcessInfo = '/act/process/extActFlowData/getProcessInfo',
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取流程节点历史信息
|
||||
* @param params
|
||||
*/
|
||||
export const hisProcessNodeInfo = (params) => {
|
||||
return defHttp.get({ url: Api.hisProcessNodeInfo, params }, { isTransformResponse: false });
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取流程历史信息
|
||||
* @param params
|
||||
*/
|
||||
export const getProcessHistoryList = (params) => defHttp.get({ url: Api.processHistoryList, params }, { isTransformResponse: false });
|
||||
|
||||
/**
|
||||
* 获取流程历史流转信息
|
||||
* @param params
|
||||
*/
|
||||
export const getHisProcessTaskTransInfo = (params) => defHttp.get({ url: Api.hisProcessTaskTransInfo, params }, { isTransformResponse: false });
|
||||
|
||||
/**
|
||||
* 委派
|
||||
* @param params
|
||||
*/
|
||||
export const taskEntrust = (params, handleSuccess?) => {
|
||||
return defHttp.put({ url: Api.taskEntrust, params }, { isTransformResponse: false }).then((res) => {
|
||||
handleSuccess && handleSuccess(res);
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 获取所有任务节点
|
||||
* @param params
|
||||
*/
|
||||
export const getAllTask = (params) => defHttp.get({ url: Api.getAllTask, params });
|
||||
/**
|
||||
* 跳转节点
|
||||
* @param params
|
||||
*/
|
||||
export const skipNode = (params) => defHttp.get({ url: Api.skipNode, params });
|
||||
/**
|
||||
* 获取业务流程节点信息
|
||||
* @param params
|
||||
*/
|
||||
export const getBizHisProcessNodeInfo = (params) => defHttp.get({ url: Api.bizHisProcessNodeInfo, params }, { isTransformResponse: false });
|
||||
/**
|
||||
* 获取我催办的流程列表
|
||||
* @param params
|
||||
*/
|
||||
export const getNotifyList = (params) => defHttp.get({ url: Api.getNotifyList, params });
|
||||
/**
|
||||
* 获取催办我的流程列表
|
||||
* @param params
|
||||
*/
|
||||
export const getNotifyMeList = (params) => defHttp.get({ url: Api.notifyMeList, params });
|
||||
/**
|
||||
* 催办
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdateNotify = (params) => {
|
||||
return defHttp.post({ url: Api.taskNotification, params });
|
||||
};
|
||||
/**
|
||||
* 获取业务流程节点信息
|
||||
* @param params
|
||||
*/
|
||||
export const getBizProcessNodeInfo = (params) => {
|
||||
return defHttp.get({ url: Api.getBizProcessNodeInfo, params }, { isTransformResponse: false });
|
||||
};
|
||||
/**
|
||||
* 获取业务流转信息
|
||||
* @param params
|
||||
*/
|
||||
export const getProcessTaskTransInfo = (params) => {
|
||||
return defHttp.get({ url: Api.getProcessTaskTransInfo, params }, { isTransformResponse: false });
|
||||
};
|
||||
/**
|
||||
* 流程办理
|
||||
* @param params
|
||||
*/
|
||||
export const processComplete = (params) => {
|
||||
return defHttp.post({ url: Api.processComplete, params }, { isTransformResponse: false });
|
||||
};
|
||||
/**
|
||||
* 挂起
|
||||
* @param params
|
||||
*/
|
||||
export const suspend = (params) => {
|
||||
return defHttp.get({ url: Api.suspend, params }, { isTransformResponse: false });
|
||||
};
|
||||
/**
|
||||
* 解挂
|
||||
* @param params
|
||||
*/
|
||||
export const restart = (params) => {
|
||||
return defHttp.get({ url: Api.restart, params }, { isTransformResponse: false });
|
||||
};
|
||||
/**
|
||||
* 签收
|
||||
* @param params
|
||||
*/
|
||||
export const claim = (params) => {
|
||||
return defHttp.put({ url: Api.claim, params }, { isTransformResponse: false });
|
||||
};
|
||||
/**
|
||||
* 获取流程信息
|
||||
* @param params
|
||||
*/
|
||||
export const getProcessInfo = (params) => {
|
||||
return defHttp.get({ url: Api.getProcessInfo, params }, { isTransformResponse: false });
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
import { getAllTask } from './bpm.api';
|
||||
|
||||
/**
|
||||
* 委派modal的form
|
||||
*/
|
||||
export const delegateFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'username',
|
||||
label: '用户名',
|
||||
component: 'JSelectUserByDept',
|
||||
required: true,
|
||||
componentProps: {
|
||||
labelKey: 'realname',
|
||||
rowKey: 'username',
|
||||
showButton: false,
|
||||
isRadioSelection: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
/**
|
||||
* 跳转节点form
|
||||
*/
|
||||
export const taskNodeFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'taskId',
|
||||
label: '',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
field: 'skipTaskNode',
|
||||
label: '跳转节点',
|
||||
component: 'ApiSelect',
|
||||
required: true,
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
api: getAllTask,
|
||||
params: { taskId: formModel.taskId },
|
||||
labelField: 'name',
|
||||
valueField: 'taskKey',
|
||||
immediate: false,
|
||||
onChange: (e) => {
|
||||
console.log('selected:', e);
|
||||
},
|
||||
onOptionsChange: (options) => {
|
||||
console.log('get options', options.length, options);
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,51 @@
|
||||
import { ref, unref } from 'vue';
|
||||
import { hisProcessNodeInfo } from '../bpm.api';
|
||||
import { getQueryVariable } from '/@/utils';
|
||||
import { isUrl } from '/@/utils/is';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path 路径
|
||||
* @param taskDealRef 弹窗示例
|
||||
*/
|
||||
export function useBpmNodeInfo(path, taskDealRef) {
|
||||
const formData = ref({});
|
||||
/**
|
||||
* 获取流程历史节点信息
|
||||
* @param record
|
||||
*/
|
||||
function getHisProcessNodeInfo(record) {
|
||||
hisProcessNodeInfo({ procInstId: record.processInstanceId }).then((res) => {
|
||||
console.log('获取流程节点信息', res);
|
||||
if (res.success) {
|
||||
let data = {
|
||||
dataId: res.result.dataId,
|
||||
taskId: record.id,
|
||||
taskDefKey: record.taskId,
|
||||
procInsId: record.processInstanceId,
|
||||
tableName: res.result.tableName,
|
||||
vars: res.result.records,
|
||||
};
|
||||
formData.value = data;
|
||||
//update--begin--autor:scott-----date:20191005------for:流程节点配置组件URL的时候也支持传递参数了,解决TASK #3238流程节点无法与online的复制视图对接------
|
||||
console.log('获取流程节点表单URL ', res.result.formUrl);
|
||||
let tempFormUrl = res.result.formUrl;
|
||||
//节点配置表单URL,VUE组件类型对应的拓展参数
|
||||
if (tempFormUrl && tempFormUrl.indexOf('?') != -1 && !isUrl(tempFormUrl) && tempFormUrl.indexOf('{{DOMAIN_URL}}') == -1) {
|
||||
tempFormUrl = res.result.formUrl.split('?')[0];
|
||||
console.log('获取流程节点表单URL(去掉参数)', tempFormUrl);
|
||||
formData.value['extendUrlParams'] = getQueryVariable(res.result.formUrl);
|
||||
}
|
||||
path.value = tempFormUrl;
|
||||
//update--end--autor:scott-----date:20191005------for:流程节点配置组件URL的时候也支持传递参数了,解决TASK #3238流程节点无法与online的复制视图对接------
|
||||
console.log('获取流程节点信息formData', unref(formData));
|
||||
console.log('获取流程节点信息path', unref(path));
|
||||
taskDealRef.value.deal(record);
|
||||
taskDealRef.value.data.title = '流程历史';
|
||||
console.log('taskDealRef', taskDealRef.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return { getHisProcessNodeInfo, formData };
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit" :width="700" :min-height="300">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema } from '../expression.data';
|
||||
import { saveOrUpdate } from '../expression.api';
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
|
||||
// labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,50 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { Modal } from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
list = '/act/process/extActExpression/list',
|
||||
save = '/act/process/extActExpression/add',
|
||||
edit = '/act/process/extActExpression/edit',
|
||||
delete = '/act/process/extActExpression/delete',
|
||||
deleteBatch = '/act/process/extActExpression/deleteBatch',
|
||||
}
|
||||
/**
|
||||
* 列表
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return isUpdate ? defHttp.put({ url: url, params }) : defHttp.post({ url: url, params });
|
||||
};
|
||||
/**
|
||||
* 删除监听
|
||||
* @param params
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.delete, data: params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
import {render} from "@/utils/common/renderUtils";
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: '表达式名称',
|
||||
dataIndex: 'name',
|
||||
width: 180,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '表达式',
|
||||
width: 180,
|
||||
dataIndex: 'expression',
|
||||
},
|
||||
{
|
||||
title: '业务类型',
|
||||
width: 180,
|
||||
dataIndex: 'bizType',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'processExpressionBizType');
|
||||
},
|
||||
},
|
||||
];
|
||||
/**
|
||||
* 列表查询form
|
||||
*/
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'name',
|
||||
label: '名称',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
// {
|
||||
// field: 'expression',
|
||||
// label: '表达式',
|
||||
// component: 'Input',
|
||||
// colProps: { span: 6 },
|
||||
// },
|
||||
];
|
||||
/**
|
||||
* 表单form
|
||||
*/
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'id',
|
||||
label: '',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '表达式名称',
|
||||
field: 'name',
|
||||
required: true,
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '表达式',
|
||||
field: 'expression',
|
||||
required: true,
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '业务类型',
|
||||
field: 'bizType',
|
||||
required: false,
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'processExpressionBizType',
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="handleBatchDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button
|
||||
>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--监听弹窗-->
|
||||
<ExpressionModal @register="registerModal" @success="reload"></ExpressionModal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" name="process-expression-list" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import ExpressionModal from './components/ExpressionModal.vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { columns, searchFormSchema } from './expression.data';
|
||||
import { list, deleteOne, batchDelete } from './expression.api';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
//弹窗
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
// 列表页面公共参数、方法
|
||||
const { prefixCls, tableContext } = useListPage({
|
||||
designScope: 'process-expression',
|
||||
tableProps: {
|
||||
title: '流程表达式',
|
||||
api: list,
|
||||
columns: columns,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
function handleCreate() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除
|
||||
* @param id
|
||||
*/
|
||||
async function handleDelete(id) {
|
||||
await deleteOne({ id }, reload);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function handleBatchDelete() {
|
||||
await batchDelete({ ids: selectedRowKeys.value }, () => {
|
||||
selectedRowKeys.value = [];
|
||||
reload();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record.id),
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,30 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
list = '/act/task/historyProcessList',
|
||||
invalidProcess = '/act/task/invalidProcess',
|
||||
callBackProcess = '/act/task/callBackProcess',
|
||||
}
|
||||
/**
|
||||
* 列表
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
/**
|
||||
* 作废流程
|
||||
* @param params
|
||||
*/
|
||||
export const invalidProcess = (params, handleSuccess) => {
|
||||
return defHttp.put({ url: Api.invalidProcess, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 取回流程
|
||||
* @param params
|
||||
*/
|
||||
export const callBackProcess = (params, handleSuccess) => {
|
||||
return defHttp.put({ url: Api.callBackProcess, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: '业务标题',
|
||||
dataIndex: 'bpmBizTitle',
|
||||
width: 180,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '流程名称',
|
||||
dataIndex: 'prcocessDefinitionName',
|
||||
},
|
||||
{
|
||||
title: '流程实例',
|
||||
dataIndex: 'processInstanceId',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '发起人',
|
||||
dataIndex: 'startUserName',
|
||||
},
|
||||
{
|
||||
title: '开始日期',
|
||||
dataIndex: 'startTime',
|
||||
},
|
||||
{
|
||||
title: '流程编号',
|
||||
dataIndex: 'processDefinitionId',
|
||||
},
|
||||
{
|
||||
title: '结束时间',
|
||||
dataIndex: 'endTime',
|
||||
},
|
||||
{
|
||||
title: '耗时',
|
||||
dataIndex: 'spendTimes',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'bpmStatus',
|
||||
customRender: ({ text }) => {
|
||||
switch (text) {
|
||||
case '1':
|
||||
return '待提交';
|
||||
case '2':
|
||||
return '处理中';
|
||||
case '3':
|
||||
return '已完成';
|
||||
case 'rejectProcess':
|
||||
return '已驳回';
|
||||
case 'callBackProcess':
|
||||
return '已取回';
|
||||
case 'invalidProcess':
|
||||
return '已作废';
|
||||
}
|
||||
return text;
|
||||
},
|
||||
},
|
||||
];
|
||||
/**
|
||||
* 列表查询form
|
||||
*/
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'processDefinitionId',
|
||||
label: '流程编号',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
field: 'processName',
|
||||
label: '流程名称',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--历史-->
|
||||
<HisTaskDealModal ref="taskDealRef" :path="path" :formData="formData"></HisTaskDealModal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" name="process-hisprocess-list" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import HisTaskDealModal from '../components/HisTaskDealModal.vue';
|
||||
import { useBpmNodeInfo } from '../components/hooks/useBpmNodeInfo';
|
||||
import { columns, searchFormSchema } from './hisprocess.data';
|
||||
import { list, invalidProcess, callBackProcess } from './hisprocess.api';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
|
||||
// 列表页面公共参数、方法
|
||||
const { prefixCls, tableContext } = useListPage({
|
||||
designScope: 'process-hisprocess',
|
||||
tableProps: {
|
||||
api: list,
|
||||
columns: columns,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
const path = ref('');
|
||||
const taskDealRef = ref(null);
|
||||
const { getHisProcessNodeInfo, formData } = useBpmNodeInfo(path, taskDealRef);
|
||||
|
||||
const [registerTable, rowSelection, { reload }] = tableContext;
|
||||
|
||||
/**
|
||||
* 显示历史
|
||||
* @param record
|
||||
*/
|
||||
function showHistory(record) {
|
||||
getHisProcessNodeInfo(record);
|
||||
}
|
||||
/**
|
||||
* 作废流程
|
||||
* @param record
|
||||
*/
|
||||
async function handleInvalidProcess(record) {
|
||||
await invalidProcess(
|
||||
{
|
||||
processInstanceId: record.processInstanceId,
|
||||
},
|
||||
reload
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 取回流程
|
||||
* @param record
|
||||
*/
|
||||
async function handleCallBackProcess(record) {
|
||||
await callBackProcess(
|
||||
{
|
||||
processInstanceId: record.processInstanceId,
|
||||
},
|
||||
reload
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '历史',
|
||||
onClick: showHistory.bind(null, record),
|
||||
ifShow: () => {
|
||||
return record.endTime && record.endTime != '';
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '作废流程',
|
||||
popConfirm: {
|
||||
title: '确定要作废流程吗?',
|
||||
confirm: handleInvalidProcess.bind(null, record),
|
||||
},
|
||||
ifShow: () => {
|
||||
return !record.endTime;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '取回流程',
|
||||
popConfirm: {
|
||||
title: '确定要取回流程吗?',
|
||||
confirm: handleCallBackProcess.bind(null, record),
|
||||
},
|
||||
ifShow: () => {
|
||||
return !record.endTime;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '历史',
|
||||
onClick: showHistory.bind(null, record),
|
||||
ifShow: () => {
|
||||
return !record.endTime;
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,10 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
list = '/act/task/taskAllHistoryList',
|
||||
}
|
||||
/**
|
||||
* 列表
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
@@ -0,0 +1,65 @@
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: '业务标题',
|
||||
dataIndex: 'bpmBizTitle',
|
||||
width: 180,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '流程名称',
|
||||
dataIndex: 'processDefinitionName',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '流程实例',
|
||||
dataIndex: 'processInstanceId',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '任务名称',
|
||||
dataIndex: 'taskName',
|
||||
},
|
||||
{
|
||||
title: '发起人',
|
||||
dataIndex: 'processApplyUserName',
|
||||
},
|
||||
{
|
||||
title: '办理人',
|
||||
dataIndex: 'taskAssigneeName',
|
||||
},
|
||||
{
|
||||
title: '开始时间',
|
||||
dataIndex: 'taskBeginTime',
|
||||
},
|
||||
{
|
||||
title: '结束时间',
|
||||
dataIndex: 'taskEndTime',
|
||||
},
|
||||
{
|
||||
title: '耗时',
|
||||
dataIndex: 'durationStr',
|
||||
},
|
||||
{
|
||||
title: '流程编号',
|
||||
dataIndex: 'processDefinitionId',
|
||||
},
|
||||
];
|
||||
/**
|
||||
* 列表查询form
|
||||
*/
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'processDefinitionId',
|
||||
label: '流程编号',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
field: 'processDefinitionName',
|
||||
label: '流程名称',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--历史-->
|
||||
<HisTaskDealModal ref="taskDealRef" :path="path" :formData="formData"></HisTaskDealModal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" name="process-histask-list" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import HisTaskDealModal from '../components/HisTaskDealModal.vue';
|
||||
import { columns, searchFormSchema } from './histask.data';
|
||||
import { list } from './histask.api';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { useBpmNodeInfo } from '../components/hooks/useBpmNodeInfo';
|
||||
|
||||
// 列表页面公共参数、方法
|
||||
const { prefixCls, tableContext } = useListPage({
|
||||
designScope: 'process-histask',
|
||||
tableProps: {
|
||||
api: list,
|
||||
columns: columns,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, rowSelection, { reload }] = tableContext;
|
||||
const path = ref('');
|
||||
const taskDealRef = ref(null);
|
||||
let { getHisProcessNodeInfo, formData } = useBpmNodeInfo(path, taskDealRef);
|
||||
/**
|
||||
* 显示历史
|
||||
* @param record
|
||||
*/
|
||||
function showHistory(record) {
|
||||
getHisProcessNodeInfo(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '历史',
|
||||
onClick: showHistory.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit" :width="700">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema } from '../listener.data';
|
||||
import { saveOrUpdate } from '../listener.api';
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
|
||||
// labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,41 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
list = '/act/process/extActListener/list',
|
||||
save = '/act/process/extActListener/add',
|
||||
edit = '/act/process/extActListener/edit',
|
||||
delete = '/act/process/extActListener/delete',
|
||||
changeStatus = '/act/process/extActListener/changeStatus',
|
||||
}
|
||||
/**
|
||||
* 列表
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return isUpdate ? defHttp.put({ url: url, params }) : defHttp.post({ url: url, params });
|
||||
};
|
||||
/**
|
||||
* 删除监听
|
||||
* @param params
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.delete, data: params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 修改状态
|
||||
* @param params
|
||||
*/
|
||||
export const changeStatus = (params, handleSuccess) => {
|
||||
return defHttp.put({ url: Api.changeStatus, data: params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,164 @@
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'listenerName',
|
||||
width: 180,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '监听类型',
|
||||
dataIndex: 'listenerType',
|
||||
width: 100,
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDictNative(
|
||||
text,
|
||||
[
|
||||
{ label: '执行监听', value: 1 },
|
||||
{ label: '任务监听', value: 2 },
|
||||
],
|
||||
false
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '事件',
|
||||
dataIndex: 'listenerEvent',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '执行类型',
|
||||
dataIndex: 'listenerValueType',
|
||||
width: 150,
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDictNative(
|
||||
text,
|
||||
[
|
||||
{ label: '表达式', value: 'expression' },
|
||||
{ label: 'JAVA类', value: 'javaClass' },
|
||||
{ label: 'Spring表达式', value: 'delegateExpression' },
|
||||
],
|
||||
false
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '执行内容',
|
||||
dataIndex: 'listenerValue',
|
||||
width: 360,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'listenerStatus',
|
||||
width: 100,
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDictNative(
|
||||
text,
|
||||
[
|
||||
{ label: '已禁用', value: '0' },
|
||||
{ label: '已启用', value: '1' },
|
||||
],
|
||||
false
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
/**
|
||||
* 列表查询form
|
||||
*/
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'listenerName',
|
||||
label: '名称',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
];
|
||||
/**
|
||||
* 表单form
|
||||
*/
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'id',
|
||||
label: '',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '名称',
|
||||
field: 'listenerName',
|
||||
required: true,
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '监听类型',
|
||||
field: 'listenerType',
|
||||
component: 'Select',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
options: [
|
||||
{ label: '执行监听', value: 1 },
|
||||
{ label: '任务监听', value: 2 },
|
||||
],
|
||||
onChange: () => {
|
||||
formModel.listenerEvent = '';
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '事件属性',
|
||||
field: 'listenerEvent',
|
||||
component: 'Select',
|
||||
componentProps: ({ formModel }) => {
|
||||
const isExecute = [
|
||||
{ label: 'start', value: 'start' },
|
||||
{ label: 'end', value: 'end' },
|
||||
{ label: 'take', value: 'take' },
|
||||
];
|
||||
const isTask = [
|
||||
{ label: 'create', value: 'create' },
|
||||
{ label: 'assignment', value: 'assignment' },
|
||||
{ label: 'complete', value: 'complete' },
|
||||
];
|
||||
let option = !formModel['listenerType'] ? [] : formModel['listenerType'] == 1 ? isExecute : isTask;
|
||||
return {
|
||||
options: option,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '值类型',
|
||||
field: 'listenerValueType',
|
||||
component: 'RadioGroup',
|
||||
defaultValue: 'javaClass',
|
||||
componentProps: ({ formActionType }) => {
|
||||
return {
|
||||
options: [
|
||||
{ label: 'JAVA类', value: 'javaClass' },
|
||||
{ label: '表达式', value: 'expression' },
|
||||
{ label: '代理表达式', value: 'delegateExpression' },
|
||||
],
|
||||
onChange: (e) => {
|
||||
const { updateSchema } = formActionType;
|
||||
let value = e.target.value;
|
||||
const label = value === 'javaClass' ? '类路径' : '表达式';
|
||||
updateSchema([
|
||||
{
|
||||
field: 'listenerValue',
|
||||
label: label,
|
||||
},
|
||||
]);
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '类路径',
|
||||
field: 'listenerValue',
|
||||
component: 'Input',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--监听弹窗-->
|
||||
<ListenerModal @register="registerModal" @success="reload"></ListenerModal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" name="process-listener-list" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import ListenerModal from './components/ListenerModal.vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { columns, searchFormSchema } from './listener.data';
|
||||
import { list, deleteOne, changeStatus } from './listener.api';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
//弹窗
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
// 列表页面公共参数、方法
|
||||
const { prefixCls, tableContext } = useListPage({
|
||||
designScope: 'process-listener',
|
||||
tableProps: {
|
||||
title: '流程监听',
|
||||
api: list,
|
||||
columns: columns,
|
||||
formConfig: {
|
||||
labelWidth: 50,
|
||||
schemas: searchFormSchema,
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
function handleCreate() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
console.log('点击了编辑', record);
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除
|
||||
* @param id
|
||||
*/
|
||||
async function handleDelete(id) {
|
||||
console.log('点击了删除', id);
|
||||
await deleteOne({ id }, reload);
|
||||
}
|
||||
/**
|
||||
* 修改状态
|
||||
* @param id
|
||||
*/
|
||||
async function handleOpen(id) {
|
||||
console.log('点击了启用', id);
|
||||
await changeStatus({ id }, reload);
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '启用',
|
||||
popConfirm: {
|
||||
title: '是否启用?',
|
||||
confirm: handleOpen.bind(null, record.id),
|
||||
},
|
||||
ifShow: () => {
|
||||
return record.listenerStatus == 0;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '禁用',
|
||||
popConfirm: {
|
||||
title: '是否禁用?',
|
||||
confirm: handleOpen.bind(null, record.id),
|
||||
},
|
||||
ifShow: () => {
|
||||
return record.listenerStatus == 1;
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record.id),
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,61 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
list = '/act/processInstance/list',
|
||||
suspend = '/act/processInstance/suspend',
|
||||
restart = '/act/processInstance/restart',
|
||||
close = '/act/processInstance/close',
|
||||
taskEntrust = '/act/task/taskEntrust',
|
||||
taskComplaint = '/act/task/taskComplaint',
|
||||
}
|
||||
/**
|
||||
* 列表
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 激活
|
||||
* @param params
|
||||
*/
|
||||
export const restart = (params, handleSuccess) => {
|
||||
return defHttp.get({ url: Api.restart, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 挂起
|
||||
* @param params
|
||||
*/
|
||||
export const suspend = (params, handleSuccess) => {
|
||||
return defHttp.get({ url: Api.suspend, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 关闭
|
||||
* @param params
|
||||
*/
|
||||
export const closeProcess = (params, handleSuccess) => {
|
||||
return defHttp.get({ url: Api.close, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 委派
|
||||
* @param params
|
||||
*/
|
||||
export const taskEntrust = (params, handleSuccess) => {
|
||||
return defHttp.put({ url: Api.taskEntrust, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 转办
|
||||
* @param params
|
||||
*/
|
||||
export const taskComplaint = (params, handleSuccess) => {
|
||||
return defHttp.put({ url: Api.taskComplaint, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: '流程名称',
|
||||
dataIndex: 'prcocessDefinitionName',
|
||||
width: 180,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '业务标题',
|
||||
dataIndex: 'bpmBizTitle',
|
||||
},
|
||||
{
|
||||
title: '当前任务',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '流程实例',
|
||||
dataIndex: 'processInstanceId',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '办理人',
|
||||
dataIndex: 'assigneeName',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '流程ID',
|
||||
dataIndex: 'processDefinitionId',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '开始时间',
|
||||
dataIndex: 'startTime',
|
||||
},
|
||||
{
|
||||
title: '发起人',
|
||||
dataIndex: 'startUserName',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '耗时',
|
||||
dataIndex: 'spendTimes',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'isSuspended',
|
||||
width: 80,
|
||||
customRender: ({ text }) => {
|
||||
return text === 'true' ? '已暂停' : '已启动';
|
||||
},
|
||||
},
|
||||
];
|
||||
/**
|
||||
* 列表查询form
|
||||
*/
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'processInstanceId',
|
||||
label: '流程实例ID',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
field: 'startUserId',
|
||||
label: '流程发起人',
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps: {
|
||||
labelKey: 'realname',
|
||||
rowKey: 'username',
|
||||
showButton: false,
|
||||
maxSelectCount: 1,
|
||||
},
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--委派弹窗-->
|
||||
<DelegateModal @register="registerModal" @success="handleEntruster" title="请选择委派人"></DelegateModal>
|
||||
<!--转办弹窗-->
|
||||
<DelegateModal @register="registerModalComplaint" @success="handleComplaint" title="请选择转办人"></DelegateModal>
|
||||
<!--跳转弹窗-->
|
||||
<SelectTaskNodeModal @register="registerSkipModal" @success="reload"></SelectTaskNodeModal>
|
||||
<!--历史-->
|
||||
<HisTaskDealModal ref="taskDealRef" :path="path" :formData="formData"></HisTaskDealModal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" name="process-instance-list" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import DelegateModal from '../components/DelegateModal.vue';
|
||||
import SelectTaskNodeModal from '../components/SelectTaskNodeModal.vue';
|
||||
import HisTaskDealModal from '../components/HisTaskDealModal.vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { columns, searchFormSchema } from './instance.data';
|
||||
import { list, suspend, restart, closeProcess, taskEntrust, taskComplaint } from './instance.api';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { useBpmNodeInfo } from '../components/hooks/useBpmNodeInfo';
|
||||
//委派弹窗
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
//委派弹窗
|
||||
const [registerModalComplaint, { openModal: openModalComplaint }] = useModal();
|
||||
//跳转弹窗
|
||||
const [registerSkipModal, { openModal: openSkipModal }] = useModal();
|
||||
|
||||
// 列表页面公共参数、方法
|
||||
const { prefixCls, tableContext } = useListPage({
|
||||
designScope: 'process-expression',
|
||||
tableProps: {
|
||||
api: list,
|
||||
isTreeTable: true,
|
||||
rowKey: 'processInstanceId',
|
||||
columns: columns,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
const taskId = ref('');
|
||||
const path = ref('');
|
||||
const taskDealRef = ref(null);
|
||||
let { getHisProcessNodeInfo, formData } = useBpmNodeInfo(path, taskDealRef);
|
||||
/**
|
||||
* 激活
|
||||
* @param id
|
||||
*/
|
||||
async function handleRestart(id) {
|
||||
await restart({ processInstanceId: id }, reload);
|
||||
}
|
||||
/**
|
||||
* 挂起
|
||||
* @param id
|
||||
*/
|
||||
async function handleSuspend(id) {
|
||||
await suspend({ processInstanceId: id }, reload);
|
||||
}
|
||||
/**
|
||||
* 关闭
|
||||
* @param id
|
||||
*/
|
||||
async function handleClose(id) {
|
||||
await closeProcess({ processInstanceId: id }, reload);
|
||||
}
|
||||
/**
|
||||
* 选择委派人员弹窗
|
||||
* @param record
|
||||
*/
|
||||
function handleSelectEntruster(record) {
|
||||
taskId.value = record.taskId;
|
||||
openModal(true);
|
||||
}
|
||||
/**
|
||||
* 选择转办人员弹窗
|
||||
* @param record
|
||||
*/
|
||||
function handleSelectComplaint(record) {
|
||||
taskId.value = record.taskId;
|
||||
openModalComplaint(true);
|
||||
}
|
||||
/**
|
||||
* 跳转
|
||||
* @param taskId
|
||||
*/
|
||||
function handleSkipNode(taskId) {
|
||||
openSkipModal(true, { taskId });
|
||||
}
|
||||
/**
|
||||
* 显示历史
|
||||
* @param record
|
||||
*/
|
||||
function showHistory(record) {
|
||||
getHisProcessNodeInfo(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* 委派
|
||||
* @data
|
||||
*/
|
||||
async function handleEntruster(data) {
|
||||
console.log('handleEntruster委派返回值data:', data);
|
||||
let params = { taskId: unref(taskId), taskAssignee: data.username };
|
||||
await taskEntrust(params, reload);
|
||||
}
|
||||
/**
|
||||
* 转办
|
||||
* @data
|
||||
*/
|
||||
async function handleComplaint(data) {
|
||||
console.log('handleComplaint转办返回值data:', data);
|
||||
let params = { taskId: unref(taskId), taskAssignee: data.username };
|
||||
await taskComplaint(params, reload);
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '激活',
|
||||
popConfirm: {
|
||||
title: '是否激活?',
|
||||
confirm: handleRestart.bind(null, record.id),
|
||||
},
|
||||
ifShow: () => {
|
||||
return record.isSuspended != '' && record.isSuspended === 'true';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '挂起',
|
||||
popConfirm: {
|
||||
title: '是否挂起?',
|
||||
confirm: handleSuspend.bind(null, record.id),
|
||||
},
|
||||
ifShow: () => {
|
||||
return record.isSuspended != '' && record.isSuspended === 'false';
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '关闭',
|
||||
popConfirm: {
|
||||
title: '是否关闭吗?',
|
||||
confirm: handleClose.bind(null, record.id),
|
||||
},
|
||||
ifShow: () => {
|
||||
return record.isSuspended != '' && record.isSuspended != 'finished';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '转办',
|
||||
onClick: handleSelectComplaint.bind(null, record),
|
||||
ifShow: () => {
|
||||
return record.isSuspended != '' && record.isSuspended === 'false' && record.isSuspended != 'finished';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '委派',
|
||||
onClick: handleSelectEntruster.bind(null, record),
|
||||
ifShow: () => {
|
||||
return record.isSuspended != '' && record.isSuspended === 'false' && record.isSuspended != 'finished';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '跳转',
|
||||
onClick: handleSkipNode.bind(null, record.taskId),
|
||||
ifShow: () => {
|
||||
return record.isSuspended != '';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '历史',
|
||||
onClick: showHistory.bind(null, record),
|
||||
ifShow: () => {
|
||||
return record.isSuspended != '';
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user