From 22e9eb2add3479a0c958876f03a2927c1e88ffda Mon Sep 17 00:00:00 2001
From: Lesan <1960681385@qq.com>
Date: Tue, 26 Nov 2024 09:45:35 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20bpm=E8=AE=BE=E8=AE=A1=E5=99=A8=E9=80=82?=
=?UTF-8?q?=E9=85=8DSimple=E8=AE=BE=E8=AE=A1=E5=99=A8=EF=BC=8C=E5=AD=97?=
=?UTF-8?q?=E6=AE=B5=E6=9D=83=E9=99=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../descriptor/flowableDescriptor.json | 25 ++-
.../custom-config/ElementCustomConfig.vue | 210 +++++++++++++++++-
src/views/bpm/model/editor/index.vue | 14 ++
3 files changed, 245 insertions(+), 4 deletions(-)
diff --git a/src/components/bpmnProcessDesigner/package/designer/plugins/descriptor/flowableDescriptor.json b/src/components/bpmnProcessDesigner/package/designer/plugins/descriptor/flowableDescriptor.json
index 5544b2d0..c60b524a 100644
--- a/src/components/bpmnProcessDesigner/package/designer/plugins/descriptor/flowableDescriptor.json
+++ b/src/components/bpmnProcessDesigner/package/designer/plugins/descriptor/flowableDescriptor.json
@@ -1305,8 +1305,31 @@
"isAttr": true
}
]
+ },
+ {
+ "name": "FieldsPermission",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": ["bpmn:UserTask"]
+ },
+ "properties": [
+ {
+ "name": "flowable:field",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "flowable:title",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "flowable:permission",
+ "type": "String",
+ "isAttr": true
+ }
+ ]
}
-
],
"emumerations": []
}
diff --git a/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue b/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue
index 9cf7e966..ac766bf9 100644
--- a/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue
+++ b/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue
@@ -3,6 +3,7 @@
2. 审批人拒绝时
3. 审批人为空时
4. 操作按钮
+ 5. 字段权限
-->
@@ -104,6 +105,47 @@
+
+ 字段权限
+
+
+
字段名称
+
+ 只读
+ 可编辑
+ 隐藏
+
+
+
+
{{ item.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -115,9 +157,11 @@ import {
ASSIGN_EMPTY_HANDLER_TYPES,
AssignEmptyHandlerType,
OPERATION_BUTTON_NAME,
- DEFAULT_BUTTON_SETTING
+ DEFAULT_BUTTON_SETTING,
+ FieldPermissionType
} from '@/components/SimpleProcessDesignerV2/src/consts'
import * as UserApi from '@/api/system/user'
+import { cloneDeep } from 'lodash-es'
defineOptions({ name: 'ElementCustomConfig' })
const props = defineProps({
@@ -148,6 +192,12 @@ const buttonsSettingEl = ref()
const { buttonsSetting, btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } =
useButtonsSetting()
+// 字段权限
+const fieldsPermissionEl = ref()
+const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFieldsPermission(
+ FieldPermissionType.READ
+)
+
const elExtensionElements = ref()
const otherExtensions = ref()
const bpmnElement = ref()
@@ -218,6 +268,21 @@ const resetCustomConfigList = () => {
})
}
+ // 字段权限
+ if (formType.value === 10) {
+ fieldsPermissionEl.value = elExtensionElements.value.values?.filter(
+ (ex) => ex.$type === `${prefix}:FieldsPermission`
+ )
+ if (fieldsPermissionEl.value.length === 0) {
+ getNodeConfigFormFields()
+ fieldsPermissionConfig.value.forEach((el) => {
+ fieldsPermissionEl.value.push(
+ bpmnInstances().moddle.create(`${prefix}:FieldsPermission`, el)
+ )
+ })
+ }
+ }
+
// 保留剩余扩展元素,便于后面更新该元素对应属性
otherExtensions.value =
elExtensionElements.value.values?.filter(
@@ -227,7 +292,8 @@ const resetCustomConfigList = () => {
ex.$type !== `${prefix}:RejectReturnTaskId` &&
ex.$type !== `${prefix}:AssignEmptyHandlerType` &&
ex.$type !== `${prefix}:AssignEmptyUserIds` &&
- ex.$type !== `${prefix}:ButtonsSetting`
+ ex.$type !== `${prefix}:ButtonsSetting` &&
+ ex.$type !== `${prefix}:FieldsPermission`
) ?? []
// 更新元素扩展属性,避免后续报错
@@ -276,7 +342,8 @@ const updateElementExtensions = () => {
returnNodeIdEl.value,
assignEmptyHandlerTypeEl.value,
assignEmptyUserIdsEl.value,
- ...buttonsSettingEl.value
+ ...buttonsSettingEl.value,
+ ...fieldsPermissionEl.value
]
})
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
@@ -359,6 +426,69 @@ function useButtonsSetting() {
}
}
+// 表单字段权限设置
+function useFormFieldsPermission(defaultPermission) {
+ // 字段权限配置. 需要有 field, title, permissioin 属性
+ const fieldsPermissionConfig = ref>>([])
+
+ const formType = inject[>('formType') // 表单类型
+
+ const formFields = inject][>('formFields') // 流程表单字段
+
+ const getNodeConfigFormFields = (nodeFormFields?: Array>) => {
+ nodeFormFields = toRaw(nodeFormFields)
+ fieldsPermissionConfig.value =
+ cloneDeep(nodeFormFields) || getDefaultFieldsPermission(unref(formFields))
+ }
+ // 默认的表单权限: 获取表单的所有字段,设置字段默认权限为只读
+ const getDefaultFieldsPermission = (formFields?: string[]) => {
+ const defaultFieldsPermission: Array> = []
+ if (formFields) {
+ formFields.forEach((fieldStr: string) => {
+ parseFieldsSetDefaultPermission(JSON.parse(fieldStr), defaultFieldsPermission)
+ })
+ }
+ return defaultFieldsPermission
+ }
+ // 解析字段。赋给默认权限
+ const parseFieldsSetDefaultPermission = (
+ rule: Record,
+ fieldsPermission: Array>,
+ parentTitle: string = ''
+ ) => {
+ const { /**type,*/ field, title: tempTitle, children } = rule
+ if (field && tempTitle) {
+ let title = tempTitle
+ if (parentTitle) {
+ title = `${parentTitle}.${tempTitle}`
+ }
+ fieldsPermission.push({
+ field,
+ title,
+ permission: defaultPermission
+ })
+ // TODO 子表单 需要处理子表单字段
+ // if (type === 'group' && rule.props?.rule && Array.isArray(rule.props.rule)) {
+ // // 解析子表单的字段
+ // rule.props.rule.forEach((item) => {
+ // parseFieldsSetDefaultPermission(item, fieldsPermission, title)
+ // })
+ // }
+ }
+ if (children && Array.isArray(children)) {
+ children.forEach((rule) => {
+ parseFieldsSetDefaultPermission(rule, fieldsPermission)
+ })
+ }
+ }
+
+ return {
+ formType,
+ fieldsPermissionConfig,
+ getNodeConfigFormFields
+ }
+}
+
const userOptions = ref([]) // 用户列表
onMounted(async () => {
// 获得用户列表
@@ -449,4 +579,78 @@ onMounted(async () => {
}
}
}
+
+.field-setting-pane {
+ display: flex;
+ flex-direction: column;
+ font-size: 14px;
+
+ .field-setting-desc {
+ padding-right: 8px;
+ margin-bottom: 16px;
+ font-size: 16px;
+ font-weight: 700;
+ }
+
+ .field-permit-title {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ height: 45px;
+ padding-left: 12px;
+ line-height: 45px;
+ background-color: #f8fafc0a;
+ border: 1px solid #1f38581a;
+
+ .first-title {
+ text-align: left !important;
+ }
+
+ .other-titles {
+ display: flex;
+ justify-content: space-between;
+ }
+
+ .setting-title-label {
+ display: inline-block;
+ width: 100px;
+ padding: 5px 0;
+ font-size: 13px;
+ font-weight: 700;
+ color: #000;
+ text-align: center;
+ }
+ }
+
+ .field-setting-item {
+ align-items: center;
+ display: flex;
+ justify-content: space-between;
+ height: 38px;
+ padding-left: 12px;
+ border: 1px solid #1f38581a;
+ border-top: 0;
+
+ .field-setting-item-label {
+ display: inline-block;
+ width: 100px;
+ min-height: 16px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ cursor: text;
+ }
+
+ .field-setting-item-group {
+ display: flex;
+ justify-content: space-between;
+
+ .item-radio-wrap {
+ display: inline-block;
+ width: 100px;
+ text-align: center;
+ }
+ }
+ }
+}
diff --git a/src/views/bpm/model/editor/index.vue b/src/views/bpm/model/editor/index.vue
index 3e773691..1a41a50c 100644
--- a/src/views/bpm/model/editor/index.vue
+++ b/src/views/bpm/model/editor/index.vue
@@ -31,6 +31,7 @@ import CustomContentPadProvider from '@/components/bpmnProcessDesigner/package/d
// 自定义左侧菜单(修改 默认任务 为 用户任务)
import CustomPaletteProvider from '@/components/bpmnProcessDesigner/package/designer/plugins/palette'
import * as ModelApi from '@/api/bpm/model'
+import { getForm, FormVO } from '@/api/bpm/form'
defineOptions({ name: 'BpmModelEditor' })
@@ -38,6 +39,12 @@ const router = useRouter() // 路由
const { query } = useRoute() // 路由的查询
const message = useMessage() // 国际化
+// 表单信息
+const formFields = ref([])
+const formType = ref(20)
+provide('formFields', formFields)
+provide('formType', formType)
+
const xmlString = ref(undefined) // BPMN XML
const modeler = ref(null) // BPMN Modeler
const controlForm = ref({
@@ -99,6 +106,13 @@ onMounted(async () => {
`
}
+
+ formType.value = data.formType
+ if (data.formType === 10) {
+ const bpmnForm = (await getForm(data.formId)) as unknown as FormVO
+ formFields.value = bpmnForm?.fields
+ }
+
model.value = {
...data,
bpmnXml: undefined // 清空 bpmnXml 属性
]