diff --git a/package.json b/package.json index 7a47e4b7dace40b3c4c46363f222dfb7a103d5e8..751bd6f512d38021bfaf4c28ac3914fe5048c73e 100644 --- a/package.json +++ b/package.json @@ -20,23 +20,33 @@ }, "dependencies": { "@element-plus/icons-vue": "2.3.1", + "@highlightjs/vue-plugin": "2.1.0", + "@lezer/common": "1.2.1", "@vueup/vue-quill": "1.2.0", "@vueuse/core": "10.7.2", "animate.css": "4.1.1", "await-to-js": "3.0.0", "axios": "1.6.5", + "bpmn-js": "16.4.0", + "camunda-bpmn-js-behaviors": "1.2.2", + "camunda-bpmn-moddle": "7.0.1", "crypto-js": "4.2.0", + "diagram-js": "12.3.0", + "didi": "9.0.2", "echarts": "5.4.3", "element-plus": "2.4.4", "file-saver": "2.0.5", "fuse.js": "7.0.0", + "highlight.js": "11.9.0", "image-conversion": "^2.1.1", "js-cookie": "3.0.5", "jsencrypt": "3.3.2", + "moddle": "6.2.3", "nprogress": "0.2.0", "path-browserify": "1.0.1", "path-to-regexp": "6.2.1", "pinia": "2.1.7", + "preact": "10.19.3", "screenfull": "6.0.2", "vform3-builds": "3.0.10", "vue": "3.4.13", @@ -44,7 +54,8 @@ "vue-i18n": "9.9.0", "vue-router": "4.2.5", "vue-types": "5.1.1", - "vxe-table": "4.5.18" + "vxe-table": "4.5.18", + "zeebe-bpmn-moddle": "1.0.0" }, "devDependencies": { "@iconify/json": "2.2.168", @@ -60,8 +71,8 @@ "@unocss/preset-attributify": "0.58.3", "@unocss/preset-icons": "0.58.3", "@unocss/preset-uno": "0.58.3", - "@vue/compiler-sfc": "3.4.13", "@vitejs/plugin-vue": "5.0.3", + "@vue/compiler-sfc": "3.4.13", "autoprefixer": "10.4.16", "eslint": "8.56.0", "eslint-config-prettier": "9.1.0", @@ -82,11 +93,11 @@ "unplugin-icons": "0.18.2", "unplugin-vue-components": "0.26.0", "unplugin-vue-setup-extend-plus": "1.0.0", + "vite": "5.0.11", "vite-plugin-compression": "0.5.1", "vite-plugin-svg-icons": "2.0.1", "vitest": "1.2.0", "vue-eslint-parser": "9.4.0", - "vue-tsc": "1.8.27", - "vite": "5.0.11" + "vue-tsc": "1.8.27" } } diff --git a/src/api/system/role/index.ts b/src/api/system/role/index.ts index 4e8b6127975d6aac3aa00d0f8d507059a65f3a05..fb0fcabcf1090d9286b88b0da90e27a375451c02 100644 --- a/src/api/system/role/index.ts +++ b/src/api/system/role/index.ts @@ -12,6 +12,17 @@ export const listRole = (query: RoleQuery): AxiosPromise => { }); }; +/** + * 通过roleIds查询角色 + * @param roleIds + */ +export const optionSelect = (roleIds: (number | string)[]): AxiosPromise => { + return request({ + url: '/system/role/optionselect?roleIds=' + roleIds, + method: 'get' + }); +}; + /** * 查询角色详细 */ @@ -142,3 +153,8 @@ export const deptTreeSelect = (roleId: string | number): AxiosPromise => { }); }; +/** + * 通过用户ids查询用户 + * @param userIds + */ +export const optionSelect = (userIds: (number | string)[]): AxiosPromise => { + return request({ + url: '/system/user/optionselect?userIds=' + userIds, + method: 'get' + }); +}; + /** * 获取用户详情 * @param userId @@ -199,6 +210,7 @@ export const deptTreeSelect = (): AxiosPromise => { export default { listUser, getUser, + optionSelect, addUser, updateUser, delUser, diff --git a/src/api/workflow/category/index.ts b/src/api/workflow/category/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..e9723b05d4cfde93d1c071171ba6c3bc06af80fc --- /dev/null +++ b/src/api/workflow/category/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { CategoryVO, CategoryForm, CategoryQuery } from '@/api/workflow/category/types'; + +/** + * 查询流程分类列表 + * @param query + * @returns {*} + */ + +export const listCategory = (query?: CategoryQuery): AxiosPromise => { + return request({ + url: '/workflow/category/list', + method: 'get', + params: query + }); +}; + +/** + * 查询流程分类详细 + * @param id + */ +export const getCategory = (id: string | number): AxiosPromise => { + return request({ + url: '/workflow/category/' + id, + method: 'get' + }); +}; + +/** + * 新增流程分类 + * @param data + */ +export const addCategory = (data: CategoryForm) => { + return request({ + url: '/workflow/category', + method: 'post', + data: data + }); +}; + +/** + * 修改流程分类 + * @param data + */ +export const updateCategory = (data: CategoryForm) => { + return request({ + url: '/workflow/category', + method: 'put', + data: data + }); +}; + +/** + * 删除流程分类 + * @param id + */ +export const delCategory = (id: string | number | Array) => { + return request({ + url: '/workflow/category/' + id, + method: 'delete' + }); +}; diff --git a/src/api/workflow/category/types.ts b/src/api/workflow/category/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..414fa55ed8da5f8bbc6ac72eb36d04bc12361966 --- /dev/null +++ b/src/api/workflow/category/types.ts @@ -0,0 +1,67 @@ +export interface CategoryVO { + /** + * 主键 + */ + id: string; + + /** + * 分类名称 + */ + categoryName: string; + + /** + * 分类编码 + */ + categoryCode: string; + + /** + * 父级id + */ + parentId: string | number; + + /** + * 排序 + */ + sortNum: number; + + children?: CategoryVO[]; +} + +export interface CategoryForm extends BaseEntity { + /** + * 主键 + */ + id?: string | number; + + /** + * 分类名称 + */ + categoryName?: string; + + /** + * 分类编码 + */ + categoryCode?: string; + + /** + * 父级id + */ + parentId?: string | number; + + /** + * 排序 + */ + sortNum?: number; +} + +export interface CategoryQuery extends PageQuery { + /** + * 分类名称 + */ + categoryName?: string; + + /** + * 分类编码 + */ + categoryCode?: string; +} diff --git a/src/api/workflow/leave/index.ts b/src/api/workflow/leave/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..36c6fdfca60d862139911e2a97b03e0d4df6ce91 --- /dev/null +++ b/src/api/workflow/leave/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { LeaveVO, LeaveQuery, LeaveForm } from '@/api/workflow/leave/types'; + +/** + * 查询请假列表 + * @param query + * @returns {*} + */ + +export const listLeave = (query?: LeaveQuery): AxiosPromise => { + return request({ + url: '/demo/leave/list', + method: 'get', + params: query + }); +}; + +/** + * 查询请假详细 + * @param id + */ +export const getLeave = (id: string | number): AxiosPromise => { + return request({ + url: '/demo/leave/' + id, + method: 'get' + }); +}; + +/** + * 新增请假 + * @param data + */ +export const addLeave = (data: LeaveForm): AxiosPromise => { + return request({ + url: '/demo/leave', + method: 'post', + data: data + }); +}; + +/** + * 修改请假 + * @param data + */ +export const updateLeave = (data: LeaveForm): AxiosPromise => { + return request({ + url: '/demo/leave', + method: 'put', + data: data + }); +}; + +/** + * 删除请假 + * @param id + */ +export const delLeave = (id: string | number | Array) => { + return request({ + url: '/demo/leave/' + id, + method: 'delete' + }); +}; diff --git a/src/api/workflow/leave/types.ts b/src/api/workflow/leave/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..9405257a2e76626a848e8d7fe65e2fd36f5c98ed --- /dev/null +++ b/src/api/workflow/leave/types.ts @@ -0,0 +1,22 @@ +export interface LeaveVO { + id: string | number; + leaveType: string; + startDate: string; + endDate: string; + leaveDays: number; + remark: string; +} + +export interface LeaveForm extends BaseEntity { + id?: string | number; + leaveType?: string; + startDate?: string; + endDate?: string; + leaveDays?: number; + remark?: string; +} + +export interface LeaveQuery extends PageQuery { + startLeaveDays?: number; + endLeaveDays?: number; +} diff --git a/src/api/workflow/model/index.ts b/src/api/workflow/model/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..f58cdd36cd47f70bd7eaf6b92185d1737b1760f1 --- /dev/null +++ b/src/api/workflow/model/index.ts @@ -0,0 +1,91 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { ModelForm, ModelQuery, ModelVO } from '@/api/workflow/model/types'; + +/** + * 查询模型列表 + * @param query + * @returns {*} + */ +export const listModel = (query: ModelQuery): AxiosPromise => { + return request({ + url: '/workflow/model/list', + method: 'get', + params: query + }); +}; + +/** + * 查询模型信息 + * @param query + * @returns {*} + */ +export const getInfo = (id: string): AxiosPromise => { + return request({ + url: '/workflow/model/getInfo/'+id, + method: 'get' + }); +}; + +/** + * 新增模型 + * @param data + * @returns {*} + */ +export const addModel = (data: ModelForm): AxiosPromise => { + return request({ + url: '/workflow/model/save', + method: 'post', + data: data + }); +}; + +/** + * 修改模型信息 + * @param data + * @returns {*} + */ +export function update(data: ModelForm): AxiosPromise { + return request({ + url: '/workflow/model/update', + method: 'put', + data: data + }); +} + +/** + * 修改模型信息 + * @param data + * @returns {*} + */ +export function editModelXml(data: ModelForm): AxiosPromise { + return request({ + url: '/workflow/model/editModelXml', + method: 'put', + data: data + }); +} + +/** + * 按id删除模型 + * @returns {*} + * @param id 模型id + */ +export function delModel(id: string | string[]): AxiosPromise { + return request({ + url: '/workflow/model/' + id, + method: 'delete' + }); +} + +/** + * 模型部署 + * @returns {*} + * @param id 模型id + */ +export const modelDeploy = (id: string): AxiosPromise => { + return request({ + url: `/workflow/model/modelDeploy/${id}`, + method: 'post' + }); +}; diff --git a/src/api/workflow/model/types.ts b/src/api/workflow/model/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..40a0faa1fe461f8675815eba9eae723c0cfa0f51 --- /dev/null +++ b/src/api/workflow/model/types.ts @@ -0,0 +1,66 @@ +export interface ModelForm { + id: string, + name: string; + key: string; + categoryCode: string; + xml:string, + svg:string, + description: string; +} + +export interface ModelQuery extends PageQuery { + name?: string; + key?: string; + categoryCode?: string; +} + +export interface OriginalPersistentState { + metaInfo: string; + editorSourceValueId: string; + createTime: string; + deploymentId?: string; + name: string; + tenantId: string; + category?: string; + version: number; + editorSourceExtraValueId?: string; + key: string; + lastUpdateTime: string; +} + +export interface PersistentState { + metaInfo: string; + editorSourceValueId: string; + createTime: string; + deploymentId?: string; + name: string; + tenantId: string; + category?: string; + version: number; + editorSourceExtraValueId?: string; + key: string; + lastUpdateTime: string; +} + +export interface ModelVO { + id: string; + revision: number; + originalPersistentState: OriginalPersistentState; + name: string; + key: string; + category?: string; + createTime: string; + lastUpdateTime: string; + version: number; + metaInfo: string; + deploymentId?: string; + editorSourceValueId: string; + editorSourceExtraValueId?: string; + tenantId: string; + persistentState: PersistentState; + revisionNext: number; + idPrefix: string; + inserted: boolean; + updated: boolean; + deleted: boolean; +} diff --git a/src/api/workflow/processDefinition/index.ts b/src/api/workflow/processDefinition/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..f64b53160f1c1fd213752207c4145942975733e2 --- /dev/null +++ b/src/api/workflow/processDefinition/index.ts @@ -0,0 +1,123 @@ +import request from '@/utils/request'; +import { ProcessDefinitionQuery, ProcessDefinitionVO, ProcessDefinitionXmlVO } from '@/api/workflow/processDefinition/types'; +import { AxiosPromise } from 'axios'; +const baseUrl = import.meta.env.VITE_APP_BASE_API; + +/** + * 获取流程定义列表 + * @param query 流程实例id + * @returns + */ +export const listProcessDefinition = (query: ProcessDefinitionQuery): AxiosPromise => { + return request({ + url: `/workflow/processDefinition/list`, + method: 'get', + params: query + }); +}; +/** + * 按照流程定义key获取流程定义 + * @param processInstanceId 流程实例id + * @returns + */ +export const getProcessDefinitionListByKey = (key: string) => { + return request({ + url: `/workflow/processDefinition/getProcessDefinitionListByKey/${key}`, + method: 'get' + }); +}; + +/** + * 通过流程定义id获取流程图 + */ +export const processDefinitionImage = (processDefinitionId: string): AxiosPromise => { + return request({ + url: `/workflow/processDefinition/processDefinitionImage/${processDefinitionId}` + '?t' + Math.random(), + method: 'get' + }); +}; + +/** + * 通过流程定义id获取xml + * @param processDefinitionId 流程定义id + * @returns + */ +export const processDefinitionXml = (processDefinitionId: string): AxiosPromise => { + return request({ + url: `/workflow/processDefinition/processDefinitionXml/${processDefinitionId}`, + method: 'get' + }); +}; + +/** + * 删除流程定义 + * @param processDefinitionId 流程定义id + * @param deploymentId 部署id + * @returns + */ +export const deleteProcessDefinition = (deploymentId: string, processDefinitionId: string) => { + return request({ + url: `/workflow/processDefinition/${deploymentId}/${processDefinitionId}`, + method: 'delete' + }); +}; + +/** + * 挂起/激活 + * @param processDefinitionId 流程定义id + * @returns + */ +export const updateProcessDefState = (processDefinitionId: string) => { + return request({ + url: `/workflow/processDefinition/updateProcessDefState/${processDefinitionId}`, + method: 'put' + }); +}; + +/** + * 流程定义转换为模型 + * @param processDefinitionId 流程定义id + * @returns + */ +export const convertToModel = (processDefinitionId: string) => { + return request({ + url: `/workflow/processDefinition/convertToModel/${processDefinitionId}`, + method: 'put' + }); +}; + +/** + * 通过zip或xml部署流程定义 + * @returns + */ +export function deployProcessFile(data: any) { + return request({ + url: '/workflow/processDefinition/deployByFile', + method: 'post', + data: data + }); +} + +/** + * 迁移流程 + * @param currentProcessDefinitionId + * @param fromProcessDefinitionId + * @returns + */ +export const migrationProcessDefinition = (currentProcessDefinitionId: string, fromProcessDefinitionId: string) => { + return request({ + url: `/workflow/processDefinition/migrationProcessDefinition/${currentProcessDefinitionId}/${fromProcessDefinitionId}`, + method: 'put' + }); +}; + +/** + * 查询流程定义列表 + * @returns + */ +export const getProcessDefinitionList = () => { + return request({ + url: `/workflow/processDefinition/getProcessDefinitionList`, + method: 'get' + }); +}; diff --git a/src/api/workflow/processDefinition/types.ts b/src/api/workflow/processDefinition/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..8987b33c7158fd6e88dd7ba6486e9c2958f6c9df --- /dev/null +++ b/src/api/workflow/processDefinition/types.ts @@ -0,0 +1,22 @@ +export interface ProcessDefinitionQuery extends PageQuery { + key?: string; + name?: string; + categoryCode?: string; +} + +export interface ProcessDefinitionVO extends BaseEntity { + id: string; + name: string; + key: string; + version: number; + suspensionState: number; + resourceName: string; + diagramResourceName: string; + deploymentId: string; + deploymentTime: string; +} + +export interface ProcessDefinitionXmlVO { + xml: string[]; + xmlStr: string; +} diff --git a/src/api/workflow/processInstance/index.ts b/src/api/workflow/processInstance/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..295fc0de96bf93013844caf65ef18e2b8253c458 --- /dev/null +++ b/src/api/workflow/processInstance/index.ts @@ -0,0 +1,115 @@ +import request from '@/utils/request'; +import { ProcessInstanceQuery, ProcessInstanceVO } from '@/api/workflow/processInstance/types'; +import { AxiosPromise } from 'axios'; +import { string } from 'vue-types'; +const baseUrl = import.meta.env.VITE_APP_BASE_API; + +/** + * 查询运行中实例列表 + * @param query + * @returns {*} + */ +export const getProcessInstanceRunningByPage = (query: ProcessInstanceQuery): AxiosPromise => { + return request({ + url: '/workflow/processInstance/getProcessInstanceRunningByPage', + method: 'get', + params: query + }); +}; + +/** + * 查询已完成实例列表 + * @param query + * @returns {*} + */ +export const getProcessInstanceFinishByPage = (query: ProcessInstanceQuery): AxiosPromise => { + return request({ + url: '/workflow/processInstance/getProcessInstanceFinishByPage', + method: 'get', + params: query + }); +}; + +/** + * 通过流程实例id获取历史流程图 + */ +export const getHistoryProcessImage = (processInstanceId: string) => { + return request({ + url: `/workflow/processInstance/getHistoryProcessImage/${processInstanceId}` + '?t' + Math.random(), + method: 'get' + }); +}; + +/** + * 获取审批记录 + * @param processInstanceId 流程实例id + * @returns + */ +export const getHistoryRecord = (processInstanceId: string) => { + return request({ + url: `/workflow/processInstance/getHistoryRecord/${processInstanceId}`, + method: 'get' + }); +}; + +/** + * 作废 + * @param data 参数 + * @returns + */ +export const deleteRuntimeProcessInst = (data: object) => { + return request({ + url: `/workflow/processInstance/deleteRuntimeProcessInst`, + method: 'post', + data: data + }); +}; + +/** + * 运行中的实例 删除程实例,删除历史记录,删除业务与流程关联信息 + * @param processInstanceId 流程实例id + * @returns + */ +export const deleteRuntimeProcessAndHisInst = (processInstanceId: string | string[]) => { + return request({ + url: `/workflow/processInstance/deleteRuntimeProcessAndHisInst/${processInstanceId}`, + method: 'delete' + }); +}; + +/** + * 已完成的实例 删除程实例,删除历史记录,删除业务与流程关联信息 + * @param processInstanceId 流程实例id + * @returns + */ +export const deleteFinishProcessAndHisInst = (processInstanceId: string | string[]) => { + return request({ + url: `/workflow/processInstance/deleteFinishProcessAndHisInst/${processInstanceId}`, + method: 'delete' + }); +}; + +/** + * 分页查询当前登录人单据 + * @param query + * @returns {*} + */ +export const getCurrentSubmitByPage = (query: ProcessInstanceQuery): AxiosPromise => { + return request({ + url: '/workflow/processInstance/getCurrentSubmitByPage', + method: 'get', + params: query + }); +}; + +/** + * 撤销流程 + * @param processInstanceId 流程实例id + * @returns + */ +export const cancelProcessApply = (processInstanceId: string) => { + return request({ + url: `/workflow/processInstance/cancelProcessApply/${processInstanceId}`, + method: 'post' + }); +}; diff --git a/src/api/workflow/processInstance/types.ts b/src/api/workflow/processInstance/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..99d0511acf039efa99f152e7167fe21c4fe7dfee --- /dev/null +++ b/src/api/workflow/processInstance/types.ts @@ -0,0 +1,27 @@ +import { TaskVO } from '@/api/workflow/task/types'; + +export interface ProcessInstanceQuery extends PageQuery { + categoryCode?: string; + name?: string; + key?: string; + startUserId?: string; + businessKey?: string; +} + +export interface ProcessInstanceVO extends BaseEntity { + id: string; + processDefinitionId: string; + processDefinitionName: string; + processDefinitionKey: string; + processDefinitionVersion: string; + deploymentId: string; + businessKey: string; + isSuspended?: any; + tenantId: string; + startTime: string; + endTime?: string; + startUserId: string; + businessStatus: string; + businessStatusName: string; + taskVoList: TaskVO[]; +} diff --git a/src/api/workflow/task/index.ts b/src/api/workflow/task/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..7be76f7d47ae54b3e524334e6b50daddae45dc43 --- /dev/null +++ b/src/api/workflow/task/index.ts @@ -0,0 +1,181 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { TaskQuery, TaskVO } from '@/api/workflow/task/types'; +/** + * 查询待办列表 + * @param query + * @returns {*} + */ +export const getTaskWaitByPage = (query: TaskQuery): AxiosPromise => { + return request({ + url: '/workflow/task/getTaskWaitByPage', + method: 'get', + params: query + }); +}; + +/** + * 查询已办列表 + * @param query + * @returns {*} + */ +export const getTaskFinishByPage = (query: TaskQuery): AxiosPromise => { + return request({ + url: '/workflow/task/getTaskFinishByPage', + method: 'get', + params: query + }); +}; + +/** + * 查询当前用户的抄送列表 + * @param query + * @returns {*} + */ +export const getTaskCopyByPage = (query: TaskQuery): AxiosPromise => { + return request({ + url: '/workflow/task/getTaskCopyByPage', + method: 'get', + params: query + }); +}; + +/** + * 当前租户所有待办任务 + * @param query + * @returns {*} + */ +export const getAllTaskWaitByPage = (query: TaskQuery): AxiosPromise => { + return request({ + url: '/workflow/task/getAllTaskWaitByPage', + method: 'get', + params: query + }); +}; + +/** + * 当前租户所有已办任务 + * @param query + * @returns {*} + */ +export const getAllTaskFinishByPage = (query: TaskQuery): AxiosPromise => { + return request({ + url: '/workflow/task/getAllTaskFinishByPage', + method: 'get', + params: query + }); +}; + +/** + * 启动流程 + * @param data + * @returns {*} + */ +export const startWorkFlow = (data: object) => { + return request({ + url: '/workflow/task/startWorkFlow', + method: 'post', + data: data + }); +}; + +/** + * 办理流程 + * @param data + * @returns {*} + */ +export const completeTask = (data: object) => { + return request({ + url: '/workflow/task/completeTask', + method: 'post', + data: data + }); +}; + +/** + * 认领任务 + * @param taskId + * @returns {*} + */ +export const claim = (taskId: string) => { + return request({ + url: '/workflow/task/claim/' + taskId, + method: 'post' + }); +}; + +/** + * 归还任务 + * @param taskId + * @returns {*} + */ +export const returnTask = (taskId: string) => { + return request({ + url: '/workflow/task/returnTask/' + taskId, + method: 'post' + }); +}; + +/** + * 任务驳回 + * @param taskId + * @returns {*} + */ +export const backProcess = (data: object) => { + return request({ + url: '/workflow/task/backProcess', + method: 'post', + data: data + }); +}; + +/** + * 获取流程状态 + * @param taskId + * @returns + */ +export const getBusinessStatus = (taskId: string) => { + return request({ + url: '/workflow/task/getBusinessStatus/' + taskId, + method: 'get' + }); +}; + +/** + * 加签 + * @param data + * @returns + */ +export const addMultiInstanceExecution = (data: object) => { + return request({ + url: '/workflow/task/addMultiInstanceExecution', + method: 'post', + data: data + }); +}; + +/** + * 减签 + * @param data + * @returns + */ +export const deleteMultiInstanceExecution = (data: object) => { + return request({ + url: '/workflow/task/deleteMultiInstanceExecution', + method: 'post', + data: data + }); +}; + +/** + * 修改任务办理人 + * @param taskIds + * @param userId + * @returns + */ +export const updateAssignee = (taskIds: Array,userId: string) => { + return request({ + url: `/workflow/task/updateAssignee/${taskIds}/${userId}`, + method: 'put' + }); +}; diff --git a/src/api/workflow/task/types.ts b/src/api/workflow/task/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..11cc48b300e6522ab3acf2a7ac78691422e257e2 --- /dev/null +++ b/src/api/workflow/task/types.ts @@ -0,0 +1,39 @@ +export interface TaskQuery extends PageQuery { + name?: string; + processDefinitionKey?: string; + processDefinitionName?: string; +} + +export interface ParticipantVo { + groupIds?: string[] | number[]; + candidate: string[] | number[]; + candidateName: string[]; + claim: boolean; +} + +export interface TaskVO extends BaseEntity { + id: string; + name: string; + description?: string; + priority: number; + owner?: string; + assignee?: string | number; + assigneeName?: string; + processInstanceId: string; + executionId: string; + taskDefinitionId?: any; + processDefinitionId: string; + endTime?: string; + taskDefinitionKey: string; + dueDate?: string; + category?: any; + parentTaskId?: any; + tenantId: string; + claimTime?: string; + businessStatus: string; + businessStatusName: string; + processDefinitionName: string; + processDefinitionKey: string; + participantVo: ParticipantVo; + multiInstance: boolean; +} diff --git a/src/api/workflow/workflowUser/index.ts b/src/api/workflow/workflowUser/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..e3ed8d962f2dd1cf5dcbbbd0179c591e71e59311 --- /dev/null +++ b/src/api/workflow/workflowUser/index.ts @@ -0,0 +1,53 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { UserVO } from '@/api/system/user/types'; + +/** + * 分页查询工作流选择加签人员 + * @param query + * @returns {*} + */ +export const getWorkflowAddMultiListByPage = (query: object) => { + return request({ + url: '/workflow/user/getWorkflowAddMultiListByPage', + method: 'get', + params: query + }); +}; + +/** + * 查询工作流选择减签人员 + * @param query + * @returns {*} + */ +export const getWorkflowDeleteMultiInstanceList = (taskId: string) => { + return request({ + url: '/workflow/user/getWorkflowDeleteMultiInstanceList/' + taskId, + method: 'get' + }); +}; + +/** + * 按照用户id查询用户 + * @param userIdList + * @returns {*} + */ +export const getUserListByIds = (userIdList: any[]): AxiosPromise => { + return request({ + url: '/workflow/user/getUserListByIds/' + userIdList, + method: 'get' + }); +}; + +/** + * 分页查询用户 + * @param query + * @returns {*} + */ +export const getUserListByPage = (query: object) => { + return request({ + url: '/workflow/user/getUserListByPage', + method: 'get', + params: query + }); +}; diff --git a/src/assets/icons/svg/caret-back.svg b/src/assets/icons/svg/caret-back.svg new file mode 100644 index 0000000000000000000000000000000000000000..9bae722337a5dd2c80391ebaaa48966c2e2e9d98 --- /dev/null +++ b/src/assets/icons/svg/caret-back.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/caret-forward.svg b/src/assets/icons/svg/caret-forward.svg new file mode 100644 index 0000000000000000000000000000000000000000..1ec3f7d0179c2a998cee507aae88b3dc03ca4901 --- /dev/null +++ b/src/assets/icons/svg/caret-forward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss index 43c093c9dbe3805ab2c687bdf13dcae0a17888eb..87326ee0541263438a2b8fe4b3f46b2488aa5e32 100644 --- a/src/assets/styles/element-ui.scss +++ b/src/assets/styles/element-ui.scss @@ -1,4 +1,15 @@ -// cover some element-ui styles + +.el-collapse { + .collapse__title { + font-weight: 600; + padding: 0 8px; + font-size: 1.2em; + line-height: 1.1em; + } + .el-collapse-item__content { + padding: 0 8px; + } +} .el-divider--horizontal { margin-bottom: 10px; @@ -68,6 +79,12 @@ .el-dialog__body { padding: 15px !important; } + .el-dialog__header { + padding: 16px 16px 8px 16px; + box-sizing: border-box; + border-bottom: 1px solid #e8e8e8; + margin-right: 0; + } } } } diff --git a/src/components/BpmnDesign/assets/defaultXML.ts b/src/components/BpmnDesign/assets/defaultXML.ts new file mode 100644 index 0000000000000000000000000000000000000000..dff0349505cfb52217e269ff0a53234754106f1f --- /dev/null +++ b/src/components/BpmnDesign/assets/defaultXML.ts @@ -0,0 +1,23 @@ +function generateRandomValue() { + // 生成一个随机数 + const randomValue = Math.random().toString(36).slice(2, 12); + return `Process_${randomValue}`; +} + +const cartage: string = 'default'; +export default ` + + + + + + + + + + + + + + +`; diff --git a/src/components/BpmnDesign/assets/lang/zh.ts b/src/components/BpmnDesign/assets/lang/zh.ts new file mode 100644 index 0000000000000000000000000000000000000000..61921a5d51ad445557ead16d5b34836c7b5b1c83 --- /dev/null +++ b/src/components/BpmnDesign/assets/lang/zh.ts @@ -0,0 +1,118 @@ +export const NodeName = { + 'bpmn:Process': '流程', + 'bpmn:StartEvent': '开始事件', + 'bpmn:IntermediateThrowEvent': '中间事件', + 'bpmn:Task': '任务', + 'bpmn:SendTask': '发送任务', + 'bpmn:ReceiveTask': '接收任务', + 'bpmn:UserTask': '用户任务', + 'bpmn:ManualTask': '手工任务', + 'bpmn:BusinessRuleTask': '业务规则任务', + 'bpmn:ServiceTask': '服务任务', + 'bpmn:ScriptTask': '脚本任务', + 'bpmn:EndEvent': '结束事件', + 'bpmn:SequenceFlow': '流程线', + 'bpmn:ExclusiveGateway': '互斥网关', + 'bpmn:ParallelGateway': '并行网关', + 'bpmn:InclusiveGateway': '相容网关', + 'bpmn:ComplexGateway': '复杂网关', + 'bpmn:EventBasedGateway': '事件网关' +}; + +export default { + 'Activate hand tool': '启动手动工具', + 'Activate lasso tool': '启动 Lasso 工具', + 'Activate create/remove space tool': '启动创建/删除空间工具', + 'Activate global connect tool': '启动全局连接工具', + 'Ad-hoc': 'Ad-hoc', + 'Add lane above': '在上方添加泳道', + 'Add lane below': '在下方添加泳道', + 'Business rule task': '规则任务', + 'Call activity': '引用流程', + 'Compensation end event': '结束补偿事件', + 'Compensation intermediate throw event': '中间补偿抛出事件', + 'Complex gateway': '复杂网关', + 'Conditional intermediate catch event': '中间条件捕获事件', + 'Conditional start event (non-interrupting)': '条件启动事件 (非中断)', + 'Conditional start event': '条件启动事件', + 'Connect using association': '文本关联', + 'Connect using sequence/message flow or association': '消息关联', + 'Change element': '更改元素', + 'Change type': '更改类型', + 'Create data object reference': '创建数据对象引用', + 'Create data store reference': '创建数据存储引用', + 'Create expanded sub-process': '创建可折叠子流程', + 'Create pool/participant': '创建池/参与者', + 'Collection': '集合', + 'Connect using data input association': '数据输入关联', + 'Data store reference': '数据存储引用', + 'Data object reference': '数据对象引用', + 'Divide into two lanes': '分成两个泳道', + 'Divide into three lanes': '分成三个泳道', + 'End event': '结束事件', + 'Error end event': '结束错误事件', + 'Escalation end event': '结束升级事件', + 'Escalation intermediate throw event': '中间升级抛出事件', + 'Event sub-process': '事件子流程', + 'Event-based gateway': '事件网关', + 'Exclusive gateway': '互斥网关', + 'Empty pool/participant (removes content)': '清空池/参与者 (删除内容)', + 'Inclusive gateway': '相容网关', + 'Intermediate throw event': '中间抛出事件', + 'Loop': '循环', + 'Link intermediate catch event': '中间链接捕获事件', + 'Link intermediate throw event': '中间链接抛出事件', + 'Manual task': '手动任务', + 'Message end event': '结束消息事件', + 'Message intermediate catch event': '中间消息捕获事件', + 'Message intermediate throw event': '中间消息抛出事件', + 'Message start event': '消息启动事件', + 'Parallel gateway': '并行网关', + 'Parallel multi-instance': '并行多实例', + 'Participant multiplicity': '参与者多重性', + 'Receive task': '接受任务', + 'Remove': '移除', + 'Script task': '脚本任务', + 'Send task': '发送任务', + 'Sequential multi-instance': '串行多实例', + 'Service task': '服务任务', + 'Signal end event': '结束信号事件', + 'Signal intermediate catch event': '中间信号捕获事件', + 'Signal intermediate throw event': '中间信号抛出事件', + 'Signal start event (non-interrupting)': '信号启动事件 (非中断)', + 'Signal start event': '信号启动事件', + 'Start event': '开始事件', + 'Sub-process (collapsed)': '可折叠子流程', + 'Sub-process (expanded)': '可展开子流程', + 'Sub rocess': '子流程', + 'Task': '任务', + 'Transaction': '事务', + 'Terminate end event': '终止边界事件', + 'Timer intermediate catch event': '中间定时捕获事件', + 'Timer start event (non-interrupting)': '定时启动事件 (非中断)', + 'Timer start event': '定时启动事件', + 'User task': '用户任务', + 'Create start event': '创建开始事件', + 'Create gateway': '创建网关', + 'Create intermediate/boundary event': '创建中间/边界事件', + 'Create end event': '创建结束事件', + 'Create group': '创建组', + 'Create startEvent': '开始节点', + 'Create endEvent': '结束节点', + 'Create exclusiveGateway': '互斥网关', + 'Create parallelGateway': '并行网关', + 'Create task': '任务节点', + 'Create userTask': '用户任务节点', + 'Condition type': '条件类型', + 'Append end event': '追加结束事件节点', + 'Append gateway': '追加网关节点', + 'Append task': '追加任务', + 'Append user task': '追加用户任务节点', + 'Append text annotation': '追加文本注释', + 'Append intermediate/boundary event': '追加中间或边界事件', + 'Append receive task': '追加接收任务节点', + 'Append message intermediate catch event': '追加中间消息捕获事件', + 'Append timer intermediate catch event': '追加中间定时捕获事件', + 'Append conditional intermediate catch event': '追加中间条件捕获事件', + 'Append signal intermediate catch event': '追加中间信号捕获事件' +}; diff --git a/src/components/BpmnDesign/assets/moddle/flowable.ts b/src/components/BpmnDesign/assets/moddle/flowable.ts new file mode 100644 index 0000000000000000000000000000000000000000..de959a6e6270a378f0f5afd22566836a903f5ad3 --- /dev/null +++ b/src/components/BpmnDesign/assets/moddle/flowable.ts @@ -0,0 +1,1250 @@ +export default { + 'name': 'Flowable', + 'uri': 'http://flowable.org/bpmn', + 'prefix': 'flowable', + 'xml': { + 'tagAlias': 'lowerCase' + }, + 'associations': [], + 'types': [ + { + 'name': 'flowable:extCandidateUsers', + 'isAbstract': true, + 'extends': [], + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['*'] + }, + 'properties': [ + { + 'name': 'body', + 'type': 'String', + 'isBody': true + } + ] + }, + { + 'name': 'flowable:extAssignee', + 'isAbstract': true, + 'extends': [], + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['*'] + }, + 'properties': [ + { + 'name': 'body', + 'type': 'String', + 'isBody': true + } + ] + }, + { + 'name': 'flowable:property', + 'superClass': ['Element'], + 'properties': [ + { + 'name': 'id', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'name', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'value', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'flowable:properties', + 'isAbstract': true, + 'extends': [], + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['*'] + }, + 'properties': [ + { + 'name': 'values', + 'type': 'flowable:property', + 'isMany': true + } + ] + }, + { + 'name': 'InOutBinding', + 'superClass': ['Element'], + 'isAbstract': true, + 'properties': [ + { + 'name': 'source', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'sourceExpression', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'target', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'businessKey', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'local', + 'isAttr': true, + 'type': 'Boolean', + 'default': false + }, + { + 'name': 'variables', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'In', + 'superClass': ['InOutBinding'], + 'meta': { + 'allowedIn': ['bpmn:CallActivity'] + } + }, + { + 'name': 'Out', + 'superClass': ['InOutBinding'], + 'meta': { + 'allowedIn': ['bpmn:CallActivity'] + } + }, + { + 'name': 'AsyncCapable', + 'isAbstract': true, + 'extends': ['bpmn:Activity', 'bpmn:Gateway', 'bpmn:Event'], + 'properties': [ + { + 'name': 'async', + 'isAttr': true, + 'type': 'Boolean', + 'default': false + }, + { + 'name': 'asyncBefore', + 'isAttr': true, + 'type': 'Boolean', + 'default': false + }, + { + 'name': 'asyncAfter', + 'isAttr': true, + 'type': 'Boolean', + 'default': false + }, + { + 'name': 'exclusive', + 'isAttr': true, + 'type': 'Boolean', + 'default': true + } + ] + }, + { + 'name': 'flowable:in', + 'superClass': ['Element'], + 'properties': [ + { + 'name': 'source', + 'type': 'string', + 'isAttr': true + }, + { + 'name': 'target', + 'type': 'string', + 'isAttr': true + } + ] + }, + { + 'name': 'flowable:out', + 'superClass': ['Element'], + 'properties': [ + { + 'name': 'source', + 'type': 'string', + 'isAttr': true + }, + { + 'name': 'target', + 'type': 'string', + 'isAttr': true + } + ] + }, + { + 'name': 'BoundaryEvent', + 'superClass': ['CatchEvent'], + 'properties': [ + { + 'name': 'cancelActivity', + 'default': true, + 'isAttr': true, + 'type': 'Boolean' + }, + { + 'name': 'attachedToRef', + 'type': 'Activity', + 'isAttr': true, + 'isReference': true + } + ] + }, + { + 'name': 'JobPriorized', + 'isAbstract': true, + 'extends': ['bpmn:Process', 'flowable:AsyncCapable'], + 'properties': [ + { + 'name': 'jobPriority', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'SignalEventDefinition', + 'isAbstract': true, + 'extends': ['bpmn:SignalEventDefinition'], + 'properties': [ + { + 'name': 'async', + 'isAttr': true, + 'type': 'Boolean', + 'default': false + } + ] + }, + { + 'name': 'ErrorEventDefinition', + 'isAbstract': true, + 'extends': ['bpmn:ErrorEventDefinition'], + 'properties': [ + { + 'name': 'errorCodeVariable', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'errorMessageVariable', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'Error', + 'isAbstract': true, + 'extends': ['bpmn:Error'], + 'properties': [ + { + 'name': 'flowable:errorMessage', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'PotentialStarter', + 'superClass': ['Element'], + 'properties': [ + { + 'name': 'resourceAssignmentExpression', + 'type': 'bpmn:ResourceAssignmentExpression' + } + ] + }, + { + 'name': 'UserTask', + 'isAbstract': true, + 'extends': ['bpmn:UserTask'], + 'properties': [ + { + 'name': 'timerEventDefinition', + 'type': 'Expression' + }, + { + 'name': 'multiInstanceLoopCharacteristics', + 'type': 'MultiInstanceLoopCharacteristics' + } + ] + }, + { + 'name': 'StartEvent', + 'isAbstract': true, + 'extends': ['bpmn:StartEvent'], + 'properties': [ + { + 'name': 'timerEventDefinition', + 'type': 'Expression' + } + ] + }, + { + 'name': 'FormSupported', + 'isAbstract': true, + 'extends': ['bpmn:StartEvent', 'bpmn:UserTask'], + 'properties': [ + { + 'name': 'formHandlerClass', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'formKey', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'TemplateSupported', + 'isAbstract': true, + 'extends': ['bpmn:Process', 'bpmn:FlowElement'], + 'properties': [ + { + 'name': 'modelerTemplate', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'Initiator', + 'isAbstract': true, + 'extends': ['bpmn:StartEvent'], + 'properties': [ + { + 'name': 'initiator', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'ScriptTask', + 'isAbstract': true, + 'extends': ['bpmn:ScriptTask'], + 'properties': [ + { + 'name': 'resultVariable', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'resource', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'Process', + 'isAbstract': true, + 'extends': ['bpmn:Process'], + 'properties': [ + { + 'name': 'candidateStarterGroups', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'candidateStarterUsers', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'versionTag', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'historyTimeToLive', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'isStartableInTasklist', + 'isAttr': true, + 'type': 'Boolean', + 'default': true + } + ] + }, + { + 'name': 'EscalationEventDefinition', + 'isAbstract': true, + 'extends': ['bpmn:EscalationEventDefinition'], + 'properties': [ + { + 'name': 'escalationCodeVariable', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'FormalExpression', + 'isAbstract': true, + 'extends': ['bpmn:FormalExpression'], + 'properties': [ + { + 'name': 'resource', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'Assignable', + 'extends': ['bpmn:UserTask'], + 'properties': [ + { + 'name': 'candidateGroups', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'dueDate', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'followUpDate', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'priority', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'CallActivity', + 'extends': ['bpmn:CallActivity'], + 'properties': [ + { + 'name': 'calledElementBinding', + 'isAttr': true, + 'type': 'String', + 'default': 'latest' + }, + { + 'name': 'calledElementVersion', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'calledElementVersionTag', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'calledElementTenantId', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'caseRef', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'caseBinding', + 'isAttr': true, + 'type': 'String', + 'default': 'latest' + }, + { + 'name': 'caseVersion', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'caseTenantId', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'variableMappingClass', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'variableMappingDelegateExpression', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'ServiceTaskLike', + 'extends': ['bpmn:ServiceTask', 'bpmn:BusinessRuleTask', 'bpmn:SendTask', 'bpmn:MessageEventDefinition'], + 'properties': [ + { + 'name': 'expression', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'class', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'delegateExpression', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'resultVariable', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'ExclusiveGateway', + 'isAbstract': true, + 'extends': ['bpmn:ExclusiveGateway'], + 'properties': [ + { + 'name': 'serviceClass', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'DmnCapable', + 'extends': ['bpmn:BusinessRuleTask'], + 'properties': [ + { + 'name': 'decisionRef', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'decisionRefBinding', + 'isAttr': true, + 'type': 'String', + 'default': 'latest' + }, + { + 'name': 'decisionRefVersion', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'mapDecisionResult', + 'isAttr': true, + 'type': 'String', + 'default': 'resultList' + }, + { + 'name': 'decisionRefTenantId', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'ExternalCapable', + 'extends': ['flowable:ServiceTaskLike'], + 'properties': [ + { + 'name': 'type', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'topic', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'TaskPriorized', + 'extends': ['bpmn:Process', 'flowable:ExternalCapable'], + 'properties': [ + { + 'name': 'taskPriority', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'Properties', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['*'] + }, + 'properties': [ + { + 'name': 'values', + 'type': 'Property', + 'isMany': true + } + ] + }, + { + 'name': 'Property', + 'superClass': ['Element'], + 'properties': [ + { + 'name': 'id', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'name', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'value', + 'type': 'String', + 'isAttr': true + } + ] + }, + { + 'name': 'Connector', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['flowable:ServiceTaskLike'] + }, + 'properties': [ + { + 'name': 'inputOutput', + 'type': 'InputOutput' + }, + { + 'name': 'connectorId', + 'type': 'String' + } + ] + }, + { + 'name': 'InputOutput', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['bpmn:FlowNode', 'flowable:Connector'] + }, + 'properties': [ + { + 'name': 'inputOutput', + 'type': 'InputOutput' + }, + { + 'name': 'connectorId', + 'type': 'String' + }, + { + 'name': 'inputParameters', + 'isMany': true, + 'type': 'InputParameter' + }, + { + 'name': 'outputParameters', + 'isMany': true, + 'type': 'OutputParameter' + } + ] + }, + { + 'name': 'InputOutputParameter', + 'properties': [ + { + 'name': 'name', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'value', + 'isBody': true, + 'type': 'String' + }, + { + 'name': 'definition', + 'type': 'InputOutputParameterDefinition' + } + ] + }, + { + 'name': 'InputOutputParameterDefinition', + 'isAbstract': true + }, + { + 'name': 'List', + 'superClass': ['InputOutputParameterDefinition'], + 'properties': [ + { + 'name': 'items', + 'isMany': true, + 'type': 'InputOutputParameterDefinition' + } + ] + }, + { + 'name': 'Map', + 'superClass': ['InputOutputParameterDefinition'], + 'properties': [ + { + 'name': 'entries', + 'isMany': true, + 'type': 'Entry' + } + ] + }, + { + 'name': 'Entry', + 'properties': [ + { + 'name': 'key', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'value', + 'isBody': true, + 'type': 'String' + }, + { + 'name': 'definition', + 'type': 'InputOutputParameterDefinition' + } + ] + }, + { + 'name': 'Value', + 'superClass': ['InputOutputParameterDefinition'], + 'properties': [ + { + 'name': 'id', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'name', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'value', + 'isBody': true, + 'type': 'String' + } + ] + }, + { + 'name': 'Script', + 'superClass': ['InputOutputParameterDefinition'], + 'properties': [ + { + 'name': 'scriptFormat', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'resource', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'value', + 'isBody': true, + 'type': 'String' + } + ] + }, + { + 'name': 'Field', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['flowable:ServiceTaskLike', 'flowable:ExecutionListener', 'flowable:TaskListener'] + }, + 'properties': [ + { + 'name': 'name', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'expression', + 'isAttr': true, + 'type': 'expression' + }, + { + 'name': 'string', + 'type': 'string' + }, + { + 'name': 'stringValue', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'string', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['flowable:Field'] + }, + 'properties': [ + { + 'name': 'body', + 'isBody': true, + 'type': 'String' + } + ] + }, + { + 'name': 'expression', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['flowable:Field'] + }, + 'properties': [ + { + 'name': 'body', + 'isBody': true, + 'type': 'String' + } + ] + }, + { + 'name': 'InputParameter', + 'superClass': ['InputOutputParameter'] + }, + { + 'name': 'OutputParameter', + 'superClass': ['InputOutputParameter'] + }, + { + 'name': 'Collectable', + 'isAbstract': true, + 'extends': ['bpmn:MultiInstanceLoopCharacteristics'], + 'superClass': ['flowable:AsyncCapable'], + 'properties': [ + { + 'name': 'collection', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'elementVariable', + 'isAttr': true, + 'type': 'String' + } + ] + }, + { + 'name': 'SequenceFlow', + 'superClass': ['FlowElement'], + 'properties': [ + { + 'name': 'isImmediate', + 'isAttr': true, + 'type': 'Boolean' + }, + { + 'name': 'conditionExpression', + 'type': 'Expression' + }, + { + 'name': 'sourceRef', + 'type': 'FlowNode', + 'isAttr': true, + 'isReference': true + }, + { + 'name': 'targetRef', + 'type': 'FlowNode', + 'isAttr': true, + 'isReference': true + } + ] + }, + { + 'name': 'MultiInstanceLoopCharacteristics', + 'superClass': ['LoopCharacteristics'], + 'properties': [ + { + 'name': 'isSequential', + 'default': false, + 'isAttr': true, + 'type': 'Boolean' + }, + { + 'name': 'behavior', + 'type': 'MultiInstanceBehavior', + 'default': 'All', + 'isAttr': true + }, + { + 'name': 'loopCardinality', + 'type': 'Expression', + 'xml': { + 'serialize': 'xsi:type' + } + }, + { + 'name': 'loopDataInputRef', + 'type': 'ItemAwareElement', + 'isReference': true + }, + { + 'name': 'loopDataOutputRef', + 'type': 'ItemAwareElement', + 'isReference': true + }, + { + 'name': 'inputDataItem', + 'type': 'DataInput', + 'xml': { + 'serialize': 'property' + } + }, + { + 'name': 'outputDataItem', + 'type': 'DataOutput', + 'xml': { + 'serialize': 'property' + } + }, + { + 'name': 'complexBehaviorDefinition', + 'type': 'ComplexBehaviorDefinition', + 'isMany': true + }, + { + 'name': 'completionCondition', + 'type': 'Expression', + 'xml': { + 'serialize': 'xsi:type' + } + }, + { + 'name': 'oneBehaviorEventRef', + 'type': 'EventDefinition', + 'isAttr': true, + 'isReference': true + }, + { + 'name': 'noneBehaviorEventRef', + 'type': 'EventDefinition', + 'isAttr': true, + 'isReference': true + } + ] + }, + { + 'name': 'FailedJobRetryTimeCycle', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['flowable:AsyncCapable', 'bpmn:MultiInstanceLoopCharacteristics'] + }, + 'properties': [ + { + 'name': 'body', + 'isBody': true, + 'type': 'String' + } + ] + }, + { + 'name': 'ExecutionListener', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': [ + 'bpmn:Task', + 'bpmn:ServiceTask', + 'bpmn:UserTask', + 'bpmn:BusinessRuleTask', + 'bpmn:ScriptTask', + 'bpmn:ReceiveTask', + 'bpmn:ManualTask', + 'bpmn:ExclusiveGateway', + 'bpmn:SequenceFlow', + 'bpmn:ParallelGateway', + 'bpmn:InclusiveGateway', + 'bpmn:EventBasedGateway', + 'bpmn:StartEvent', + 'bpmn:IntermediateCatchEvent', + 'bpmn:IntermediateThrowEvent', + 'bpmn:EndEvent', + 'bpmn:BoundaryEvent', + 'bpmn:CallActivity', + 'bpmn:SubProcess', + 'bpmn:Process' + ] + }, + 'properties': [ + { + 'name': 'expression', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'class', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'delegateExpression', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'event', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'script', + 'type': 'Script' + }, + { + 'name': 'fields', + 'type': 'Field', + 'isMany': true + } + ] + }, + { + 'name': 'TaskListener', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['bpmn:UserTask'] + }, + 'properties': [ + { + 'name': 'expression', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'class', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'delegateExpression', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'event', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'script', + 'type': 'Script' + }, + { + 'name': 'fields', + 'type': 'Field', + 'isMany': true + } + ] + }, + { + 'name': 'FormProperty', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['bpmn:StartEvent', 'bpmn:UserTask'] + }, + 'properties': [ + { + 'name': 'id', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'name', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'type', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'required', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'readable', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'writable', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'variable', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'expression', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'datePattern', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'default', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'values', + 'type': 'Value', + 'isMany': true + } + ] + }, + { + 'name': 'FormData', + 'superClass': ['Element'], + 'meta': { + 'allowedIn': ['bpmn:StartEvent', 'bpmn:UserTask'] + }, + 'properties': [ + { + 'name': 'fields', + 'type': 'FormField', + 'isMany': true + }, + { + 'name': 'businessKey', + 'type': 'String', + 'isAttr': true + } + ] + }, + { + 'name': 'FormField', + 'superClass': ['Element'], + 'properties': [ + { + 'name': 'id', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'label', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'type', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'datePattern', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'defaultValue', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'properties', + 'type': 'Properties' + }, + { + 'name': 'validation', + 'type': 'Validation' + }, + { + 'name': 'values', + 'type': 'Value', + 'isMany': true + } + ] + }, + { + 'name': 'Validation', + 'superClass': ['Element'], + 'properties': [ + { + 'name': 'constraints', + 'type': 'Constraint', + 'isMany': true + } + ] + }, + { + 'name': 'Constraint', + 'superClass': ['Element'], + 'properties': [ + { + 'name': 'name', + 'type': 'String', + 'isAttr': true + }, + { + 'name': 'config', + 'type': 'String', + 'isAttr': true + } + ] + }, + { + 'name': 'ConditionalEventDefinition', + 'isAbstract': true, + 'extends': ['bpmn:ConditionalEventDefinition'], + 'properties': [ + { + 'name': 'variableName', + 'isAttr': true, + 'type': 'String' + }, + { + 'name': 'variableEvent', + 'isAttr': true, + 'type': 'String' + } + ] + } + ], + 'emumerations': [] +}; diff --git a/src/components/BpmnDesign/assets/module/ContextPad/CustomContextPadProvider.ts b/src/components/BpmnDesign/assets/module/ContextPad/CustomContextPadProvider.ts new file mode 100644 index 0000000000000000000000000000000000000000..9f12ff24d1cf4c2a155faada59795abf4a4cc8a3 --- /dev/null +++ b/src/components/BpmnDesign/assets/module/ContextPad/CustomContextPadProvider.ts @@ -0,0 +1,138 @@ +import ContextPadProvider from 'bpmn-js/lib/features/context-pad/ContextPadProvider'; +import { Injector } from 'didi'; +import EventBus from 'diagram-js/lib/core/EventBus'; +import ContextPad from 'diagram-js/lib/features/context-pad/ContextPad'; +import Modeling from 'bpmn-js/lib/features/modeling/Modeling.js'; +import ElementFactory from 'bpmn-js/lib/features/modeling/ElementFactory'; +import Connect from 'diagram-js/lib/features/connect/Connect'; +import Create from 'diagram-js/lib/features/create/Create'; +import PopupMenu from 'diagram-js/lib/features/popup-menu/PopupMenu'; +import Canvas from 'diagram-js/lib/core/Canvas'; +import Rules from 'diagram-js/lib/features/rules/Rules'; +import { Element, Shape } from 'diagram-js/lib/model/Types'; +import BpmnFactory from 'bpmn-js/lib/features/modeling/BpmnFactory'; +import modeler from '@/store/modules/modeler'; + +// @Description: 增强元素连线事件 + +class CustomContextPadProvider extends ContextPadProvider { + private _contextPad: ContextPad; + private _modeling: Modeling; + private _elementFactory: ElementFactory; + private _autoPlace: any; + private _connect: Connect; + private _create: Create; + private _popupMenu: PopupMenu; + private _canvas: Canvas; + private _rules: Rules; + + constructor( + config: any, + injector: Injector, + eventBus: EventBus, + contextPad: ContextPad, + modeling: Modeling, + elementFactory: ElementFactory, + connect: Connect, + create: Create, + popupMenu: PopupMenu, + canvas: Canvas, + rules: Rules, + translate + ) { + // @ts-ignore + super(config, injector, eventBus, contextPad, modeling, elementFactory, connect, create, popupMenu, canvas, rules, translate); + + this._contextPad = contextPad; + this._modeling = modeling; + this._elementFactory = elementFactory; + this._connect = connect; + this._create = create; + this._popupMenu = popupMenu; + this._canvas = canvas; + this._rules = rules; + + this._autoPlace = injector.get('autoPlace', false); + } + + getContextPadEntries(element: Element) { + const actions: Record = {}; + + const appendUserTask = (event: Event, element: Shape) => { + const shape = this._elementFactory.createShape({ type: 'bpmn:UserTask' }); + this._create.start(event, shape, { + source: element + }); + }; + + const appendMultiInstanceUserTask = (event: Event, element: Shape) => { + const store = modeler(); + const bpmnFactory = store.getModeler().get('bpmnFactory') as BpmnFactory; + const businessObject = bpmnFactory.create('bpmn:UserTask', { + // name: '多实例用户任务', + isForCompensation: false + }); + businessObject.loopCharacteristics = bpmnFactory.create('bpmn:MultiInstanceLoopCharacteristics'); + // 创建 Shape + const shape = this._elementFactory.createShape({ + type: 'bpmn:UserTask', + businessObject: businessObject + }); + this._create.start(event, shape, { source: element }); + }; + + const appendTask = this._autoPlace + ? (event, element) => { + const bpmnFactory: BpmnFactory | undefined = modeler().getModeler().get('bpmnFactory'); + const businessObject = bpmnFactory.create('bpmn:UserTask', { + // name: '多实例用户任务',// 右键创建显示 + isForCompensation: false + }); + + // 创建多实例属性并分配给用户任务的 loopCharacteristics + businessObject.loopCharacteristics = bpmnFactory.create('bpmn:MultiInstanceLoopCharacteristics'); + + // 创建 Shape + const shape = this._elementFactory.createShape({ + type: 'bpmn:UserTask', + businessObject: businessObject + }); + + this._autoPlace.append(element, shape); + } + : appendMultiInstanceUserTask; + + const append = this._autoPlace + ? (event: Event, element: Shape) => { + const shape = this._elementFactory.createShape({ type: 'bpmn:UserTask' }); + this._autoPlace.append(element, shape); + } + : appendUserTask; + + // // 添加创建用户任务按钮 + actions['append.append-user-task'] = { + group: 'model', + className: 'bpmn-icon-user-task', + title: '用户任务', + action: { + dragstart: appendUserTask, + click: append + } + }; + + // 添加创建多实例用户任务按钮 + actions['append.append-multi-instance-user-task'] = { + group: 'model', + className: 'bpmn-icon-user', // 你可以使用多实例用户任务的图标 bpmn-icon-user bpmn-icon-user-task + title: '多实例用户任务', + action: { + dragstart: appendMultiInstanceUserTask, + click: appendTask + } + }; + + return actions; + } +} + +export default CustomContextPadProvider; diff --git a/src/components/BpmnDesign/assets/module/Palette/CustomPaletteProvider.ts b/src/components/BpmnDesign/assets/module/Palette/CustomPaletteProvider.ts new file mode 100644 index 0000000000000000000000000000000000000000..38f1cea46628ce3958d1bd448be8f5751b827c47 --- /dev/null +++ b/src/components/BpmnDesign/assets/module/Palette/CustomPaletteProvider.ts @@ -0,0 +1,119 @@ +import { assign } from 'min-dash'; +import PaletteProvider from 'bpmn-js/lib/features/palette/PaletteProvider'; +import ElementFactory from 'bpmn-js/lib/features/modeling/ElementFactory'; +import Create from 'diagram-js/lib/features/create/Create'; +import SpaceTool from 'diagram-js/lib/features/space-tool/SpaceTool'; +import LassoTool from 'diagram-js/lib/features/lasso-tool/LassoTool'; +import HandTool from 'diagram-js/lib/features/hand-tool/HandTool'; +import GlobalConnect from 'diagram-js/lib/features/global-connect/GlobalConnect'; +import Palette from 'diagram-js/lib/features/palette/Palette'; +import modeler from '@/store/modules/modeler'; +import BpmnFactory from 'bpmn-js/lib/features/modeling/BpmnFactory'; + +// @Description: 增强左侧面板 +class CustomPaletteProvider extends PaletteProvider { + private readonly _palette: Palette; + private readonly _create: Create; + private readonly _elementFactory: ElementFactory; + private readonly _spaceTool: SpaceTool; + private readonly _lassoTool: LassoTool; + private readonly _handTool: HandTool; + private readonly _globalConnect: GlobalConnect; + private readonly _translate: any; + + constructor(palette, create, elementFactory, spaceTool, lassoTool, handTool, globalConnect, translate) { + super( + palette, + create, + elementFactory, + spaceTool, + lassoTool, + handTool, + globalConnect, + translate + // 2000 + ); + this._palette = palette; + this._create = create; + this._elementFactory = elementFactory; + this._spaceTool = spaceTool; + this._lassoTool = lassoTool; + this._handTool = handTool; + this._globalConnect = globalConnect; + this._translate = translate; + } + + getPaletteEntries() { + const actions = {}, + create = this._create, + elementFactory = this._elementFactory, + translate = this._translate; + + function createAction(type: string, group: string, className: string, title: string, options?: object) { + function createListener(event) { + const shape = elementFactory.createShape(assign({ type: type }, options)); + if (options) { + !shape.businessObject.di && (shape.businessObject.di = {}); + shape.businessObject.di.isExpanded = (options as { [key: string]: any }).isExpanded; + } + create.start(event, shape, null); + } + const shortType = type.replace(/^bpmn:/, ''); + return { + group: group, + className: className, + title: title || translate('Create {type}', { type: shortType }), + action: { + dragstart: createListener, + click: createListener + } + }; + } + + function createMultiInstanceUserTask(event) { + const bpmnFactory: BpmnFactory | undefined = modeler().getBpmnFactory(); + // 创建一个 bpmn:UserTask + const userTask = bpmnFactory.create('bpmn:UserTask', { + // name: '多实例用户任务', // 在画板中显示字段 + isForCompensation: false + }); + // 将多实例属性分配给 bpmn:UserTask 的 loopCharacteristics + userTask.loopCharacteristics = bpmnFactory.create('bpmn:MultiInstanceLoopCharacteristics'); + const customUserTask = elementFactory.createShape({ + type: 'bpmn:UserTask', + businessObject: userTask // 分配创建的 userTask 到 businessObject + }); + create.start(event, customUserTask, {}); + } + + assign(actions, { + 'create.parallel-gateway': createAction('bpmn:ParallelGateway', 'gateway', 'bpmn-icon-gateway-parallel', '并行网关'), + 'create.event-base-gateway': createAction('bpmn:EventBasedGateway', 'gateway', 'bpmn-icon-gateway-eventbased', '事件网关'), + // 分组线 + 'gateway-separator': { + group: 'gateway', + separator: true + }, + 'create.user-task': createAction('bpmn:UserTask', 'activity', 'bpmn-icon-user-task', '创建用户任务'), + 'create.multi-instance-user-task': { + group: 'activity', + type: 'bpmn:UserTask', + className: 'bpmn-icon-user task-multi-instance', + title: '创建多实例用户任务', + action: { + click: createMultiInstanceUserTask, + dragstart: createMultiInstanceUserTask + } + }, + 'task-separator': { + group: 'activity', + separator: true + } + }); + return actions; + } +} + +CustomPaletteProvider['$inject'] = ['palette', 'create', 'elementFactory', 'spaceTool', 'lassoTool', 'handTool', 'globalConnect', 'translate']; + +export default CustomPaletteProvider; diff --git a/src/components/BpmnDesign/assets/module/Renderer/CustomRenderer.ts b/src/components/BpmnDesign/assets/module/Renderer/CustomRenderer.ts new file mode 100644 index 0000000000000000000000000000000000000000..6a4eb1a202d394d57c8871cb8f1066a3d399791f --- /dev/null +++ b/src/components/BpmnDesign/assets/module/Renderer/CustomRenderer.ts @@ -0,0 +1,56 @@ +import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer'; +import { + append as svgAppend, + attr as svgAttr, + create as svgCreate, + select as svgSelect, + selectAll as svgSelectAll, + clone as svgClone, + clear as svgClear, + remove as svgRemove +} from 'tiny-svg'; + +const HIGH_PRIORITY = 1500; +export default class CustomRenderer extends BaseRenderer { + bpmnRenderer: BaseRenderer; + modeling: any; + constructor(eventBus, bpmnRenderer, modeling) { + super(eventBus, HIGH_PRIORITY); + this.bpmnRenderer = bpmnRenderer; + this.modeling = modeling; + } + canRender(element) { + // ignore labels + return !element.labelTarget; + } + + /** + * 自定义节点图形 + * @param {*} parentNode 当前元素的svgNode + * @param {*} element + * @returns + */ + drawShape(parentNode, element) { + const shape = this.bpmnRenderer.drawShape(parentNode, element); + const { type, width, height } = element; + // 开始 填充绿色 + if (type === 'bpmn:StartEvent') { + svgAttr(shape, { fill: '#77DF6D' }); + return shape; + } + if (type === 'bpmn:EndEvent') { + svgAttr(shape, { fill: '#EE7B77' }); + return shape; + } + if (type === 'bpmn:UserTask') { + svgAttr(shape, { fill: '#A9C4F8' }); + return shape; + } + return shape; + } + + getShapePath(shape) { + return this.bpmnRenderer.getShapePath(shape); + } +} +CustomRenderer['$inject'] = ['eventBus', 'bpmnRenderer']; diff --git a/src/components/BpmnDesign/assets/module/Translate/index.ts b/src/components/BpmnDesign/assets/module/Translate/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..7324c77ce194129639e2954cc9e68860faa4d0ed --- /dev/null +++ b/src/components/BpmnDesign/assets/module/Translate/index.ts @@ -0,0 +1,15 @@ +import zh from '@/components/BpmnDesign/assets/lang/zh'; + +const customTranslate = (template: any, replacements: any) => { + replacements = replacements || {}; + template = zh[template] || template; + return template.replace(/{([^}]+)}/g, function (_: any, key: any) { + return replacements[key] || '{' + key + '}'; + }); +}; + +export const translateModule = { + translate: ['value', customTranslate] +}; + +export default translateModule; diff --git a/src/components/BpmnDesign/assets/module/index.ts b/src/components/BpmnDesign/assets/module/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..55f6b9fd6aee730dc8411e845a54e2adb594cce7 --- /dev/null +++ b/src/components/BpmnDesign/assets/module/index.ts @@ -0,0 +1,17 @@ +// 翻译模块 +import TranslationModule from './Translate'; +import { ModuleDeclaration } from 'didi'; +import CustomPaletteProvider from './Palette/CustomPaletteProvider'; +import CustomRenderer from './Renderer/CustomRenderer'; +import CustomContextPadProvider from './ContextPad/CustomContextPadProvider'; + +const Module: ModuleDeclaration[] = [ + { + __init__: ['customPaletteProvider', 'customContextPadProvider', 'customRenderer'], + customPaletteProvider: ['type', CustomPaletteProvider], + customRenderer: ['type', CustomRenderer], + customContextPadProvider: ['type', CustomContextPadProvider] + }, + TranslationModule +]; +export default Module; diff --git a/src/components/BpmnDesign/assets/showConfig.ts b/src/components/BpmnDesign/assets/showConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..853eb3587edbaf812b9c53eb452ed195cbe6f92a --- /dev/null +++ b/src/components/BpmnDesign/assets/showConfig.ts @@ -0,0 +1,50 @@ +export default { + 'bpmn:EndEvent': {}, + 'bpmn:StartEvent': { + initiator: true, + formKey: true + }, + 'bpmn:UserTask': { + allocationType: true, + specifyDesc: true, + multipleUserAuditType: true, + async: true, + priority: true, + skipExpression: true, + dueDate: true, + taskListener: true, + executionListener: true + }, + 'bpmn:ServiceTask': { + async: true, + skipExpression: true, + isForCompensation: true, + triggerable: true, + class: true + }, + 'bpmn:ScriptTask': { + async: true, + isForCompensation: true, + autoStoreVariables: true + }, + 'bpmn:ManualTask': { + async: true, + isForCompensation: true + }, + 'bpmn:ReceiveTask': { + async: true, + isForCompensation: true + }, + 'bpmn:SendTask': { + async: true, + isForCompensation: true + }, + 'bpmn:BusinessRuleTask': { + async: true, + isForCompensation: true, + ruleVariablesInput: true, + rules: true, + resultVariable: true, + exclude: true + } +}; diff --git a/src/components/BpmnDesign/assets/style/index.scss b/src/components/BpmnDesign/assets/style/index.scss new file mode 100644 index 0000000000000000000000000000000000000000..d3ce37978078430af819e598040f4306110591b5 --- /dev/null +++ b/src/components/BpmnDesign/assets/style/index.scss @@ -0,0 +1,230 @@ +.djs-palette { + width: 300px; + + .bpmn-icon-hand-tool:hover { + &:after { + content: '启动手动工具'; + position: absolute; + left: 45px; + width: 120px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-lasso-tool:hover { + &:after { + content: '启动套索工具'; + position: absolute; + left: 100px; + width: 120px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-space-tool:hover { + &:after { + content: '启动创建/删除空间工具'; + position: absolute; + left: 45px; + width: 170px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-connection-multi:hover { + &:after { + content: '启动全局连接工具'; + position: absolute; + left: 100px; + width: 140px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-start-event-none:hover { + &:after { + content: '创建开始事件'; + position: absolute; + left: 45px; + width: 120px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-intermediate-event-none:hover { + &:after { + content: '创建中间/边界事件'; + position: absolute; + left: 100px; + width: 140px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-end-event-none:hover { + &:after { + content: '创建结束事件'; + position: absolute; + left: 45px; + width: 120px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-gateway-none:hover { + &:after { + content: '创建网关'; + position: absolute; + left: 100px; + width: 90px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-gateway-parallel:hover { + &:after { + content: '创建并行网关'; + position: absolute; + left: 45px; + width: 120px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-gateway-eventbased:hover { + &:after { + content: '创建事件网关'; + position: absolute; + left: 100px; + width: 120px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-task:hover { + &:after { + content: '创建任务'; + position: absolute; + left: 45px; + width: 80px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-subprocess-expanded:hover { + &:after { + content: '创建可折叠子流程'; + position: absolute; + left: 100px; + width: 140px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-user-task:hover { + &:after { + content: '创建用户任务'; + position: absolute; + left: 45px; + width: 120px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + + .task-multi-instance:hover { + &:after { + content: '创建多实例用户任务'; + position: absolute; + left: 100px; + width: 160px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } + .bpmn-icon-participant:hover { + &:after { + content: '创建泳池/泳道'; + position: absolute; + left: 45px; + width: 120px; + font-size: 15px; + font-weight: bold; + color: #3a84de; + border-radius: 2px; + border: 1px solid #cccccc; + background-color: #fafafa; + opacity: 0.8; + } + } +} diff --git a/src/components/BpmnDesign/hooks/usePanel.ts b/src/components/BpmnDesign/hooks/usePanel.ts new file mode 100644 index 0000000000000000000000000000000000000000..0dbc3f345510dcceac429a1b769571076b7e0992 --- /dev/null +++ b/src/components/BpmnDesign/hooks/usePanel.ts @@ -0,0 +1,132 @@ +import showConfig from '@/components/BpmnDesign/assets/showConfig'; +import { ModdleElement } from 'bpmn'; +import useModelerStore from '@/store/modules/modeler'; +interface Options { + element: ModdleElement; +} + +export default (ops: Options) => { + const { element } = ops; + const { getModeling, getModdle } = useModelerStore(); + const modeling = getModeling(); + const moddle = getModdle(); + + /** + * 当前节点类型 + */ + const elementType = computed(() => { + const bizObj = element.businessObject; + return bizObj.eventDefinitions ? bizObj.eventDefinitions[0].$type : bizObj.$type; + }); + + /** + * 用于控制面板字段显示与隐藏的配置 + */ + const config = computed(() => showConfig[elementType.value] || {}); + + /** + * 创建一个节点 + * @param elementType 节点类型 + * @param properties 属性 + * @param parent 父节点 + */ + const createModdleElement = (elementType: string, properties: any, parent: ModdleElement) => { + const element = moddle.create(elementType, properties); + parent && (element.$parent = parent); + return element; + }; + + /** + * 获取扩展属性,如果不存在会自动创建 + */ + const getExtensionElements = (create = true) => { + let extensionElements = element.businessObject.get('extensionElements'); + if (!extensionElements && create) { + extensionElements = createModdleElement('bpmn:ExtensionElements', { values: [] }, element.businessObject); + modeling.updateModdleProperties(element, element.businessObject, { extensionElements }); + } + return extensionElements; + }; + + /** + * 获取extensionElements下的properties + * @param extensionElements 可选参数,默认获取当前Element下的extensionElements下的Properties + */ + const getPropertiesElements = (extensionElements?: ModdleElement) => { + if (!extensionElements) { + extensionElements = getExtensionElements(); + } + let propertiesElements = extensionElements.values.find((item) => item.$type === 'flowable:properties'); + if (!propertiesElements) { + propertiesElements = createModdleElement('flowable:properties', { values: [] }, extensionElements); + modeling.updateModdleProperties(element, extensionElements, { + values: [...extensionElements.get<[]>('values'), propertiesElements] + }); + } + return propertiesElements; + }; + + /** + * 更新节点属性 + * @param properties 属性值 + */ + const updateProperties = (properties: any) => { + modeling.updateProperties(element, properties); + }; + + /** + * 更新节点信息 + * @param updateElement 需要更新的节点 + * @param properties 属性 + */ + const updateModdleProperties = (updateElement, properties: any) => { + modeling.updateModdleProperties(element, updateElement, properties); + }; + + /** + * 更新Property属性 + * @param name key值 + * @param value 值 + */ + const updateProperty = (name: string, value: string) => { + const propertiesElements = getPropertiesElements(); + + let propertyElements = propertiesElements.values.find((item) => item.name === name); + if (!propertyElements) { + propertyElements = createModdleElement('flowable:property', { name: name, value: value }, propertiesElements); + modeling.updateModdleProperties(element, propertiesElements, { + values: [...propertiesElements.get('values'), propertyElements] + }); + } else { + propertyElements.name = name; + propertyElements.value = value; + } + return propertyElements; + }; + + const idChange = (newVal: string) => { + if (newVal) { + updateProperties({ id: newVal }); + } + }; + const nameChange = (newVal: string) => { + if (newVal) { + updateProperties({ name: newVal }); + } + }; + return { + elementType, + showConfig: config, + + updateProperties, + updateProperty, + updateModdleProperties, + + createModdleElement, + idChange, + nameChange, + + getExtensionElements, + getPropertiesElements + }; +}; diff --git a/src/components/BpmnDesign/hooks/useParseElement.ts b/src/components/BpmnDesign/hooks/useParseElement.ts new file mode 100644 index 0000000000000000000000000000000000000000..a5a255d6d776731628dc52c37627ed279cf39cc6 --- /dev/null +++ b/src/components/BpmnDesign/hooks/useParseElement.ts @@ -0,0 +1,34 @@ +import { ModdleElement } from 'bpmn'; + +interface Options { + element: ModdleElement; +} + +interface Data { + id: string; +} + +export default (ops: Options) => { + const { element } = ops; + + const parseData = (): T => { + const result = { + ...element.businessObject, + ...element.businessObject.$attrs + }; + + // 移除flowable前缀,格式化数组 + for (const key in result) { + if (key.indexOf('flowable:') === 0) { + const newKey = key.replace('flowable:', ''); + result[newKey] = result[key]; + delete result[key]; + } + } + return { ...result } as T; + }; + + return { + parseData + }; +}; diff --git a/src/components/BpmnDesign/index.vue b/src/components/BpmnDesign/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..1568a3e41d58863ca9e0ae64baa616d5409390c3 --- /dev/null +++ b/src/components/BpmnDesign/index.vue @@ -0,0 +1,409 @@ + + + + + diff --git a/src/components/BpmnDesign/panel/GatewayPanel.vue b/src/components/BpmnDesign/panel/GatewayPanel.vue new file mode 100644 index 0000000000000000000000000000000000000000..46c67b589f2c633e92b741f6b86d15200c6378bd --- /dev/null +++ b/src/components/BpmnDesign/panel/GatewayPanel.vue @@ -0,0 +1,68 @@ + + + + diff --git a/src/components/BpmnDesign/panel/ProcessPanel.vue b/src/components/BpmnDesign/panel/ProcessPanel.vue new file mode 100644 index 0000000000000000000000000000000000000000..01e8f89d710381b4c8a10bc9b0fcffe4b8755da4 --- /dev/null +++ b/src/components/BpmnDesign/panel/ProcessPanel.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/BpmnDesign/panel/SequenceFlowPanel.vue b/src/components/BpmnDesign/panel/SequenceFlowPanel.vue new file mode 100644 index 0000000000000000000000000000000000000000..88ce3504d570b45de2a293e42ab158305d1e5c32 --- /dev/null +++ b/src/components/BpmnDesign/panel/SequenceFlowPanel.vue @@ -0,0 +1,94 @@ + + + + diff --git a/src/components/BpmnDesign/panel/StartEndPanel.vue b/src/components/BpmnDesign/panel/StartEndPanel.vue new file mode 100644 index 0000000000000000000000000000000000000000..9cd0efc41b71df160c45701bb61b9af1debb9c44 --- /dev/null +++ b/src/components/BpmnDesign/panel/StartEndPanel.vue @@ -0,0 +1,40 @@ + + + + diff --git a/src/components/BpmnDesign/panel/TaskPanel.vue b/src/components/BpmnDesign/panel/TaskPanel.vue new file mode 100644 index 0000000000000000000000000000000000000000..267ad30739116eb724eaf2619e3dd47be3162142 --- /dev/null +++ b/src/components/BpmnDesign/panel/TaskPanel.vue @@ -0,0 +1,467 @@ + + + + diff --git a/src/components/BpmnDesign/panel/index.vue b/src/components/BpmnDesign/panel/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..aa39af1f67fafe0f021a22270f569104f2676c78 --- /dev/null +++ b/src/components/BpmnDesign/panel/index.vue @@ -0,0 +1,104 @@ + + + + diff --git a/src/components/BpmnDesign/panel/property/DueDate.vue b/src/components/BpmnDesign/panel/property/DueDate.vue new file mode 100644 index 0000000000000000000000000000000000000000..4825a1ccd151e39f99db06e4819557ab58e3a388 --- /dev/null +++ b/src/components/BpmnDesign/panel/property/DueDate.vue @@ -0,0 +1,252 @@ + + + diff --git a/src/components/BpmnDesign/panel/property/ExecutionListener.vue b/src/components/BpmnDesign/panel/property/ExecutionListener.vue new file mode 100644 index 0000000000000000000000000000000000000000..ecd50345c3d4624e108bdabe6bec7ce37acab12c --- /dev/null +++ b/src/components/BpmnDesign/panel/property/ExecutionListener.vue @@ -0,0 +1,305 @@ + + + + diff --git a/src/components/BpmnDesign/panel/property/ListenerParam.vue b/src/components/BpmnDesign/panel/property/ListenerParam.vue new file mode 100644 index 0000000000000000000000000000000000000000..334249bdb0fdc9361cfebf9dc2f56526cbb2c471 --- /dev/null +++ b/src/components/BpmnDesign/panel/property/ListenerParam.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/src/components/BpmnDesign/panel/property/TaskListener.vue b/src/components/BpmnDesign/panel/property/TaskListener.vue new file mode 100644 index 0000000000000000000000000000000000000000..f90c9a8768084540658052673c44ab42c00cc392 --- /dev/null +++ b/src/components/BpmnDesign/panel/property/TaskListener.vue @@ -0,0 +1,307 @@ + + + + diff --git a/src/components/Process/approvalRecord.vue b/src/components/Process/approvalRecord.vue new file mode 100644 index 0000000000000000000000000000000000000000..d06e7effe09001cd839de84fa2299a8114242ea8 --- /dev/null +++ b/src/components/Process/approvalRecord.vue @@ -0,0 +1,162 @@ + + + diff --git a/src/components/Process/multiInstance-user.vue b/src/components/Process/multiInstance-user.vue new file mode 100644 index 0000000000000000000000000000000000000000..96fa21f21fb24b77d56a0294db4e6f69a7ce416e --- /dev/null +++ b/src/components/Process/multiInstance-user.vue @@ -0,0 +1,362 @@ + + + \ No newline at end of file diff --git a/src/components/Process/submitVerify.vue b/src/components/Process/submitVerify.vue new file mode 100644 index 0000000000000000000000000000000000000000..b52854f5d7f43f2c9846f5d5b81c1b9d38a4c34c --- /dev/null +++ b/src/components/Process/submitVerify.vue @@ -0,0 +1,165 @@ + + + diff --git a/src/components/Process/sys-user.vue b/src/components/Process/sys-user.vue new file mode 100644 index 0000000000000000000000000000000000000000..dc100f3f4b6fcae35408981edd0f2b9840c58665 --- /dev/null +++ b/src/components/Process/sys-user.vue @@ -0,0 +1,301 @@ + + + diff --git a/src/components/RoleSelect/index.vue b/src/components/RoleSelect/index.vue index a9a07d3bb3e0541b91b971103e377faf7da61e5e..ec5bcc71fae8df7e7c87e54173eaef0b0c85dfa8 100644 --- a/src/components/RoleSelect/index.vue +++ b/src/components/RoleSelect/index.vue @@ -196,4 +196,4 @@ defineExpose({ onMounted(() => { getList(); }); - + \ No newline at end of file diff --git a/src/components/UserSelect/index.vue b/src/components/UserSelect/index.vue index 6a68f924abc917dee3bf9b269ca514510e401875..f2ef014ee3b6c3e6c97518a656f4d80bc8677ec0 100644 --- a/src/components/UserSelect/index.vue +++ b/src/components/UserSelect/index.vue @@ -258,4 +258,4 @@ defineExpose({ }); - + \ No newline at end of file diff --git a/src/directive/common/copyText.ts b/src/directive/common/copyText.ts index b6805f84173ea03551e9d40429351067244cf48d..0e605d31f0df0e092f6835e9f0cb269ac80e6692 100644 --- a/src/directive/common/copyText.ts +++ b/src/directive/common/copyText.ts @@ -2,9 +2,10 @@ * v-copyText 复制文本内容 * Copyright (c) 2022 ruoyi */ +import { DirectiveBinding } from 'vue'; export default { - beforeMount(el: any, { value, arg }: any) { + beforeMount(el: any, { value, arg }: DirectiveBinding) { if (arg === 'callback') { el.$copyCallback = value; } else { diff --git a/src/enums/bpmn/IndexEnums.ts b/src/enums/bpmn/IndexEnums.ts new file mode 100644 index 0000000000000000000000000000000000000000..8c398233c683a377584a3a2485713b28f1149d7b --- /dev/null +++ b/src/enums/bpmn/IndexEnums.ts @@ -0,0 +1,17 @@ +export enum AllocationTypeEnum { + USER = 'user', + CANDIDATE = 'candidate', + YOURSELF = 'yourself', + SPECIFY = 'specify' +} + +export enum SpecifyDescEnum { + SPECIFY_MULTIPLE = 'specifyMultiple', + SPECIFY_SINGLE = 'specifySingle' +} + +export enum MultiInstanceTypeEnum { + SERIAL = 'serial', + PARALLEL = 'parallel', + NONE = 'none' +} diff --git a/src/hooks/useDialog.ts b/src/hooks/useDialog.ts index 547f199766d142e66f41b07eda589cf535e39582..68440bf2eca51b6d82e67ee4428f7981ea86eb10 100644 --- a/src/hooks/useDialog.ts +++ b/src/hooks/useDialog.ts @@ -28,4 +28,4 @@ export default (ops?: Options): Return => { openDialog, closeDialog }; -}; +}; \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 29a5ee572391af8fb61321490258f9612b64df45..592de58b25b55bca622e801e07c5712668d82958 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,6 +15,12 @@ import directive from './directive'; // 注册插件 import plugins from './plugins/index'; // plugins +// 高亮组件 +// import 'highlight.js/styles/a11y-light.css'; +import 'highlight.js/styles/atom-one-dark.css'; +import 'highlight.js/lib/common'; +import HighLight from '@highlightjs/vue-plugin'; + // svg图标 import 'virtual:svg-icons-register'; import ElementIcons from '@/plugins/svgicon'; @@ -38,6 +44,7 @@ ElDialog.props.closeOnClickModal.default = false; const app = createApp(App); +app.use(HighLight); app.use(ElementIcons); app.use(router); app.use(store); diff --git a/src/store/modules/modeler.ts b/src/store/modules/modeler.ts new file mode 100644 index 0000000000000000000000000000000000000000..7b19c1a7277975a9f3c153e68b49aaa22d0308cb --- /dev/null +++ b/src/store/modules/modeler.ts @@ -0,0 +1,76 @@ +import { Modeler, Modeling, Canvas, ElementRegistry, Moddle, BpmnFactory } from 'bpmn'; + +type ModelerStore = { + modeler: Modeler | undefined; + moddle: Moddle | undefined; + modeling: Modeling | undefined; + canvas: Canvas | undefined; + elementRegistry: ElementRegistry | undefined; + bpmnFactory: BpmnFactory | undefined; + // 流程定义根节点信息 + procDefId: string | undefined; + procDefName: string | undefined; +}; + +const defaultState: ModelerStore = { + modeler: undefined, + moddle: undefined, + modeling: undefined, + canvas: undefined, + elementRegistry: undefined, + bpmnFactory: undefined, + procDefId: undefined, + procDefName: undefined +}; +export const useModelerStore = defineStore('modeler', () => { + let modeler = defaultState.modeler; + let moddle = defaultState.moddle; + let modeling = defaultState.modeling; + let canvas = defaultState.canvas; + let elementRegistry = defaultState.elementRegistry; + let bpmnFactory = defaultState.bpmnFactory; + const procDefId = ref(defaultState.procDefId); + const procDefName = ref(defaultState.procDefName); + + const getModeler = () => modeler; + const getModdle = () => moddle; + const getModeling = (): Modeling | undefined => modeling; + const getCanvas = (): Canvas | undefined => canvas; + const getElRegistry = (): ElementRegistry | undefined => elementRegistry; + const getBpmnFactory = (): BpmnFactory | undefined => bpmnFactory; + const getProcDefId = (): string | undefined => procDefId.value; + const getProcDefName = (): string | undefined => procDefName.value; + + // 设置根节点 + const setModeler = (modelers: Modeler | undefined) => { + if (modelers) { + modeler = modelers; + modeling = modelers.get('modeling'); + moddle = modelers.get('moddle'); + canvas = modelers.get('canvas'); + bpmnFactory = modelers.get('bpmnFactory'); + elementRegistry = modelers.get('elementRegistry'); + } else { + modeling = moddle = canvas = elementRegistry = bpmnFactory = undefined; + } + }; + // 设置流程定义根节点信息 + const setProcDef = (modeler: Modeler | undefined) => { + procDefId.value = modeler.get('canvas').getRootElement().businessObject.get('id'); + procDefName.value = modeler.get('canvas').getRootElement().businessObject.get('name'); + }; + + return { + getModeler, + getModdle, + getModeling, + getCanvas, + getElRegistry, + getBpmnFactory, + getProcDefId, + getProcDefName, + setModeler, + setProcDef + }; +}); +export default useModelerStore; diff --git a/src/types/bpmn/editor/global.d.ts b/src/types/bpmn/editor/global.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..1b9a634329c43695c413827346b9bd6fdd2ce7dd --- /dev/null +++ b/src/types/bpmn/editor/global.d.ts @@ -0,0 +1,13 @@ +import { MessageApiInjection } from 'naive-ui/lib/message/src/MessageProvider'; + +declare global { + interface Window { + bpmnInstances: any; + __messageBox: MessageApiInjection; + URL: any; + } +} + +declare interface Window { + bpmnInstances: any; +} diff --git a/src/types/bpmn/index.d.ts b/src/types/bpmn/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8e8d15c9c4dfc6f4174fb3da99603be31a4e173 --- /dev/null +++ b/src/types/bpmn/index.d.ts @@ -0,0 +1,15 @@ +declare module 'bpmn' { + import type modeler from 'bpmn-js/lib/Modeler'; + import type modeling from 'bpmn-js/lib/features/modeling/Modeling'; + import type canvas from 'diagram-js/lib/core/Canvas'; + import type elementRegistry from 'diagram-js/lib/core/ElementRegistry'; + import type bpmnFactory from 'bpmn-js/lib/features/modeling/BpmnFactory'; + + export type Modeler = modeler; + export type Modeling = modeling; + export type Canvas = canvas; + export type ElementRegistry = elementRegistry; + export type Moddle = import('moddle').Moddle; + export type ModdleElement = import('moddle').ModdleElement; + export type BpmnFactory = bpmnFactory; +} diff --git a/src/types/bpmn/moddle.d.ts b/src/types/bpmn/moddle.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..1ed79335f16a568b4ce09f7bc1da9b5503f00034 --- /dev/null +++ b/src/types/bpmn/moddle.d.ts @@ -0,0 +1,37 @@ +declare module 'moddle' { + import type { Element as element } from 'bpmn-js/lib/model/Types'; + + export type Element = { + get(name: string): T; + + set(name: string, value: any): void; + } & element; + + export interface ModdleElement extends Element { + $model: Moddle; + readonly $type: string; + $attrs: object | {}; + $parent: any; + businessObject: ModdleElement; + type: string; + + [field: string]: any; + + hasType(element: ModdleElement, type?: string): boolean; + } + + export interface Package { + name: string; + prefix: string; + } + + export interface Moddle { + typeCache: Record; + + getPackage: typeof Registry.prototype.getPackage; + + getPackages: typeof Registry.prototype.getPackages; + + create(type: string, attrs?: any): ModdleElement; + } +} diff --git a/src/types/bpmn/panel.d.ts b/src/types/bpmn/panel.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..0d0cac4538f811b26ba5002f336e077ba0acbc7a --- /dev/null +++ b/src/types/bpmn/panel.d.ts @@ -0,0 +1,75 @@ +declare module 'bpmnDesign' { + import { AllocationTypeEnum, SpecifyDescEnum, MultiInstanceTypeEnum } from '@/enums/bpmn/IndexEnums'; + + export interface ParamVO { + type: string; + name: string; + value: string; + } + + export interface TaskListenerVO { + event: string; + type: string; + name: string; + className: string; + params: ParamVO[]; + } + + export interface ExecutionListenerVO { + event: string; + type: string; + className: string; + params: ParamVO[]; + } + + interface BasePanel { + id: string; + name: string; + } + export interface ProcessPanel extends BasePanel {} + + export interface TaskPanel extends BasePanel { + allocationType: AllocationTypeEnum; + specifyDesc: SpecifyDescEnum; + multiInstanceType: MultiInstanceTypeEnum; + async?: boolean; + priority?: number; + skipExpression?: string; + isForCompensation?: boolean; + triggerServiceTask?: boolean; + autoStoreVariables?: boolean; + ruleVariablesInput?: string; + excludeTaskListener?: boolean; + exclude?: boolean; + class?: string; + dueDate?: string; + fixedAssignee?: string; + + candidateUsers?: string; + assignee?: string; + candidateGroups?: string; + collection?: string; + elementVariable?: string; + completionCondition?: string; + isSequential?: boolean; + + loopCharacteristics?: { + collection: string; + elementVariable: string; + isSequential: boolean; + completionCondition: { + body: string; + }; + }; + } + + export interface StartEndPanel extends BasePanel {} + export interface GatewayPanel extends BasePanel {} + export interface SequenceFlowPanel extends BasePanel { + conditionExpression: { + body: string; + }; + conditionExpressionValue: string; + skipExpression: string; + } +} diff --git a/src/views/workflow/category/index.vue b/src/views/workflow/category/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..3fa430776cfd9e108b5a3eb9ff6b0de59297fb76 --- /dev/null +++ b/src/views/workflow/category/index.vue @@ -0,0 +1,263 @@ + + + diff --git a/src/views/workflow/leave/index.vue b/src/views/workflow/leave/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..c7550b25de21824d6796f4d94fe80840b7c6d9d5 --- /dev/null +++ b/src/views/workflow/leave/index.vue @@ -0,0 +1,381 @@ + + + diff --git a/src/views/workflow/model/design.vue b/src/views/workflow/model/design.vue new file mode 100644 index 0000000000000000000000000000000000000000..0f6b118d34ddcf3bd0a1920f9bf7ee6aa75b4648 --- /dev/null +++ b/src/views/workflow/model/design.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/src/views/workflow/model/index.vue b/src/views/workflow/model/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..93cd675acf41d22a0be7d4e23ca86e317a48dfba --- /dev/null +++ b/src/views/workflow/model/index.vue @@ -0,0 +1,360 @@ + + + diff --git a/src/views/workflow/processDefinition/components/processPreview.vue b/src/views/workflow/processDefinition/components/processPreview.vue new file mode 100644 index 0000000000000000000000000000000000000000..817552a37cde5201733e1ae0b1848ec44c88ffe6 --- /dev/null +++ b/src/views/workflow/processDefinition/components/processPreview.vue @@ -0,0 +1,57 @@ + + + + diff --git a/src/views/workflow/processDefinition/index.vue b/src/views/workflow/processDefinition/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..3843573425dfd42332025e98e384a15d50e60918 --- /dev/null +++ b/src/views/workflow/processDefinition/index.vue @@ -0,0 +1,403 @@ + + + diff --git a/src/views/workflow/processInstance/index.vue b/src/views/workflow/processInstance/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..98303663d4351bc962be969f1bff7cb77305ff66 --- /dev/null +++ b/src/views/workflow/processInstance/index.vue @@ -0,0 +1,363 @@ + + + diff --git a/src/views/workflow/task/allTaskWaiting.vue b/src/views/workflow/task/allTaskWaiting.vue new file mode 100644 index 0000000000000000000000000000000000000000..ef1c45e3cb43713f655203cd6c7fd7e927a0075c --- /dev/null +++ b/src/views/workflow/task/allTaskWaiting.vue @@ -0,0 +1,237 @@ + + + diff --git a/src/views/workflow/task/myDocument.vue b/src/views/workflow/task/myDocument.vue new file mode 100644 index 0000000000000000000000000000000000000000..1e1d2a0123a3b6a60900c4cc6c2f1f41c2ee5c10 --- /dev/null +++ b/src/views/workflow/task/myDocument.vue @@ -0,0 +1,256 @@ + + + diff --git a/src/views/workflow/task/taskCopyList.vue b/src/views/workflow/task/taskCopyList.vue new file mode 100644 index 0000000000000000000000000000000000000000..6348024cf833d0c1e9ac7e81d0d449292a6d8593 --- /dev/null +++ b/src/views/workflow/task/taskCopyList.vue @@ -0,0 +1,141 @@ + + + diff --git a/src/views/workflow/task/taskFinish.vue b/src/views/workflow/task/taskFinish.vue new file mode 100644 index 0000000000000000000000000000000000000000..3e8adbaebce05d9a1db2040b4c662c727138297e --- /dev/null +++ b/src/views/workflow/task/taskFinish.vue @@ -0,0 +1,128 @@ + + + diff --git a/src/views/workflow/task/taskWaiting.vue b/src/views/workflow/task/taskWaiting.vue new file mode 100644 index 0000000000000000000000000000000000000000..c3f34aa735c4faf4e59987ae4385b3d92014cfab --- /dev/null +++ b/src/views/workflow/task/taskWaiting.vue @@ -0,0 +1,181 @@ + + + diff --git a/vite.config.ts b/vite.config.ts index 01da6687fb428a75cd977543724072da03a6d99f..99ea8e8132e8d6f2ebcf322d151f76ea75020e77 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -65,7 +65,24 @@ export default defineConfig(({ mode, command }: ConfigEnv): UserConfig => { 'echarts', 'vue-i18n', '@vueup/vue-quill', + 'bpmn-js/lib/Modeler.js', + 'bpmn-js-properties-panel', + 'min-dash', + 'bpmn-js/lib/features/palette/PaletteProvider', + 'bpmn-js/lib/features/context-pad/ContextPadProvider', + 'diagram-js/lib/draw/BaseRenderer', + 'tiny-svg', + 'element-plus/es/components/collapse-item/style/css', + 'element-plus/es/components/collapse/style/css', + 'element-plus/es/components/space/style/css', + 'element-plus/es/components/container/style/css', + 'element-plus/es/components/aside/style/css', + 'element-plus/es/components/main/style/css', + 'element-plus/es/components/header/style/css', + 'element-plus/es/components/button-group/style/css', + 'element-plus/es/components/radio-button/style/css', + 'element-plus/es/components/checkbox-group/style/css', 'element-plus/es/components/form/style/css', 'element-plus/es/components/form-item/style/css', 'element-plus/es/components/button/style/css',