refactor:【BPM 工作流】 针对TODO 更新流程相关接口和组件,优化文档提示,调整表单字段类型
parent
7a54f7767a
commit
a4839416fe
|
@ -4,6 +4,7 @@ import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
/** 流程定义 */
|
/** 流程定义 */
|
||||||
export namespace BpmProcessDefinitionApi {
|
export namespace BpmProcessDefinitionApi {
|
||||||
|
// 流程定义
|
||||||
export interface ProcessDefinitionVO {
|
export interface ProcessDefinitionVO {
|
||||||
id: string;
|
id: string;
|
||||||
version: number;
|
version: number;
|
||||||
|
|
|
@ -3,7 +3,7 @@ import type { PageParam, PageResult } from '@vben/request';
|
||||||
import { requestClient } from '#/api/request';
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
export namespace BpmFormApi {
|
export namespace BpmFormApi {
|
||||||
// TODO @siye:注释加一个。。嘿嘿
|
// 流程表单
|
||||||
export interface FormVO {
|
export interface FormVO {
|
||||||
id?: number | undefined;
|
id?: number | undefined;
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -11,7 +11,7 @@ export namespace BpmFormApi {
|
||||||
fields: string[];
|
fields: string[];
|
||||||
status: number;
|
status: number;
|
||||||
remark: string;
|
remark: string;
|
||||||
createTime: string;
|
createTime: number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ export async function getFormPage(params: PageParam) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取表单详情 */
|
/** 获取表单详情 */
|
||||||
export async function getFormDetail(id: number) {
|
export async function getFormDetail(id: number | string) {
|
||||||
return requestClient.get<BpmFormApi.FormVO>(`/bpm/form/get?id=${id}`);
|
return requestClient.get<BpmFormApi.FormVO>(`/bpm/form/get?id=${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ export namespace BpmProcessInstanceApi {
|
||||||
tasks: ApprovalTaskInfo[];
|
tasks: ApprovalTaskInfo[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 流程实例
|
||||||
export type ProcessInstanceVO = {
|
export type ProcessInstanceVO = {
|
||||||
businessKey: string;
|
businessKey: string;
|
||||||
category: string;
|
category: string;
|
||||||
|
@ -59,6 +60,7 @@ export namespace BpmProcessInstanceApi {
|
||||||
tasks?: BpmProcessInstanceApi.Task[];
|
tasks?: BpmProcessInstanceApi.Task[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 审批详情
|
||||||
export type ApprovalDetail = {
|
export type ApprovalDetail = {
|
||||||
activityNodes: BpmProcessInstanceApi.ApprovalNodeInfo[];
|
activityNodes: BpmProcessInstanceApi.ApprovalNodeInfo[];
|
||||||
formFieldsPermission: any;
|
formFieldsPermission: any;
|
||||||
|
@ -66,6 +68,25 @@ export namespace BpmProcessInstanceApi {
|
||||||
processInstance: BpmProcessInstanceApi.ProcessInstanceVO;
|
processInstance: BpmProcessInstanceApi.ProcessInstanceVO;
|
||||||
status: number;
|
status: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 抄送流程实例 VO
|
||||||
|
export type CopyVO = {
|
||||||
|
id: number;
|
||||||
|
startUser: User;
|
||||||
|
processInstanceId: string;
|
||||||
|
processInstanceName: string;
|
||||||
|
processInstanceStartTime: number;
|
||||||
|
activityId: string;
|
||||||
|
activityName: string;
|
||||||
|
taskId: string;
|
||||||
|
reason: string;
|
||||||
|
createUser: User;
|
||||||
|
createTime: number;
|
||||||
|
summary: {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询我的流程实例分页 */
|
/** 查询我的流程实例分页 */
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import type { PageParam, PageResult } from '@vben/request';
|
import type { PageParam, PageResult } from '@vben/request';
|
||||||
|
|
||||||
|
import type { BpmProcessInstanceApi } from '../processInstance';
|
||||||
|
|
||||||
import { requestClient } from '#/api/request';
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
export namespace BpmTaskApi {
|
export namespace BpmTaskApi {
|
||||||
|
@ -11,7 +13,33 @@ export namespace BpmTaskApi {
|
||||||
status: number; // 监听器状态
|
status: number; // 监听器状态
|
||||||
event: string; // 监听事件
|
event: string; // 监听事件
|
||||||
valueType: string; // 监听器值类型
|
valueType: string; // 监听器值类型
|
||||||
value: string; // 监听器值
|
}
|
||||||
|
|
||||||
|
// 流程任务 VO
|
||||||
|
export interface TaskManagerVO {
|
||||||
|
id: string; // 编号
|
||||||
|
name: string; // 任务名称
|
||||||
|
createTime: number; // 创建时间
|
||||||
|
endTime: number; // 结束时间
|
||||||
|
durationInMillis: number; // 持续时间
|
||||||
|
status: number; // 状态
|
||||||
|
reason: string; // 原因
|
||||||
|
ownerUser: any; // 负责人
|
||||||
|
assigneeUser: any; // 处理人
|
||||||
|
taskDefinitionKey: string; // 任务定义key
|
||||||
|
processInstanceId: string; // 流程实例id
|
||||||
|
processInstance: BpmProcessInstanceApi.ProcessInstanceVO; // 流程实例
|
||||||
|
parentTaskId: any; // 父任务id
|
||||||
|
children: any; // 子任务
|
||||||
|
formId: any; // 表单id
|
||||||
|
formName: any; // 表单名称
|
||||||
|
formConf: any; // 表单配置
|
||||||
|
formFields: any; // 表单字段
|
||||||
|
formVariables: any; // 表单变量
|
||||||
|
buttonsSetting: any; // 按钮设置
|
||||||
|
signEnable: any; // 签名设置
|
||||||
|
reasonRequire: any; // 原因设置
|
||||||
|
nodeType: any; // 节点类型
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: '/bpm/manager/form/edit',
|
path: '/bpm/manager/form/edit',
|
||||||
name: 'BpmFormEditor',
|
name: 'BpmFormEditor',
|
||||||
component: () => import('#/views/bpm/form/editor.vue'),
|
component: () => import('#/views/bpm/form/designer/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '编辑流程表单',
|
title: '编辑流程表单',
|
||||||
activePath: '/bpm/manager/form',
|
activePath: '/bpm/manager/form',
|
||||||
|
|
|
@ -34,7 +34,7 @@ export const decodeFields = (fields: string[]) => {
|
||||||
export const setConfAndFields = (
|
export const setConfAndFields = (
|
||||||
designerRef: object,
|
designerRef: object,
|
||||||
conf: string,
|
conf: string,
|
||||||
fields: string,
|
fields: string | string[],
|
||||||
) => {
|
) => {
|
||||||
// @ts-ignore designerRef.value is dynamically added by form-create-designer
|
// @ts-ignore designerRef.value is dynamically added by form-create-designer
|
||||||
designerRef.value.setOption(JSON.parse(conf));
|
designerRef.value.setOption(JSON.parse(conf));
|
||||||
|
|
|
@ -6,11 +6,13 @@ import type {
|
||||||
import type { BpmCategoryApi } from '#/api/bpm/category';
|
import type { BpmCategoryApi } from '#/api/bpm/category';
|
||||||
|
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
import { Plus } from '@vben/icons';
|
||||||
|
|
||||||
import { Button, message } from 'ant-design-vue';
|
import { Button, message } from 'ant-design-vue';
|
||||||
|
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteCategory, getCategoryPage } from '#/api/bpm/category';
|
import { deleteCategory, getCategoryPage } from '#/api/bpm/category';
|
||||||
|
import { DocAlert } from '#/components/doc-alert';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
@ -100,6 +102,10 @@ async function onDelete(row: BpmCategoryApi.CategoryVO) {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
|
<template #doc>
|
||||||
|
<DocAlert title="工作流手册" url="https://doc.iocoder.cn/bpm/" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<FormModal @success="onRefresh" />
|
<FormModal @success="onRefresh" />
|
||||||
<Grid table-title="流程分类">
|
<Grid table-title="流程分类">
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// TODO @siye:editor 要不要放到独立的目录?form/designer ?
|
|
||||||
import { computed, onMounted, ref } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
@ -12,19 +11,15 @@ import { getFormDetail } from '#/api/bpm/form';
|
||||||
import { useFormCreateDesigner } from '#/components/form-create';
|
import { useFormCreateDesigner } from '#/components/form-create';
|
||||||
import { router } from '#/router';
|
import { router } from '#/router';
|
||||||
import { setConfAndFields } from '#/utils';
|
import { setConfAndFields } from '#/utils';
|
||||||
|
import Form from '#/views/bpm/form/modules/form.vue';
|
||||||
import Form from './modules/form.vue';
|
|
||||||
|
|
||||||
defineOptions({ name: 'BpmFormEditor' });
|
defineOptions({ name: 'BpmFormEditor' });
|
||||||
|
|
||||||
// TODO @siye:这里有 lint 告警
|
const props = defineProps<{
|
||||||
const props = defineProps<Props>();
|
copyId?: number | string;
|
||||||
|
|
||||||
interface Props {
|
|
||||||
copyId?: number;
|
|
||||||
id?: number;
|
id?: number;
|
||||||
type: 'copy' | 'create' | 'edit';
|
type: 'copy' | 'create' | 'edit';
|
||||||
}
|
}>();
|
||||||
|
|
||||||
// 流程表单详情
|
// 流程表单详情
|
||||||
const flowFormConfig = ref();
|
const flowFormConfig = ref();
|
||||||
|
@ -85,7 +80,7 @@ const currentFormId = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// 加载表单配置
|
// 加载表单配置
|
||||||
async function loadFormConfig(id: number) {
|
async function loadFormConfig(id: number | string) {
|
||||||
try {
|
try {
|
||||||
const formDetail = await getFormDetail(id);
|
const formDetail = await getFormDetail(id);
|
||||||
flowFormConfig.value = formDetail;
|
flowFormConfig.value = formDetail;
|
||||||
|
@ -107,10 +102,11 @@ async function initializeDesigner() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id) {
|
if (id) {
|
||||||
await loadFormConfig(id);
|
await loadFormConfig(Number(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 保存表单
|
||||||
function handleSave() {
|
function handleSave() {
|
||||||
formModalApi
|
formModalApi
|
||||||
.setData({
|
.setData({
|
||||||
|
@ -121,7 +117,7 @@ function handleSave() {
|
||||||
.open();
|
.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @siye:一些必要的注释,稍微写写哈。保持风格的一致性;
|
// 返回列表页
|
||||||
function onBack() {
|
function onBack() {
|
||||||
router.push({
|
router.push({
|
||||||
path: '/bpm/manager/form',
|
path: '/bpm/manager/form',
|
|
@ -12,6 +12,7 @@ import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
import { Plus } from '@vben/icons';
|
import { Plus } from '@vben/icons';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
|
import FormCreate from '@form-create/ant-design-vue';
|
||||||
import { Button, message } from 'ant-design-vue';
|
import { Button, message } from 'ant-design-vue';
|
||||||
|
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
|
@ -119,7 +120,6 @@ async function onDetail(row: BpmFormApi.FormVO) {
|
||||||
|
|
||||||
/** 编辑 */
|
/** 编辑 */
|
||||||
function onEdit(row: BpmFormApi.FormVO) {
|
function onEdit(row: BpmFormApi.FormVO) {
|
||||||
console.warn(row);
|
|
||||||
router.push({
|
router.push({
|
||||||
name: 'BpmFormEditor',
|
name: 'BpmFormEditor',
|
||||||
query: {
|
query: {
|
||||||
|
@ -165,11 +165,12 @@ watch(
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<DocAlert
|
<template #doc>
|
||||||
title="审批接入(流程表单)"
|
<DocAlert
|
||||||
url="https://doc.iocoder.cn/bpm/use-bpm-form/"
|
title="审批接入(流程表单)"
|
||||||
/>
|
url="https://doc.iocoder.cn/bpm/use-bpm-form/"
|
||||||
<FormModal @success="onRefresh" />
|
/>
|
||||||
|
</template>
|
||||||
<Grid table-title="流程表单">
|
<Grid table-title="流程表单">
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
<Button type="primary" @click="onCreate">
|
<Button type="primary" @click="onCreate">
|
||||||
|
@ -177,28 +178,6 @@ watch(
|
||||||
{{ $t('ui.actionTitle.create', ['流程表单']) }}
|
{{ $t('ui.actionTitle.create', ['流程表单']) }}
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 摘要 -->
|
|
||||||
<!-- TODO @siye:这个是不是不应该有呀? -->
|
|
||||||
<template #slot-summary="{ row }">
|
|
||||||
<div
|
|
||||||
class="flex flex-col py-2"
|
|
||||||
v-if="
|
|
||||||
row.processInstance.summary &&
|
|
||||||
row.processInstance.summary.length > 0
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in row.processInstance.summary"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<span class="text-gray-500">
|
|
||||||
{{ item.key }} : {{ item.value }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else>-</div>
|
|
||||||
</template>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<DetailModal
|
<DetailModal
|
||||||
|
@ -209,7 +188,7 @@ watch(
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="mx-4">
|
<div class="mx-4">
|
||||||
<form-create :option="formConfig.option" :rule="formConfig.rule" />
|
<FormCreate :option="formConfig.option" :rule="formConfig.rule" />
|
||||||
</div>
|
</div>
|
||||||
</DetailModal>
|
</DetailModal>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
|
@ -39,28 +39,29 @@ const [Form, formApi] = useVbenForm({
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
async onConfirm() {
|
async onConfirm() {
|
||||||
// TODO @siye:建议和别的模块,也稍微加点类似的注释哈。= = 阅读总是会有点层次感;
|
// 表单验证
|
||||||
const { valid } = await formApi.validate();
|
const { valid } = await formApi.validate();
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
|
|
||||||
|
// 锁定模态框
|
||||||
modalApi.lock();
|
modalApi.lock();
|
||||||
try {
|
try {
|
||||||
|
// 获取表单数据
|
||||||
const data = (await formApi.getValues()) as BpmFormApi.FormVO;
|
const data = (await formApi.getValues()) as BpmFormApi.FormVO;
|
||||||
|
|
||||||
|
// 编码表单配置和表单字段
|
||||||
data.conf = encodeConf(designerComponent);
|
data.conf = encodeConf(designerComponent);
|
||||||
data.fields = encodeFields(designerComponent);
|
data.fields = encodeFields(designerComponent);
|
||||||
|
|
||||||
// TODO @siye:这个是不是不用抽方法呀,直接写逻辑就完事啦。
|
// 保存表单数据
|
||||||
const saveForm = async () => {
|
if (formData.value?.id) {
|
||||||
if (!formData.value?.id) {
|
await (editorAction.value === 'copy'
|
||||||
return createForm(data);
|
|
||||||
}
|
|
||||||
return editorAction.value === 'copy'
|
|
||||||
? createForm(data)
|
? createForm(data)
|
||||||
: updateForm(data);
|
: updateForm(data));
|
||||||
};
|
} else {
|
||||||
|
await createForm(data);
|
||||||
|
}
|
||||||
|
|
||||||
await saveForm();
|
|
||||||
await modalApi.close();
|
await modalApi.close();
|
||||||
emit('success');
|
emit('success');
|
||||||
message.success($t('ui.actionMessage.operationSuccess'));
|
message.success($t('ui.actionMessage.operationSuccess'));
|
||||||
|
@ -76,14 +77,15 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @siye:建议和别的模块,也稍微加点类似的注释哈。= = 阅读总是会有点层次感;
|
|
||||||
const data = modalApi.getData<any>();
|
const data = modalApi.getData<any>();
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
|
// 设置表单设计器组件
|
||||||
designerComponent.value = data.designer;
|
designerComponent.value = data.designer;
|
||||||
formData.value = data.formConfig;
|
formData.value = data.formConfig;
|
||||||
editorAction.value = data.action;
|
editorAction.value = data.action;
|
||||||
|
|
||||||
|
// 如果是复制,表单名称后缀添加 _copy ,id 置空
|
||||||
if (editorAction.value === 'copy' && formData.value) {
|
if (editorAction.value === 'copy' && formData.value) {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
...formData.value,
|
...formData.value,
|
||||||
|
|
|
@ -101,6 +101,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
/** 列表的字段 */
|
/** 列表的字段 */
|
||||||
export function useGridColumns<T = BpmCategoryApi.CategoryVO>(
|
export function useGridColumns<T = BpmCategoryApi.CategoryVO>(
|
||||||
onActionClick: OnActionClickFn<T>,
|
onActionClick: OnActionClickFn<T>,
|
||||||
|
getMemberNames: (userIds: number[]) => string,
|
||||||
): VxeTableGridOptions['columns'] {
|
): VxeTableGridOptions['columns'] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
@ -122,8 +123,8 @@ export function useGridColumns<T = BpmCategoryApi.CategoryVO>(
|
||||||
field: 'userIds',
|
field: 'userIds',
|
||||||
title: '成员',
|
title: '成员',
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
slots: {
|
formatter: (row) => {
|
||||||
default: 'userIds-cell',
|
return getMemberNames(row.cellValue);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { Button, message } from 'ant-design-vue';
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteUserGroup, getUserGroupPage } from '#/api/bpm/userGroup';
|
import { deleteUserGroup, getUserGroupPage } from '#/api/bpm/userGroup';
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
import { getSimpleUserList } from '#/api/system/user';
|
||||||
|
import { DocAlert } from '#/components/doc-alert';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
@ -30,7 +31,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
schema: useGridFormSchema(),
|
schema: useGridFormSchema(),
|
||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useGridColumns(onActionClick),
|
columns: useGridColumns(onActionClick, getMemberNames),
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
|
@ -42,21 +43,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
...formValues,
|
...formValues,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
querySuccess: (params) => {
|
|
||||||
// TODO @siye:getLeaderName?: (userId: number) => string | undefined, 参考这个哈。
|
|
||||||
const { list } = params.response;
|
|
||||||
const userMap = new Map(
|
|
||||||
userList.value.map((user) => [user.id, user.nickname]),
|
|
||||||
);
|
|
||||||
list.forEach(
|
|
||||||
(item: BpmUserGroupApi.UserGroupVO & { nicknames?: string }) => {
|
|
||||||
item.nicknames = item.userIds
|
|
||||||
.map((userId) => userMap.get(userId))
|
|
||||||
.filter(Boolean)
|
|
||||||
.join('、');
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
rowConfig: {
|
rowConfig: {
|
||||||
|
@ -69,6 +55,17 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
} as VxeTableGridOptions<BpmUserGroupApi.UserGroupVO>,
|
} as VxeTableGridOptions<BpmUserGroupApi.UserGroupVO>,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** 获取分组成员姓名 */
|
||||||
|
function getMemberNames(userIds: number[]) {
|
||||||
|
const userMap = new Map(
|
||||||
|
userList.value.map((user) => [user.id, user.nickname]),
|
||||||
|
);
|
||||||
|
return userIds
|
||||||
|
.map((userId) => userMap.get(userId))
|
||||||
|
.filter(Boolean)
|
||||||
|
.join('、');
|
||||||
|
}
|
||||||
|
|
||||||
/** 表格操作按钮的回调函数 */
|
/** 表格操作按钮的回调函数 */
|
||||||
function onActionClick({
|
function onActionClick({
|
||||||
code,
|
code,
|
||||||
|
@ -128,6 +125,10 @@ onMounted(async () => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
|
<template #doc>
|
||||||
|
<DocAlert title="工作流手册" url="https://doc.iocoder.cn/bpm/" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<FormModal @success="onRefresh" />
|
<FormModal @success="onRefresh" />
|
||||||
<Grid table-title="用户分组">
|
<Grid table-title="用户分组">
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
|
|
|
@ -106,8 +106,12 @@ async function onDelete(row: BpmProcessExpressionApi.ProcessExpressionVO) {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<DocAlert title="流程表达式" url="https://doc.iocoder.cn/bpm/expression/" />
|
<template #doc>
|
||||||
|
<DocAlert
|
||||||
|
title="流程表达式"
|
||||||
|
url="https://doc.iocoder.cn/bpm/expression/"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<FormModal @success="onRefresh" />
|
<FormModal @success="onRefresh" />
|
||||||
<Grid table-title="流程表达式">
|
<Grid table-title="流程表达式">
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
|
|
|
@ -125,7 +125,9 @@ function onRefresh() {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<DocAlert title="工作流手册" url="https://doc.iocoder.cn/bpm" />
|
<template #doc>
|
||||||
|
<DocAlert title="工作流手册" url="https://doc.iocoder.cn/bpm" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<FormModal @success="onRefresh" />
|
<FormModal @success="onRefresh" />
|
||||||
<Grid table-title="流程实例" />
|
<Grid table-title="流程实例" />
|
||||||
|
|
|
@ -108,10 +108,12 @@ async function onDelete(row: BpmProcessListenerApi.ProcessListenerVO) {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<DocAlert
|
<template #doc>
|
||||||
title="执行监听器、任务监听器"
|
<DocAlert
|
||||||
url="https://doc.iocoder.cn/bpm/listener/"
|
title="执行监听器、任务监听器"
|
||||||
/>
|
url="https://doc.iocoder.cn/bpm/listener/"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<FormModal @success="onRefresh" />
|
<FormModal @success="onRefresh" />
|
||||||
<Grid table-title="流程监听器">
|
<Grid table-title="流程监听器">
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
|
|
|
@ -61,9 +61,8 @@ function onActionClick({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 办理任务 */
|
/** 任务详情 */
|
||||||
function onDetail(row: BpmProcessInstanceApi.ProcessInstanceVO) {
|
function onDetail(row: BpmProcessInstanceApi.CopyVO) {
|
||||||
// TODO @siye:row 的类型是不是不对哈?需要改成 copyvo 么?
|
|
||||||
const query = {
|
const query = {
|
||||||
id: row.processInstanceId,
|
id: row.processInstanceId,
|
||||||
...(row.activityId && { activityId: row.activityId }),
|
...(row.activityId && { activityId: row.activityId }),
|
||||||
|
@ -82,11 +81,12 @@ function onRefresh() {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<!-- TODO @siye:应该用 <template #doc>,这样高度可以被用进去哈 -->
|
<template #doc>
|
||||||
<DocAlert
|
<DocAlert
|
||||||
title="审批转办、委派、抄送"
|
title="审批转办、委派、抄送"
|
||||||
url="https://doc.iocoder.cn/bpm/task-delegation-and-cc/"
|
url="https://doc.iocoder.cn/bpm/task-delegation-and-cc/"
|
||||||
/>
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
<FormModal @success="onRefresh" />
|
<FormModal @success="onRefresh" />
|
||||||
<Grid table-title="抄送任务">
|
<Grid table-title="抄送任务">
|
||||||
|
|
|
@ -2,8 +2,6 @@ import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { BpmTaskApi } from '#/api/bpm/task';
|
import type { BpmTaskApi } from '#/api/bpm/task';
|
||||||
|
|
||||||
import { useAccess } from '@vben/access';
|
|
||||||
|
|
||||||
import { getCategorySimpleList } from '#/api/bpm/category';
|
import { getCategorySimpleList } from '#/api/bpm/category';
|
||||||
import {
|
import {
|
||||||
DICT_TYPE,
|
DICT_TYPE,
|
||||||
|
@ -12,18 +10,15 @@ import {
|
||||||
getRangePickerDefaultProps,
|
getRangePickerDefaultProps,
|
||||||
} from '#/utils';
|
} from '#/utils';
|
||||||
|
|
||||||
// TODO @siye:这个要去掉么?没用到
|
|
||||||
const { hasAccessByCodes } = useAccess();
|
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
fieldName: 'name',
|
fieldName: 'name',
|
||||||
label: '流程名称',
|
label: '任务名称',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: '请输入流程名称',
|
placeholder: '请输入任务名称',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -79,8 +74,8 @@ export function useGridColumns<T = BpmTaskApi.TaskVO>(
|
||||||
): VxeTableGridOptions['columns'] {
|
): VxeTableGridOptions['columns'] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
field: 'name',
|
field: 'processInstance.name',
|
||||||
title: '流程名称',
|
title: '流程',
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
},
|
},
|
||||||
|
|
|
@ -78,18 +78,19 @@ function onRefresh() {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<DocAlert
|
<template #doc>
|
||||||
title="审批通过、不通过、驳回"
|
<DocAlert
|
||||||
url="https://doc.iocoder.cn/bpm/task-todo-done/"
|
title="审批通过、不通过、驳回"
|
||||||
/>
|
url="https://doc.iocoder.cn/bpm/task-todo-done/"
|
||||||
<DocAlert title="审批加签、减签" url="https://doc.iocoder.cn/bpm/sign/" />
|
/>
|
||||||
<DocAlert
|
<DocAlert title="审批加签、减签" url="https://doc.iocoder.cn/bpm/sign/" />
|
||||||
title="审批转办、委派、抄送"
|
<DocAlert
|
||||||
url="https://doc.iocoder.cn/bpm/task-delegation-and-cc/"
|
title="审批转办、委派、抄送"
|
||||||
/>
|
url="https://doc.iocoder.cn/bpm/task-delegation-and-cc/"
|
||||||
<DocAlert title="审批加签、减签" url="https://doc.iocoder.cn/bpm/sign/" />
|
/>
|
||||||
|
<DocAlert title="审批加签、减签" url="https://doc.iocoder.cn/bpm/sign/" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<FormModal @success="onRefresh" />
|
|
||||||
<Grid table-title="已办任务">
|
<Grid table-title="已办任务">
|
||||||
<!-- 摘要 -->
|
<!-- 摘要 -->
|
||||||
<template #slot-summary="{ row }">
|
<template #slot-summary="{ row }">
|
||||||
|
|
|
@ -33,19 +33,11 @@ export function useGridColumns<T = BpmTaskApi.TaskVO>(
|
||||||
): VxeTableGridOptions['columns'] {
|
): VxeTableGridOptions['columns'] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
field: 'name',
|
field: 'processInstance.name',
|
||||||
title: '流程名称',
|
title: '流程',
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
field: 'processInstance.summary',
|
|
||||||
title: '摘要',
|
|
||||||
minWidth: 200,
|
|
||||||
slots: {
|
|
||||||
default: 'slot-summary',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
field: 'processInstance.startUser.nickname',
|
field: 'processInstance.startUser.nickname',
|
||||||
title: '发起人',
|
title: '发起人',
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
|
||||||
defineOptions({ name: 'BpmManagerTask' });
|
defineOptions({ name: 'BpmManagerTask' });
|
||||||
|
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid] = useVbenVxeGrid({
|
||||||
formOptions: {
|
formOptions: {
|
||||||
schema: useGridFormSchema(),
|
schema: useGridFormSchema(),
|
||||||
},
|
},
|
||||||
|
@ -45,11 +45,14 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
cellConfig: {
|
cellConfig: {
|
||||||
height: 64,
|
height: 64,
|
||||||
},
|
},
|
||||||
} as VxeTableGridOptions<BpmTaskApi.TaskVO>,
|
} as VxeTableGridOptions<BpmTaskApi.TaskManagerVO>,
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 表格操作按钮的回调函数 */
|
/** 表格操作按钮的回调函数 */
|
||||||
function onActionClick({ code, row }: OnActionClickParams<BpmTaskApi.TaskVO>) {
|
function onActionClick({
|
||||||
|
code,
|
||||||
|
row,
|
||||||
|
}: OnActionClickParams<BpmTaskApi.TaskManagerVO>) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 'history': {
|
case 'history': {
|
||||||
onHistory(row);
|
onHistory(row);
|
||||||
|
@ -59,50 +62,22 @@ function onActionClick({ code, row }: OnActionClickParams<BpmTaskApi.TaskVO>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查看历史 */
|
/** 查看历史 */
|
||||||
function onHistory(row: BpmTaskApi.TaskVO) {
|
function onHistory(row: BpmTaskApi.TaskManagerVO) {
|
||||||
console.warn(row);
|
console.warn(row);
|
||||||
router.push({
|
router.push({
|
||||||
name: 'BpmProcessInstanceDetail',
|
name: 'BpmProcessInstanceDetail',
|
||||||
query: {
|
query: {
|
||||||
// TODO @siye:数据类型,会爆红哈;
|
|
||||||
id: row.processInstance.id,
|
id: row.processInstance.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 刷新表格 */
|
|
||||||
function onRefresh() {
|
|
||||||
gridApi.query();
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<DocAlert title="工作流手册" url="https://doc.iocoder.cn/bpm/" />
|
<template #doc>
|
||||||
|
<DocAlert title="工作流手册" url="https://doc.iocoder.cn/bpm/" />
|
||||||
<FormModal @success="onRefresh" />
|
</template>
|
||||||
<Grid table-title="流程任务">
|
<Grid table-title="流程任务" />
|
||||||
<!-- 摘要 -->
|
|
||||||
<!-- TODO siye:这个要不要,也放到 data.ts 处理掉? -->
|
|
||||||
<template #slot-summary="{ row }">
|
|
||||||
<div
|
|
||||||
class="flex flex-col py-2"
|
|
||||||
v-if="
|
|
||||||
row.processInstance.summary &&
|
|
||||||
row.processInstance.summary.length > 0
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in row.processInstance.summary"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<span class="text-gray-500">
|
|
||||||
{{ item.key }} : {{ item.value }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else>-</div>
|
|
||||||
</template>
|
|
||||||
</Grid>
|
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -14,10 +14,10 @@ export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
fieldName: 'name',
|
fieldName: 'name',
|
||||||
label: '流程名称',
|
label: '任务名称',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: '请输入流程名称',
|
placeholder: '请输入任务名称',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -72,8 +72,8 @@ export function useGridColumns<T = BpmTaskApi.TaskVO>(
|
||||||
): VxeTableGridOptions['columns'] {
|
): VxeTableGridOptions['columns'] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
field: 'name',
|
field: 'processInstance.name',
|
||||||
title: '流程名称',
|
title: '流程',
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
},
|
},
|
||||||
|
@ -81,9 +81,9 @@ export function useGridColumns<T = BpmTaskApi.TaskVO>(
|
||||||
field: 'processInstance.summary',
|
field: 'processInstance.summary',
|
||||||
title: '摘要',
|
title: '摘要',
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
slots: {
|
// slots: {
|
||||||
default: 'slot-summary',
|
// default: 'slot-summary',
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'processInstance.startUser.nickname',
|
field: 'processInstance.startUser.nickname',
|
||||||
|
|
|
@ -78,18 +78,18 @@ function onRefresh() {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<DocAlert
|
<template #doc>
|
||||||
title="审批通过、不通过、驳回"
|
<DocAlert
|
||||||
url="https://doc.iocoder.cn/bpm/task-todo-done/"
|
title="审批通过、不通过、驳回"
|
||||||
/>
|
url="https://doc.iocoder.cn/bpm/task-todo-done/"
|
||||||
<DocAlert title="审批加签、减签" url="https://doc.iocoder.cn/bpm/sign/" />
|
/>
|
||||||
<DocAlert
|
<DocAlert title="审批加签、减签" url="https://doc.iocoder.cn/bpm/sign/" />
|
||||||
title="审批转办、委派、抄送"
|
<DocAlert
|
||||||
url="https://doc.iocoder.cn/bpm/task-delegation-and-cc/"
|
title="审批转办、委派、抄送"
|
||||||
/>
|
url="https://doc.iocoder.cn/bpm/task-delegation-and-cc/"
|
||||||
<DocAlert title="审批加签、减签" url="https://doc.iocoder.cn/bpm/sign/" />
|
/>
|
||||||
|
<DocAlert title="审批加签、减签" url="https://doc.iocoder.cn/bpm/sign/" />
|
||||||
<FormModal @success="onRefresh" />
|
</template>
|
||||||
<Grid table-title="待办任务">
|
<Grid table-title="待办任务">
|
||||||
<!-- 摘要 -->
|
<!-- 摘要 -->
|
||||||
<!-- TODO siye:这个要不要,也放到 data.ts 处理掉? -->
|
<!-- TODO siye:这个要不要,也放到 data.ts 处理掉? -->
|
||||||
|
|
Loading…
Reference in New Issue