mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-24 07:49:47 +08:00
feat-wip(projects): 对接流程定义功能ing
This commit is contained in:
@ -54,3 +54,11 @@ export function fetchActiveDefinition(id: CommonType.IdType, active: boolean) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 发布流程定义 */
|
||||||
|
export function fetchPublishDefinition(id: CommonType.IdType) {
|
||||||
|
return request<boolean>({
|
||||||
|
url: `/workflow/definition/publish/${id}`,
|
||||||
|
method: 'put'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
2
src/typings/api/workflow.api.d.ts
vendored
2
src/typings/api/workflow.api.d.ts
vendored
@ -90,6 +90,8 @@ declare namespace Api {
|
|||||||
flowName: string;
|
flowName: string;
|
||||||
/** 流程类别 */
|
/** 流程类别 */
|
||||||
category: string;
|
category: string;
|
||||||
|
/** 流程分类名称 */
|
||||||
|
categoryName: string;
|
||||||
/** 流程版本 */
|
/** 流程版本 */
|
||||||
version: string;
|
version: string;
|
||||||
/** 是否发布(0未发布 1已发布 9失效) */
|
/** 是否发布(0未发布 1已发布 9失效) */
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
import { NDivider, NSwitch, NTag } from 'naive-ui';
|
import { NDivider, NSwitch, NTag } from 'naive-ui';
|
||||||
import { useBoolean, useLoading } from '@sa/hooks';
|
import { useBoolean, useLoading } from '@sa/hooks';
|
||||||
|
import { type TableDataWithIndex } from '@sa/hooks';
|
||||||
import { workflowPublishStatusRecord } from '@/constants/workflow';
|
import { workflowPublishStatusRecord } from '@/constants/workflow';
|
||||||
import {
|
import {
|
||||||
fetchActiveDefinition,
|
fetchActiveDefinition,
|
||||||
fetchBatchDeleteDefinition,
|
fetchBatchDeleteDefinition,
|
||||||
fetchGetCategoryTree,
|
fetchGetCategoryTree,
|
||||||
fetchGetUnPublishDefinitionList
|
fetchGetDefinitionList,
|
||||||
|
fetchGetUnPublishDefinitionList,
|
||||||
|
fetchPublishDefinition
|
||||||
} from '@/service/api/workflow';
|
} from '@/service/api/workflow';
|
||||||
import { useAppStore } from '@/store/modules/app';
|
import { useAppStore } from '@/store/modules/app';
|
||||||
import { useAuth } from '@/hooks/business/auth';
|
import { useAuth } from '@/hooks/business/auth';
|
||||||
@ -23,12 +26,28 @@ defineOptions({
|
|||||||
name: 'DefinitionList'
|
name: 'DefinitionList'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interface IsPublishOption {
|
||||||
|
label: string;
|
||||||
|
value: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const { download } = useDownload();
|
const { download } = useDownload();
|
||||||
const { hasAuth } = useAuth();
|
const { hasAuth } = useAuth();
|
||||||
|
|
||||||
const { bool: importVisible, setTrue: showImportModal } = useBoolean();
|
const { bool: importVisible, setTrue: showImportModal } = useBoolean();
|
||||||
|
|
||||||
|
const isPublish = ref<boolean>(true);
|
||||||
|
const isPublishOptions = ref<IsPublishOption[]>([
|
||||||
|
{
|
||||||
|
label: '已发布',
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '未发布',
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
]);
|
||||||
const {
|
const {
|
||||||
columns,
|
columns,
|
||||||
columnChecks,
|
columnChecks,
|
||||||
@ -38,9 +57,10 @@ const {
|
|||||||
loading,
|
loading,
|
||||||
mobilePagination,
|
mobilePagination,
|
||||||
searchParams,
|
searchParams,
|
||||||
resetSearchParams
|
resetSearchParams,
|
||||||
|
updateApiFn
|
||||||
} = useTable({
|
} = useTable({
|
||||||
apiFn: fetchGetUnPublishDefinitionList,
|
apiFn: fetchGetDefinitionList,
|
||||||
apiParams: {
|
apiParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@ -70,7 +90,7 @@ const {
|
|||||||
minWidth: 120
|
minWidth: 120
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'category',
|
key: 'categoryName',
|
||||||
title: '流程分类',
|
title: '流程分类',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
minWidth: 120
|
minWidth: 120
|
||||||
@ -79,7 +99,10 @@ const {
|
|||||||
key: 'version',
|
key: 'version',
|
||||||
title: '版本号',
|
title: '版本号',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
minWidth: 120
|
minWidth: 120,
|
||||||
|
render(row) {
|
||||||
|
return <NTag type="info">v{row.version}.0</NTag>;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'activityStatus',
|
key: 'activityStatus',
|
||||||
@ -136,13 +159,11 @@ const {
|
|||||||
if (row.isPublish === null) {
|
if (row.isPublish === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tagMap: Record<Api.Workflow.WorkflowPublishStatus, NaiveUI.ThemeColor> = {
|
const tagMap: Record<Api.Workflow.WorkflowPublishStatus, NaiveUI.ThemeColor> = {
|
||||||
0: 'warning',
|
0: 'warning',
|
||||||
1: 'success',
|
1: 'success',
|
||||||
9: 'error'
|
9: 'error'
|
||||||
};
|
};
|
||||||
|
|
||||||
return <NTag type={tagMap[row.isPublish]}>{workflowPublishStatusRecord[row.isPublish]}</NTag>;
|
return <NTag type={tagMap[row.isPublish]}>{workflowPublishStatusRecord[row.isPublish]}</NTag>;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -150,51 +171,76 @@ const {
|
|||||||
key: 'operate',
|
key: 'operate',
|
||||||
title: $t('common.operate'),
|
title: $t('common.operate'),
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 130,
|
width: 150,
|
||||||
|
fixed: 'right',
|
||||||
render: row => {
|
render: row => {
|
||||||
const divider = () => {
|
const Divider = <NDivider vertical />;
|
||||||
if (!hasAuth('workflow:definition:edit') || !hasAuth('workflow:definition:remove')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return <NDivider vertical />;
|
|
||||||
};
|
|
||||||
|
|
||||||
const editBtn = () => {
|
const buttons = {
|
||||||
if (!hasAuth('workflow:definition:edit')) {
|
edit: (
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
text
|
text
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="material-symbols:drive-file-rename-outline-outline"
|
icon="material-symbols:drive-file-rename-outline-outline"
|
||||||
tooltipContent={$t('common.edit')}
|
tooltipContent={$t('common.edit')}
|
||||||
onClick={() => edit(row.id!)}
|
onClick={() => edit(row.id)}
|
||||||
/>
|
/>
|
||||||
);
|
),
|
||||||
};
|
delete: (
|
||||||
|
|
||||||
const deleteBtn = () => {
|
|
||||||
if (!hasAuth('workflow:definition:remove')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
text
|
text
|
||||||
type="error"
|
type="error"
|
||||||
icon="material-symbols:delete-outline"
|
icon="material-symbols:delete-outline"
|
||||||
tooltipContent={$t('common.delete')}
|
tooltipContent={$t('common.delete')}
|
||||||
popconfirmContent={$t('common.confirmDelete')}
|
popconfirmContent={$t('common.confirmDelete')}
|
||||||
onPositiveClick={() => handleDelete(row.id!)}
|
onPositiveClick={() => handleDelete(row.id)}
|
||||||
/>
|
/>
|
||||||
);
|
),
|
||||||
|
design: <ButtonIcon text type="primary" icon="material-symbols:design-services" tooltipContent="流程设计" />,
|
||||||
|
preview: (
|
||||||
|
<ButtonIcon text type="primary" icon="material-symbols:visibility-outline" tooltipContent="查看流程" />
|
||||||
|
),
|
||||||
|
publish: (
|
||||||
|
<ButtonIcon
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
icon="material-symbols:publish"
|
||||||
|
tooltipContent="发布流程"
|
||||||
|
onClick={() => handlePublish(row.id)}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
copy: <ButtonIcon text type="primary" icon="material-symbols:content-copy" tooltipContent="复制流程" />,
|
||||||
|
export: (
|
||||||
|
<ButtonIcon
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
icon="material-symbols:file-export"
|
||||||
|
tooltipContent="导出流程"
|
||||||
|
onClick={() => handleExport(row)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="flex-center gap-8px">
|
<div class="flex-col">
|
||||||
{editBtn()}
|
<div class="h-[24px] flex-center gap-4px">
|
||||||
{divider()}
|
{buttons.edit}
|
||||||
{deleteBtn()}
|
{Divider}
|
||||||
|
{buttons.delete}
|
||||||
|
{Divider}
|
||||||
|
{buttons.copy}
|
||||||
|
</div>
|
||||||
|
<div class="h-[24px] flex-center gap-4px">
|
||||||
|
{buttons.export}
|
||||||
|
{Divider}
|
||||||
|
{isPublish.value ? buttons.preview : buttons.design}
|
||||||
|
{!isPublish.value && (
|
||||||
|
<>
|
||||||
|
{Divider}
|
||||||
|
{buttons.publish}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -202,6 +248,13 @@ const {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 监听运行状态变化
|
||||||
|
watch(isPublish, async () => {
|
||||||
|
const newApiFn = isPublish.value ? fetchGetDefinitionList : fetchGetUnPublishDefinitionList;
|
||||||
|
updateApiFn(newApiFn);
|
||||||
|
await getDataByPage();
|
||||||
|
});
|
||||||
|
|
||||||
const { drawerVisible, operateType, editingData, handleAdd, handleEdit, checkedRowKeys, onBatchDeleted, onDeleted } =
|
const { drawerVisible, operateType, editingData, handleAdd, handleEdit, checkedRowKeys, onBatchDeleted, onDeleted } =
|
||||||
useTableOperate(data, getData);
|
useTableOperate(data, getData);
|
||||||
|
|
||||||
@ -223,14 +276,20 @@ function edit(id: CommonType.IdType) {
|
|||||||
handleEdit('id', id);
|
handleEdit('id', id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleExport() {
|
|
||||||
download('/workflow/definition/export', searchParams, `流程定义_${new Date().getTime()}.xlsx`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleDeploy() {
|
function handleDeploy() {
|
||||||
showImportModal();
|
showImportModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handlePublish(id: CommonType.IdType) {
|
||||||
|
const { error } = await fetchPublishDefinition(id);
|
||||||
|
if (error) return;
|
||||||
|
window.$message?.success('发布成功');
|
||||||
|
getDataByPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleExport(row: TableDataWithIndex<Api.Workflow.Definition>) {
|
||||||
|
download(`/workflow/definition/exportDef/${row.id}`, {}, `${row.flowCode}.json`);
|
||||||
|
}
|
||||||
const { loading: categoryLoading, startLoading: startCategoryLoading, endLoading: endCategoryLoading } = useLoading();
|
const { loading: categoryLoading, startLoading: startCategoryLoading, endLoading: endCategoryLoading } = useLoading();
|
||||||
const categoryPattern = ref<string>();
|
const categoryPattern = ref<string>();
|
||||||
const categoryData = ref<Api.Common.CommonTreeRecord>([]);
|
const categoryData = ref<Api.Common.CommonTreeRecord>([]);
|
||||||
@ -300,18 +359,27 @@ const selectable = computed(() => {
|
|||||||
</template>
|
</template>
|
||||||
<div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
|
<div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
|
||||||
<DefinitionSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
<DefinitionSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||||
<NCard title="流程定义列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
<NCard :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||||
|
<template #header>
|
||||||
|
<NSpace>
|
||||||
|
<NRadioGroup v-model:value="isPublish" on-up size="small">
|
||||||
|
<NRadioButton
|
||||||
|
v-for="(status, index) in isPublishOptions"
|
||||||
|
:key="index"
|
||||||
|
:value="status.value"
|
||||||
|
:label="status.label"
|
||||||
|
/>
|
||||||
|
</NRadioGroup>
|
||||||
|
</NSpace>
|
||||||
|
</template>
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<TableHeaderOperation
|
<TableHeaderOperation
|
||||||
v-model:columns="columnChecks"
|
v-model:columns="columnChecks"
|
||||||
:disabled-delete="checkedRowKeys.length === 0"
|
:disabled-delete="checkedRowKeys.length === 0"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:show-add="hasAuth('workflow:definition:add')"
|
|
||||||
:show-delete="hasAuth('workflow:definition:remove')"
|
:show-delete="hasAuth('workflow:definition:remove')"
|
||||||
:show-export="hasAuth('workflow:definition:export')"
|
|
||||||
@add="handleAdd"
|
@add="handleAdd"
|
||||||
@delete="handleBatchDelete"
|
@delete="handleBatchDelete"
|
||||||
@export="handleExport"
|
|
||||||
@refresh="getData"
|
@refresh="getData"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
|
@ -151,13 +151,12 @@ const operateColumns = ref<NaiveUI.TableColumn<Api.Workflow.ProcessInstance>[]>(
|
|||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
width: 155,
|
width: 155,
|
||||||
render: row => {
|
render: row => {
|
||||||
const showAll = runningStatus.value;
|
|
||||||
const id = row.id;
|
const id = row.id;
|
||||||
return (
|
const showAll = runningStatus.value;
|
||||||
<div class="flex-center gap-1px">
|
const Divider = <NDivider vertical />;
|
||||||
{showAll && [
|
|
||||||
|
const cancelBtn = (
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
key="cancel"
|
|
||||||
text
|
text
|
||||||
type="error"
|
type="error"
|
||||||
showPopconfirmIcon={false}
|
showPopconfirmIcon={false}
|
||||||
@ -167,29 +166,43 @@ const operateColumns = ref<NaiveUI.TableColumn<Api.Workflow.ProcessInstance>[]>(
|
|||||||
<NInput v-model:value={cancelModel.comment} size="large" type="textarea" placeholder="请输入作废原因" />
|
<NInput v-model:value={cancelModel.comment} size="large" type="textarea" placeholder="请输入作废原因" />
|
||||||
}
|
}
|
||||||
onPositiveClick={() => handleCancel(id)}
|
onPositiveClick={() => handleCancel(id)}
|
||||||
/>,
|
/>
|
||||||
<NDivider key="div1" vertical />,
|
);
|
||||||
|
|
||||||
|
const deleteBtn = (
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
key="delete"
|
|
||||||
text
|
text
|
||||||
type="error"
|
type="error"
|
||||||
icon="material-symbols:delete-outline"
|
icon="material-symbols:delete-outline"
|
||||||
tooltipContent={$t('common.delete')}
|
tooltipContent={$t('common.delete')}
|
||||||
popconfirmContent={$t('common.confirmDelete')}
|
popconfirmContent={$t('common.confirmDelete')}
|
||||||
onPositiveClick={() => handleDelete(id)}
|
onPositiveClick={() => handleDelete(id)}
|
||||||
/>,
|
/>
|
||||||
<NDivider key="div2" vertical />
|
);
|
||||||
]}
|
|
||||||
|
const previewBtn = (
|
||||||
<ButtonIcon text type="info" icon="material-symbols:visibility-outline" tooltipContent="流程预览" />
|
<ButtonIcon text type="info" icon="material-symbols:visibility-outline" tooltipContent="流程预览" />
|
||||||
<NDivider vertical />
|
);
|
||||||
|
|
||||||
|
const variableBtn = (
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
key=""
|
|
||||||
text
|
text
|
||||||
type="info"
|
type="info"
|
||||||
icon="material-symbols:variable-insert"
|
icon="material-symbols:variable-insert"
|
||||||
tooltipContent="流程变量"
|
tooltipContent="流程变量"
|
||||||
onClick={() => handleShowVariable(id)}
|
onClick={() => handleShowVariable(id)}
|
||||||
/>
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="flex-center gap-1px">
|
||||||
|
{showAll && cancelBtn}
|
||||||
|
{showAll && Divider}
|
||||||
|
{showAll && deleteBtn}
|
||||||
|
{showAll && Divider}
|
||||||
|
{previewBtn}
|
||||||
|
{Divider}
|
||||||
|
{variableBtn}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user