From 97b91aaf7cf691ecd45541e06ea15b853ce26cd8 Mon Sep 17 00:00:00 2001 From: dap <15891557205@163.com> Date: Wed, 11 Dec 2024 21:33:59 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=B5=81=E7=A8=8B=E5=AE=9A=E4=B9=89(?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E4=B8=AD)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/workflow/category/model.d.ts | 1 + .../src/api/workflow/definition/index.ts | 130 ++++++++++++ apps/web-antd/src/router/routes/local.ts | 24 +++ .../workflow/components/flow-designer.vue | 25 +++ .../processDefinition/category-tree.vue | 125 +++++++++++ .../views/workflow/processDefinition/data.tsx | 173 ++++++++++++++++ .../workflow/processDefinition/index.vue | 196 +++++++++++++++++- 7 files changed, 670 insertions(+), 4 deletions(-) create mode 100644 apps/web-antd/src/api/workflow/definition/index.ts create mode 100644 apps/web-antd/src/views/workflow/components/flow-designer.vue create mode 100644 apps/web-antd/src/views/workflow/processDefinition/category-tree.vue create mode 100644 apps/web-antd/src/views/workflow/processDefinition/data.tsx diff --git a/apps/web-antd/src/api/workflow/category/model.d.ts b/apps/web-antd/src/api/workflow/category/model.d.ts index 87937ec8..00ee6077 100644 --- a/apps/web-antd/src/api/workflow/category/model.d.ts +++ b/apps/web-antd/src/api/workflow/category/model.d.ts @@ -30,6 +30,7 @@ export interface CategoryVO { * 子对象 */ children: CategoryVO[]; + key: string; } export interface CategoryForm extends BaseEntity { diff --git a/apps/web-antd/src/api/workflow/definition/index.ts b/apps/web-antd/src/api/workflow/definition/index.ts new file mode 100644 index 00000000..bf228a6b --- /dev/null +++ b/apps/web-antd/src/api/workflow/definition/index.ts @@ -0,0 +1,130 @@ +import type { ID, IDS, PageQuery } from '#/api/common'; + +import { requestClient } from '#/api/request'; + +export function workflowDefinitionList(params?: PageQuery) { + return requestClient.get('/workflow/definition/list', { params }); +} + +/** + * 获取历史流程定义列表 + * @param flowCode + * @returns + */ +export function getHisListByKey(flowCode: string) { + return requestClient.get(`/workflow/definition/getHisListByKey/${flowCode}`); +} + +/** + * 获取流程定义详细信息 + * @param id id + * @returns + */ +export function workflowDefinitionInfo(id: ID) { + return requestClient.get(`/workflow/definition/${id}`); +} + +/** + * 新增流程定义 + * @param data + */ +export function workflowDefinitionAdd(data: any) { + return requestClient.postWithMsg('/workflow/definition', data); +} + +/** + * 更新流程定义 + * @param data + */ +export function workflowDefinitionUpdate(data: any) { + return requestClient.putWithMsg('/workflow/definition', data); +} + +/** + * 发布流程定义 + * @param id id + * @returns boolean + */ +export function workflowDefinitionPublish(id: ID) { + return requestClient.putWithMsg( + `/workflow/definition/publish/${id}`, + ); +} + +/** + * 取消发布流程定义 + * @param id id + * @returns boolean + */ +export function workflowDefinitionUnPublish(id: ID) { + return requestClient.putWithMsg( + `/workflow/definition/unPublish/${id}`, + ); +} + +/** + * 删除流程定义 + * @param ids idList + */ +export function workflowDefinitionDelete(ids: IDS) { + return requestClient.deleteWithMsg(`/workflow/definition/${ids}`); +} + +/** + * 复制流程定义 + * @param id id + */ +export function workflowDefinitionCopy(id: ID) { + return requestClient.postWithMsg(`/workflow/definition/copy/${id}`); +} + +/** + * 导入流程定义 + * @param file 模型文件 + * @returns boolean + */ +export function workflowDefinitionImport(file: File) { + return requestClient.postWithMsg( + '/workflow/definition/importDef', + { + file, + }, + { headers: { 'Content-Type': 'multipart/form-data' } }, + ); +} + +/** + * 导出流程定义 + * @param id id + * @returns blob + */ +export function workflowDefinitionExport(id: ID) { + return requestClient.postWithMsg( + `/workflow/definition/exportDef/${id}`, + { + responseType: 'blob', + isTransformResponse: false, + }, + ); +} + +/** + * 获取流程定义xml字符串 + * @param id id + * @returns xml + */ +export function workflowDefinitionXml(id: ID) { + return requestClient.get(`/workflow/definition/xmlString/${id}`); +} + +/** + * 激活/挂起流程定义 + * @param id 流程定义id + * @param active 激活/挂起 + * @returns boolean + */ +export function workflowDefinitionActive(id: ID, active: boolean) { + return requestClient.putWithMsg( + `/workflow/definition/active/${id}?active=${active}`, + ); +} diff --git a/apps/web-antd/src/router/routes/local.ts b/apps/web-antd/src/router/routes/local.ts index 1e131b3c..1fa950d4 100644 --- a/apps/web-antd/src/router/routes/local.ts +++ b/apps/web-antd/src/router/routes/local.ts @@ -105,6 +105,30 @@ const profileRoute: RouteRecordStringComponent[] = [ }, ], }, + { + component: 'BasicLayout', + meta: { + hideChildrenInMenu: true, + hideInMenu: true, + title: '流程设计', + }, + name: 'WorkflowDesigner', + path: '/', + redirect: '/workflow/designer', + children: [ + { + component: '/workflow/components/flow-designer', + meta: { + activePath: '/workflow/processDefinition', + icon: 'eos-icons:role-binding-outlined', + keepAlive: true, + title: '流程设计', + }, + name: 'RoleAssignIndex', + path: '/workflow/designer', + }, + ], + }, ]; /** diff --git a/apps/web-antd/src/views/workflow/components/flow-designer.vue b/apps/web-antd/src/views/workflow/components/flow-designer.vue new file mode 100644 index 00000000..6c58d3cf --- /dev/null +++ b/apps/web-antd/src/views/workflow/components/flow-designer.vue @@ -0,0 +1,25 @@ + + + diff --git a/apps/web-antd/src/views/workflow/processDefinition/category-tree.vue b/apps/web-antd/src/views/workflow/processDefinition/category-tree.vue new file mode 100644 index 00000000..4b2d4d29 --- /dev/null +++ b/apps/web-antd/src/views/workflow/processDefinition/category-tree.vue @@ -0,0 +1,125 @@ + + + diff --git a/apps/web-antd/src/views/workflow/processDefinition/data.tsx b/apps/web-antd/src/views/workflow/processDefinition/data.tsx new file mode 100644 index 00000000..bf3d5b3a --- /dev/null +++ b/apps/web-antd/src/views/workflow/processDefinition/data.tsx @@ -0,0 +1,173 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { DictEnum } from '@vben/constants'; +import { getPopupContainer } from '@vben/utils'; + +import { type FormSchemaGetter, z } from '#/adapter/form'; +import { getDictOptions } from '#/utils/dict'; + +export const querySchema: FormSchemaGetter = () => [ + { + component: 'Input', + fieldName: 'flowName', + label: '流程名称', + }, + { + component: 'Input', + fieldName: 'flowCode', + label: '流程code', + }, +]; + +export const columns: VxeGridProps['columns'] = [ + { type: 'checkbox', width: 60 }, + { + field: 'flowName', + title: '流程名称', + minWidth: 150, + }, + { + field: 'flowCode', + title: '流程code', + minWidth: 150, + }, + { + field: 'version', + title: '版本号', + minWidth: 80, + formatter: ({ cellValue }) => `V${cellValue}.0`, + }, + { + field: 'activityStatus', + title: '状态', + minWidth: 100, + }, + { + field: 'isPublish', + title: '发布状态', + minWidth: 100, + }, + { + field: 'action', + fixed: 'right', + slots: { default: 'action' }, + title: '操作', + resizable: false, + width: 180, + }, +]; + +export const drawerSchema: FormSchemaGetter = () => [ + { + component: 'Input', + dependencies: { + show: () => false, + triggerFields: [''], + }, + fieldName: 'userId', + }, + { + component: 'Input', + fieldName: 'userName', + label: '用户账号', + rules: 'required', + }, + { + component: 'InputPassword', + fieldName: 'password', + label: '用户密码', + rules: 'required', + }, + { + component: 'Input', + fieldName: 'nickName', + label: '用户昵称', + rules: 'required', + }, + { + component: 'TreeSelect', + // 在drawer里更新 这里不需要默认的componentProps + defaultValue: undefined, + fieldName: 'deptId', + label: '所属部门', + rules: 'selectRequired', + }, + { + component: 'Input', + fieldName: 'phonenumber', + label: '手机号码', + defaultValue: undefined, + rules: z + .string() + .regex(/^1[3-9]\d{9}$/, '请输入正确的手机号码') + .optional() + .or(z.literal('')), + }, + { + component: 'Input', + fieldName: 'email', + defaultValue: undefined, + label: '邮箱', + /** + * z.literal 是 Zod 中的一种类型,用于定义一个特定的字面量值。 + * 它可以用于确保输入的值与指定的字面量完全匹配。 + * 例如,你可以使用 z.literal 来确保某个字段的值只能是特定的字符串、数字、布尔值等。 + * 即空字符串也可通过校验 + */ + rules: z.string().email('请输入正确的邮箱').optional().or(z.literal('')), + }, + { + component: 'RadioGroup', + componentProps: { + buttonStyle: 'solid', + options: getDictOptions(DictEnum.SYS_USER_SEX), + optionType: 'button', + }, + defaultValue: '0', + fieldName: 'sex', + formItemClass: 'col-span-2 lg:col-span-1', + label: '性别', + }, + { + component: 'RadioGroup', + componentProps: { + buttonStyle: 'solid', + options: getDictOptions(DictEnum.SYS_NORMAL_DISABLE), + optionType: 'button', + }, + defaultValue: '0', + fieldName: 'status', + formItemClass: 'col-span-2 lg:col-span-1', + label: '状态', + }, + { + component: 'Select', + componentProps: { + getPopupContainer, + mode: 'multiple', + optionFilterProp: 'label', + optionLabelProp: 'label', + placeholder: '请先选择部门', + }, + fieldName: 'postIds', + help: '选择部门后, 将自动加载该部门下所有的岗位', + label: '岗位', + }, + { + component: 'Select', + componentProps: { + getPopupContainer, + mode: 'multiple', + optionFilterProp: 'title', + optionLabelProp: 'title', + }, + fieldName: 'roleIds', + label: '角色', + }, + { + component: 'Textarea', + fieldName: 'remark', + formItemClass: 'items-baseline', + label: '备注', + }, +]; diff --git a/apps/web-antd/src/views/workflow/processDefinition/index.vue b/apps/web-antd/src/views/workflow/processDefinition/index.vue index 06372a15..895f6913 100644 --- a/apps/web-antd/src/views/workflow/processDefinition/index.vue +++ b/apps/web-antd/src/views/workflow/processDefinition/index.vue @@ -1,9 +1,197 @@