You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

530 lines
22 KiB

<template>
<div style="height: 100%">
<q-splitter :model-value="100" unit="px" class="w-full" style="height: 100%">
<template #before>
<q-tabs v-model="selectedTabRef" vertical no-caps>
<q-tab name="processDefine" icon="bi-share" :label="$t('lcdp.bpm.tabs.processDefine')" />
<q-tab name="processInstance" icon="bi-sliders" :label="$t('lcdp.bpm.tabs.processInstance')" />
<q-tab name="task" icon="bi-receipt" :label="$t('lcdp.bpm.tabs.task')" />
<q-tab name="tools" icon="bi-wrench-adjustable" :label="$t('lcdp.bpm.tabs.tools')" />
</q-tabs>
</template>
<template #after>
<q-tab-panels v-model="selectedTabRef" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up" keep-alive style="height: 100%">
<q-tab-panel name="processDefine" class="pl-1 pr-0 pb-0" style="height: 100%">
<w-grid
ref="processDefineGridRef"
:title="$t('lcdp.bpm.processDefine.grid.title')"
:checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/flowable/process')"
:pageable="true"
:pagination="{ sortBy: 'lastModifyDate', descending: true }"
:query-form-cols-num="4"
:query-form-fields="[
{ name: 'key', label: $t('code'), type: 'w-text' },
{ name: 'name', label: $t('name'), type: 'w-text' },
{ name: 'status', label: $t('status'), queryOperator: 'equals', type: 'w-select', clearable: true, options: Options.enum(ProcessStatusEnum) },
]"
:toolbar-actions="[
'query',
'separator',
'refresh',
'separator',
'add',
'clone',
{
extend: 'edit',
enableIf: (arg) => {
if (arg.selected) {
if ('SKETCH' === arg.selected.status) {
return true;
}
}
return false;
},
},
{
extend: 'remove',
enableIf: (arg) => {
if (arg.selected) {
if ('SKETCH' === arg.selected.status) {
return true;
}
}
return false;
},
},
'separator',
{
name: 'design',
label: $t('lcdp.bpm.processDefine.grid.toolbar.design'),
icon: 'bi-brush',
enableIf: (arg) => {
if (arg.selected) {
if ('SKETCH' === arg.selected.status) {
return true;
}
}
return false;
},
click: (arg) => {
if (arg.selected) {
let title = $t('lcdp.bpm.designer.dialog.title.prefix');
title += ' - ' + arg.selected.name;
title += arg.selected.version ? ' (' + arg.selected.version + ')' : '';
processDesignerDialogRef.open(title, arg.selected.id);
}
},
},
{
name: 'deployment',
label: $t('lcdp.bpm.processDefine.grid.toolbar.deployment'),
icon: 'bi-arrow-up-circle',
enableIf: (arg) => {
if (arg.selected) {
if ('SKETCH' === arg.selected.status) {
return true;
}
}
return false;
},
click: (arg) => {
DialogManager.confirm($t('lcdp.bpm.processDefine.grid.toolbar.deployment.tip'), () => {
axios.post(Environment.apiContextPath('api/flowable/process/deploy/') + arg.selected.id).then(() => {
processDefineGridRef.refresh();
NotifyManager.success();
});
});
},
},
'separator',
{
name: 'createProcessInstance',
label: $t('lcdp.bpm.processDefine.grid.toolbar.createProcessInstance'),
icon: 'bi-file-plus',
enableIf: (arg) => {
if (arg.selected) {
if ('RELEASE' === arg.selected.status) {
return true;
}
}
return false;
},
click: (arg) => {
if (arg.selected) {
createProcessInstanceDialogRef.open(arg.selected.key, arg.selected.name);
}
},
},
{
name: 'queryProcessInstance',
label: $t('lcdp.bpm.processDefine.grid.toolbar.queryProcessInstance'),
icon: 'bi-list-ul',
enableIf: (arg) => {
if (arg.selected) {
if ('SKETCH' != arg.selected.status) {
return true;
}
}
return false;
},
click: (arg) => {
if (arg.selected) {
selectedTabRef = 'processInstance';
nextTick(() => {
processInstanceGridRef.getQueryForm().setFieldValue('deployedId', arg.selected.deployedId);
processInstanceGridRef.refresh();
});
}
},
},
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ width: 150, name: 'key', label: $t('code') },
{
width: '100%',
name: 'name',
label: $t('name'),
format: (value, row) => {
return Formater.dictionary(ProcessCategoryDictionaries)(row.key);
},
},
{ width: 60, name: 'version', label: $t('version') },
{ width: 60, name: 'status', label: $t('status'), format: Formater.enum(ProcessStatusEnum) },
{ width: 250, name: 'deployedId', label: $t('lcdp.bpm.processDefine.grid.entity.deployId') },
{
width: 90,
name: 'canClaimTask',
label: $t('lcdp.bpm.processDefine.grid.entity.canClaimTask'),
format: Formater.yesNo(),
},
{ width: 100, name: 'lastModifier', label: $t('lastModifier') },
{ width: 110, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
]"
:editor="{
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{
name: 'category',
label: $t('category'),
type: 'w-select',
defaultValue: 'SAMPLE',
options: Options.dictionary(ProcessCategoryDictionaries),
'onUpdate:modelValue': (value) => {
const form = processDefineGridRef.getEditorForm();
form.setFieldValue('key', value);
form.setFieldValue('name', Formater.dictionary(ProcessCategoryDictionaries)(value));
},
},
{
name: 'key',
label: $t('code'),
type: 'w-text',
defaultValue: 'SAMPLE',
readonlyIf: () => {
return true;
},
},
{
name: 'name',
label: $t('name'),
type: 'w-text',
requiredIf: true,
defaultValue: Formater.dictionary(ProcessCategoryDictionaries)('SAMPLE'),
readonlyIf: () => {
return true;
},
},
{ name: 'description', label: $t('description'), type: 'w-textarea', rows: 1 },
{ name: 'xml', label: $t('xml'), type: 'w-textarea' },
{ name: 'status', label: $t('status'), type: 'w-text', defaultValue: 'SKETCH', showIf: false },
{ name: 'canClaimTask', label: $t('lcdp.bpm.processDefine.grid.entity.canClaimTask'), type: 'w-checkbox', defaultValue: true, rule: [] },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t('id') },
{ name: 'category', label: $t('category') },
{ name: 'key', label: $t('code') },
{ name: 'name', label: $t('name'), format: Formater.none() },
{ name: 'description', label: $t('description') },
{ name: 'version', label: $t('version') },
{ name: 'status', label: $t('status'), format: Formater.enum(ProcessStatusEnum) },
{ name: 'deployedId', label: $t('lcdp.bpm.deployId') },
{ name: 'canClaimTask', label: $t('lcdp.bpm.processDefine.grid.entity.canClaimTask'), format: Formater.none() },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
],
},
}"
></w-grid>
</q-tab-panel>
<q-tab-panel name="processInstance" class="pl-1 pr-0 pb-0" style="height: 100%">
<w-grid
ref="processInstanceGridRef"
:title="$t('lcdp.bpm.processInstance.grid.title')"
:checkbox-selection="false"
:data-url="Environment.apiContextPath('/api/flowable/process/query/instance')"
:auto-fetch-data="false"
:pageable="true"
:pagination="{}"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'key', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionKey'), type: 'w-text' },
{ name: 'name', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionName'), type: 'w-text' },
{ name: 'deployedId', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionId'), type: 'w-text' },
]"
:toolbar-actions="[
'query',
'separator',
'refresh',
'separator',
{
name: 'queryTask',
label: $t('lcdp.bpm.processInstance.grid.toolbar.queryTask'),
icon: 'bi-list-ul',
enableIf: (arg) => {
return arg.selected;
},
click: (arg) => {
if (arg.selected) {
selectedTabRef = 'task';
nextTick(() => {
taskGridRef.getQueryForm().setFieldValue('processInstanceId', arg.selected.id);
taskGridRef.refresh();
});
}
},
},
{
name: 'variables',
label: $t('lcdp.bpm.task.grid.toolbar.variables'),
icon: 'bi-record',
enableIf: (arg) => {
return arg.selected;
},
click: (arg) => {
if (arg.selected) {
variableDialogRef.open(arg.selected.id);
}
},
},
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ name: 'processDefinitionKey', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionKey') },
{ name: 'processDefinitionName', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionName') },
{ name: 'id', label: $t('id'), showIf: false },
{ name: 'businessKey', label: $t('lcdp.bpm.processInstance.grid.entity.bussinessKey') },
{ name: 'startTime', label: $t('lcdp.bpm.processInstance.grid.entity.startTime') },
{ name: 'startUserId', label: $t('lcdp.bpm.processInstance.grid.entity.startUserId') },
{ name: 'suspended', label: $t('lcdp.bpm.processInstance.grid.entity.suspended') },
{ name: 'processDefinitionId', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionId'), showIf: false },
]"
:editor="{
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [],
},
}"
></w-grid>
</q-tab-panel>
<q-tab-panel name="task" class="pl-1 pr-0 pb-0" style="height: 100%">
<w-grid
ref="taskGridRef"
:title="$t('lcdp.bpm.task.grid.title')"
:checkbox-selection="false"
:data-url="Environment.apiContextPath('/api/flowable/process/query/task')"
:auto-fetch-data="false"
:pageable="true"
:pagination="{ sortBy: 'createTime', descending: true }"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'processInstanceId', label: $t('lcdp.bpm.task.grid.entity.processInstanceId'), type: 'w-text', queryOperator: 'equals' },
]"
:toolbar-actions="[
'query',
'separator',
'refresh',
'separator',
[
{
label: $t('operation'),
icon: 'bi-cursor',
},
{
name: 'complete',
label: $t('lcdp.bpm.task.grid.toolbar.complete'),
icon: 'bi-caret-right',
enableIf: function (arg) {
return arg.selected;
},
click: (arg) => {
if (arg.selected) {
completeTaskDialogRef.open(arg.selected.id);
}
},
},
{
name: 'claim',
label: $t('lcdp.bpm.task.grid.toolbar.claim'),
icon: 'bi-clipboard-check',
enableIf: function (selecteds) {
return selecteds && selecteds.length > 0 && !selecteds[0].assignee;
},
click: (arg) => {
if (arg.selected) {
DialogManager.confirm($t('lcdp.bpm.task.grid.toolbar.claim.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/process/operation/claim/') + arg.selected.id).then(() => {
taskGridRef.refresh();
NotifyManager.success();
});
});
}
},
},
{
name: 'unclaim',
label: $t('lcdp.bpm.task.grid.toolbar.unclaim'),
icon: 'bi-clipboard-x',
enableIf: function (arg) {
return arg.selected && arg.selected.assignee;
},
click: (arg) => {
if (arg.selected) {
DialogManager.confirm($t('lcdp.bpm.task.grid.toolbar.unclaim.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/process/operation/unClaim/') + arg.selected.id).then(() => {
taskGridRef.refresh();
NotifyManager.success();
});
});
}
},
},
{
name: 'jump',
label: $t('lcdp.bpm.task.grid.toolbar.jump'),
icon: 'bi-sign-turn-right',
enableIf: function (arg) {
return arg.selected;
},
click: (arg) => {
if (arg.selected) {
jumpTaskDialogRef.open(arg.selected.id);
}
},
},
{
name: 'terminate',
label: $t('lcdp.bpm.task.grid.toolbar.terminate'),
icon: 'bi-stop',
enableIf: function (arg) {
return arg.selected;
},
click: (arg) => {
if (arg.selected) {
DialogManager.confirm($t('lcdp.bpm.task.grid.toolbar.terminate.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/process/operation/terminateProcessInstance/') + arg.selected.id).then(() => {
taskGridRef.refresh();
NotifyManager.success();
});
});
}
},
},
],
{
name: 'variables',
label: $t('lcdp.bpm.task.grid.toolbar.variables'),
icon: 'bi-record',
enableIf: function (arg) {
return arg.selected;
},
click: (arg) => {
if (arg.selected) {
variableDialogRef.open(arg.selected.processInstanceId);
}
},
},
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ name: 'id', label: $t('id') },
{ name: 'name', label: $t('name') },
{ name: 'owner', label: $t('lcdp.bpm.task.grid.entity.owner') },
{ name: 'assignee', label: $t('lcdp.bpm.task.grid.entity.assignee') },
{ name: 'createTime', label: $t('lcdp.bpm.task.grid.entity.createTime') },
{ name: 'claimTime', label: $t('lcdp.bpm.task.grid.entity.claimTime') },
{ name: 'processInstanceId', label: $t('lcdp.bpm.task.grid.entity.processInstanceId') },
]"
:editor="{
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [],
},
}"
></w-grid>
</q-tab-panel>
<q-tab-panel name="tools" class="pl-1 pr-0 pb-0" style="height: 100%">
<div class="flex 'justify-center' gap-4">
<q-btn :label="$t('lcdp.bpm.tools.action.cleanRuntimeData')" color="primary" no-caps @click="cleanRuntimeData"></q-btn>
<q-btn :label="$t('lcdp.bpm.tools.action.cleanHistoryData')" color="primary" no-caps @click="cleanHistoryData"></q-btn>
</div>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
<ProcessDesigner ref="processDesignerDialogRef">
<iframe ref="processDesignerIframeRef" src="#" style="width: 100%; height: 100%"></iframe>
</ProcessDesigner>
<CreateProcessInstanceDialog ref="createProcessInstanceDialogRef"></CreateProcessInstanceDialog>
<VariableDialog ref="variableDialogRef"></VariableDialog>
<CompleteTaskDialog ref="completeTaskDialogRef" @after-task-completed="afterTaskCompleted"></CompleteTaskDialog>
<JumpTaskDialog ref="jumpTaskDialogRef"></JumpTaskDialog>
</div>
</template>
<script setup lang="ts">
import 'tailwindcss/utilities.css';
import { ref, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { Environment, DialogManager, NotifyManager, axios, EnumTools, DictionaryTools, Formater, Options } from 'platform-core';
import ProcessDesigner from './ProcessDesigner.vue';
import CreateProcessInstanceDialog from './CreateProcessInstanceDialog.vue';
import VariableDialog from './VariableDialog.vue';
import CompleteTaskDialog from './CompleteTaskDialog.vue';
import JumpTaskDialog from './JumpTaskDialog.vue';
const { t } = useI18n();
const selectedTabRef = ref('processDefine');
const processDefineGridRef = ref();
const processInstanceGridRef = ref();
const taskGridRef = ref();
const variableDialogRef = ref();
const completeTaskDialogRef = ref();
const jumpTaskDialogRef = ref();
const processDesignerDialogRef = ref();
const processDesignerIframeRef = ref();
const createProcessInstanceDialogRef = ref();
const afterTaskCompleted = () => {
NotifyManager.success();
taskGridRef.value.refresh();
};
const cleanRuntimeData = () => {
DialogManager.confirm(t('lcdp.bpm.tools.action.cleanRuntimeData.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/tools/cleanRuntimeData')).then(() => {
NotifyManager.success();
});
});
};
const cleanHistoryData = () => {
DialogManager.confirm(t('lcdp.bpm.tools.action.cleanHistoryData.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/tools/cleanHistoryData')).then(() => {
NotifyManager.success();
});
});
};
const ProcessStatusEnum = await EnumTools.fetch('io.sc.platform.flowable.enums.ProcessStatus');
const ProcessCategoryDictionaries = await DictionaryTools.fetch('WORK_FLOW');
</script>