仿钉钉设计流程:增加字段权限设置

This commit is contained in:
jason 2024-04-14 10:26:42 +08:00
parent 11b7cf32ca
commit cfc0003388
4 changed files with 373 additions and 201 deletions

View File

@ -70,6 +70,10 @@ let props = defineProps({
showAddButton:{ showAddButton:{
type:Boolean, type:Boolean,
default:true default:true
},
defaultFieldsPermission : {
type: Array,
default: () => ([])
} }
}) })
let emits = defineEmits(['update:childNodeP']) let emits = defineEmits(['update:childNodeP'])
@ -78,6 +82,7 @@ const addType = (type: number) => {
visible.value = false visible.value = false
// //
if (type === NodeType.APPROVE_USER_NODE) { if (type === NodeType.APPROVE_USER_NODE) {
console.log("props.defaultFieldsPermission", props.defaultFieldsPermission)
const data = { const data = {
name: '审核人', name: '审核人',
error: true, error: true,
@ -86,7 +91,8 @@ const addType = (type: number) => {
attributes: { attributes: {
approveMethod: undefined, approveMethod: undefined,
candidateStrategy: undefined, candidateStrategy: undefined,
candidateParam: undefined candidateParam: undefined,
fieldsPermission: props.defaultFieldsPermission,
}, },
childNode: props.childNodeP childNode: props.childNodeP
} }

View File

@ -1,3 +1,4 @@
<!-- eslint-disable vue/html-self-closing -->
<template> <template>
<el-drawer <el-drawer
:append-to-body="true" :append-to-body="true"
@ -5,10 +6,16 @@
:show-close="false" :show-close="false"
:size="550" :size="550"
:before-close="saveConfig" :before-close="saveConfig"
class="justify-start"
> >
<template #header> <template #header>
<div class="user-task-header">审批设置</div> <div class="w-full flex flex-col">
<span class="text-size-2xl">审批设置</span>
<el-divider />
</div>
</template> </template>
<el-tabs type="border-card">
<el-tab-pane label="审批人">
<div> <div>
<el-form label-position="top" label-width="100px"> <el-form label-position="top" label-width="100px">
<el-form-item label="审批方式" prop="approveMethod"> <el-form-item label="审批方式" prop="approveMethod">
@ -23,7 +30,12 @@
</el-form-item> </el-form-item>
<el-form-item label="审批人规则类型" prop="candidateStrategy"> <el-form-item label="审批人规则类型" prop="candidateStrategy">
<el-select v-model="candidateConfig.candidateStrategy" style="width: 100%" clearable @change="changecandidateStrategy"> <el-select
v-model="candidateConfig.candidateStrategy"
style="width: 100%"
clearable
@change="changecandidateStrategy"
>
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY)" v-for="dict in getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY)"
:key="dict.value" :key="dict.value"
@ -53,7 +65,9 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="candidateConfig.candidateStrategy == 20 || candidateConfig.candidateStrategy == 21" v-if="
candidateConfig.candidateStrategy == 20 || candidateConfig.candidateStrategy == 21
"
label="指定部门" label="指定部门"
prop="candidateParam" prop="candidateParam"
span="24" span="24"
@ -147,10 +161,63 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="demo-drawer__footer clear"> </el-tab-pane>
<el-tab-pane label="设置字段权限">
<div class="field-setting-pane h-full w-full flex flex-col">
<div class="field-setting-content mr-2 overflow-auto py-4 pr-2">
<div class="field-container flex flex-col flex-items-start">
<div class="mb-2 ml-4 font-bold">字段权限</div>
<div class="field-body ml-4 mt-2">
<div class="field-permit-box text-size--13px">
<div class="field-permit-title">
<span class="setting-title-label">组件名称</span>
<span class="setting-title-label">可编辑</span>
<span class="setting-title-label">只读</span>
<span class="setting-title-label">隐藏</span>
</div>
<div class="field-setting-item">
<span class="field-setting-item-label">全选</span>
<span class="all-checkbox-wrap">
<el-checkbox label="" size="large" />
</span>
<span class="all-checkbox-wrap">
<el-checkbox label="" size="large" />
</span>
<span class="all-checkbox-wrap">
<el-checkbox label="" size="large" />
</span>
</div>
<div class="field-setting-item-check">
<div class="field-setting-item" v-for="(item,index) in candidateConfig.fieldsPermission" :key="index">
<span class="field-setting-item-label"> {{ item.title }}</span>
<el-radio-group v-model="item.permission" >
<div class="item-radio-wrap">
<el-radio value="1" size="large" label="1"/>
</div>
<div class="item-radio-wrap">
<el-radio value="2" size="large" label="2"/>
</div>
<div class="item-radio-wrap">
<el-radio value="3" size="large" label="3"/>
</div>
</el-radio-group>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
<template #footer>
<el-divider />
<div>
<el-button type="primary" @click="saveConfig"> </el-button> <el-button type="primary" @click="saveConfig"> </el-button>
<el-button @click="closeDrawer"> </el-button> <el-button @click="closeDrawer"> </el-button>
</div> </div>
</template>
</el-drawer> </el-drawer>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -173,12 +240,13 @@ const userGroupOptions = ref<UserGroupApi.UserGroupVO[]>([]) // 用户组列表
const candidateConfig = ref({ const candidateConfig = ref({
candidateStrategy: undefined, candidateStrategy: undefined,
candidateParam: [], candidateParam: [],
approveMethod: undefined approveMethod: undefined,
fieldsPermission:[]
}) })
let approverConfig = ref({}) // let approverConfig = ref({})
let store = useWorkFlowStoreWithOut() let store = useWorkFlowStoreWithOut()
let { setApproverDrawer, setUserTaskConfig } = store let { setApproverDrawer, setUserTaskConfig } = store
let approverConfig1 = computed(() => store.approverConfig1) // let approverConfig1 = computed(() => store.approverConfig1)
let approverDrawer = computed(() => store.approverDrawer) let approverDrawer = computed(() => store.approverDrawer)
const userTaskConfig = computed(() => store.userTaskConfig) const userTaskConfig = computed(() => store.userTaskConfig)
@ -192,33 +260,33 @@ let visible = computed({
}) })
watch(userTaskConfig, (val) => { watch(userTaskConfig, (val) => {
if (val.value.attributes) { if (val.value.attributes) {
console.log('val.value.attributes', val.value.attributes);
candidateConfig.value.approveMethod = val.value.attributes.approveMethod candidateConfig.value.approveMethod = val.value.attributes.approveMethod
candidateConfig.value.candidateStrategy = val.value.attributes.candidateStrategy candidateConfig.value.candidateStrategy = val.value.attributes.candidateStrategy
const candidateParamStr = val.value.attributes.candidateParam; const candidateParamStr = val.value.attributes.candidateParam
if(val.value.attributes.candidateStrategy === 60) { if (val.value.attributes.candidateStrategy === 60) {
candidateConfig.value.candidateParam = [candidateParamStr] candidateConfig.value.candidateParam = [candidateParamStr]
} else { } else {
if(candidateParamStr){ if (candidateParamStr) {
candidateConfig.value.candidateParam = candidateParamStr.split(',').map((item) => +item) candidateConfig.value.candidateParam = candidateParamStr.split(',').map((item) => +item)
} }
} }
console.log('val.value.attributes.fieldsPermission', val.value.attributes.fieldsPermission)
// candidateConfig.value = val.value.attributes candidateConfig.value.fieldsPermission = val.value.attributes.fieldsPermission
} }
}) })
watch(approverConfig1, (val) => { // watch(approverConfig1, (val) => {
approverConfig.value = val.value // approverConfig.value = val.value
}) // })
const saveConfig = () => { const saveConfig = () => {
const rawConfig = toRaw(userTaskConfig.value) const rawConfig = toRaw(userTaskConfig.value)
const { approveMethod, candidateStrategy , candidateParam} = toRaw(candidateConfig.value); const { approveMethod, candidateStrategy, candidateParam, fieldsPermission } = toRaw(candidateConfig.value)
const candidateParamStr = candidateParam.join(',') const candidateParamStr = candidateParam.join(',')
rawConfig.value.attributes = { rawConfig.value.attributes = {
approveMethod, approveMethod,
candidateStrategy, candidateStrategy,
candidateParam: candidateParamStr candidateParam: candidateParamStr,
fieldsPermission: fieldsPermission
} }
rawConfig.flag = true rawConfig.flag = true
// TODO // TODO
@ -230,7 +298,7 @@ const saveConfig = () => {
setUserTaskConfig({ setUserTaskConfig({
value: rawConfig.value, value: rawConfig.value,
flag: true, flag: true,
id: userTaskConfig.value.id, id: userTaskConfig.value.id
}) })
closeDrawer() closeDrawer()
} }
@ -253,10 +321,84 @@ onMounted(async () => {
deptTreeOptions.value = handleTree(deptOptions, 'id') deptTreeOptions.value = handleTree(deptOptions, 'id')
// //
userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList() userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList()
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.user-task-header { // ::v-deep .el-drawer__header {
font-size: 16px !important; // margin-bottom: 2px;
// }
.field-permit-title {
height: 45px;
padding: 0 0 0 12px;
line-height: 32px;
background-color: rgba(248, 250, 252, 0.04);
border: 1px solid rgba(31, 56, 88, 0.1);
.setting-title-label:first-child {
text-align: left;
}
.setting-title-label {
display: inline-block;
width: 110px;
padding: 5px 0;
font-size: 13px;
font-weight: 700;
color: rgba(0, 0, 0, 0.6);
text-align: center;
}
}
.field-setting-item {
display: flex;
align-items: center;
height: 38px;
padding-bottom: 0;
padding-left: 12px;
line-height: 38px;
border-right: 1px solid rgba(31, 56, 88, 0.1);
border-bottom: 1px solid rgba(31, 56, 88, 0.1);
border-left: 1px solid rgba(31, 56, 88, 0.1);
.no-label {
font-size: 0;
}
.field-setting-item-label {
display: inline-block;
width: 110px;
min-height: 16px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: text;
}
.all-checkbox-wrap {
display: inline-block;
width: 110px;
text-align: center;
}
.item-radio-wrap {
display: inline-block;
width: 110px;
padding-left: 6px;
text-align: center;
}
}
::v-deep(.el-radio__label) {
opacity: 0; /* 隐藏标签文本 */
}
::v-deep(.el-divider--horizontal) {
display: block;
width: 100%;
height: 1px;
margin: 4px 0;
border-top: 1px var(--el-border-color) var(--el-border-style);
} }
</style> </style>

View File

@ -44,7 +44,7 @@
<i class="anticon anticon-exclamation-circle"></i> <i class="anticon anticon-exclamation-circle"></i>
</div> </div>
</div> </div>
<addNode v-model:childNodeP="nodeConfig.childNode" /> <addNode v-model:childNodeP="nodeConfig.childNode" :default-fields-permission="props.defaultFieldsPermission" />
</div> </div>
<div class="branch-wrap" v-if="nodeConfig.type == 4"> <div class="branch-wrap" v-if="nodeConfig.type == 4">
<div class="branch-box-wrap"> <div class="branch-box-wrap">
@ -92,10 +92,10 @@
<i class="anticon anticon-exclamation-circle"></i> <i class="anticon anticon-exclamation-circle"></i>
</div> </div>
</div> </div>
<addNode v-model:childNodeP="item.childNode" /> <addNode v-model:childNodeP="item.childNode" :default-fields-permission="props.defaultFieldsPermission"/>
</div> </div>
</div> </div>
<nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" /> <nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" :default-fields-permission="props.defaultFieldsPermission"/>
<template v-if="index == 0"> <template v-if="index == 0">
<div class="top-left-cover-line"></div> <div class="top-left-cover-line"></div>
<div class="bottom-left-cover-line"></div> <div class="bottom-left-cover-line"></div>
@ -106,7 +106,7 @@
</template> </template>
</div> </div>
</div> </div>
<addNode v-model:childNodeP="nodeConfig.childNode" /> <addNode v-model:childNodeP="nodeConfig.childNode" :default-fields-permission="props.defaultFieldsPermission"/>
</div> </div>
</div> </div>
<div class="branch-wrap" v-if="nodeConfig.type == 5"> <div class="branch-wrap" v-if="nodeConfig.type == 5">
@ -137,10 +137,10 @@
<i class="anticon anticon-exclamation-circle"></i> <i class="anticon anticon-exclamation-circle"></i>
</div> </div>
</div> </div>
<addNode v-model:childNodeP="item.childNode" /> <addNode v-model:childNodeP="item.childNode" :default-fields-permission="props.defaultFieldsPermission"/>
</div> </div>
</div> </div>
<nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" /> <nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" :default-fields-permission="props.defaultFieldsPermission" />
<template v-if="index == 0"> <template v-if="index == 0">
<div class="top-left-cover-line"></div> <div class="top-left-cover-line"></div>
<div class="bottom-left-cover-line"></div> <div class="bottom-left-cover-line"></div>
@ -151,7 +151,7 @@
</template> </template>
</div> </div>
</div> </div>
<addNode v-model:childNodeP="nodeConfig.childNode" :show-add-button="false" /> <addNode v-model:childNodeP="nodeConfig.childNode" :show-add-button="false" :default-fields-permission="props.defaultFieldsPermission"/>
</div> </div>
</div> </div>
<div class="branch-wrap" v-if="nodeConfig.type == 7"> <div class="branch-wrap" v-if="nodeConfig.type == 7">
@ -186,10 +186,10 @@
<i class="anticon anticon-exclamation-circle"></i> <i class="anticon anticon-exclamation-circle"></i>
</div> </div>
</div> </div>
<addNode v-model:childNodeP="item.childNode" /> <addNode v-model:childNodeP="item.childNode" :default-fields-permission="props.defaultFieldsPermission"/>
</div> </div>
</div> </div>
<nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" /> <nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" :default-fields-permission="props.defaultFieldsPermission" />
<template v-if="index == 0"> <template v-if="index == 0">
<div class="top-left-cover-line"></div> <div class="top-left-cover-line"></div>
<div class="bottom-left-cover-line"></div> <div class="bottom-left-cover-line"></div>
@ -200,7 +200,7 @@
</template> </template>
</div> </div>
</div> </div>
<addNode v-model:childNodeP="nodeConfig.childNode" :show-add-button="false" /> <addNode v-model:childNodeP="nodeConfig.childNode" :show-add-button="false" :default-fields-permission="props.defaultFieldsPermission" />
</div> </div>
</div> </div>
<div class="node-wrap" v-if="nodeConfig.type === NodeType.PARALLEL_NODE_JOIN || nodeConfig.type === NodeType.INCLUSIVE_NODE_JOIN"> <div class="node-wrap" v-if="nodeConfig.type === NodeType.PARALLEL_NODE_JOIN || nodeConfig.type === NodeType.INCLUSIVE_NODE_JOIN">
@ -209,9 +209,9 @@
<div class="text">聚合</div> <div class="text">聚合</div>
</div> </div>
</div> </div>
<addNode v-model:childNodeP="nodeConfig.childNode" /> <addNode v-model:childNodeP="nodeConfig.childNode" :default-fields-permission="props.defaultFieldsPermission" />
</div> </div>
<nodeWrap v-if="nodeConfig.childNode" v-model:nodeConfig="nodeConfig.childNode" /> <nodeWrap v-if="nodeConfig.childNode" v-model:nodeConfig="nodeConfig.childNode" :default-fields-permission="props.defaultFieldsPermission" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import addNode from './addNode.vue' import addNode from './addNode.vue'
@ -232,6 +232,10 @@ let props = defineProps({
nodeConfig: { nodeConfig: {
type: Object as () => WorkFlowNode, type: Object as () => WorkFlowNode,
default: () => ({}) as WorkFlowNode default: () => ({}) as WorkFlowNode
},
defaultFieldsPermission : {
type: Array,
default: () => ([])
} }
}) })

View File

@ -12,7 +12,7 @@
<div class="start-event-node-circle">开始</div> <div class="start-event-node-circle">开始</div>
</div> </div>
<div class="start-event-node-line"></div> <div class="start-event-node-line"></div>
<nodeWrap v-model:nodeConfig="nodeConfig" /> <nodeWrap v-model:nodeConfig="nodeConfig" :defaultFieldsPermission="defaultFieldsPermission" />
<!-- <div class="end-node"> <!-- <div class="end-node">
<div class="end-node-circle"></div> <div class="end-node-circle"></div>
<div class="end-node-text">流程结束</div> <div class="end-node-text">流程结束</div>
@ -23,7 +23,7 @@
</div> </div>
</section> </section>
</div> </div>
<approverDrawer /> <approverDrawer/>
<copyerDrawer /> <copyerDrawer />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -33,6 +33,8 @@ import copyerDrawer from '@/components/SimpleProcessDesigner/src/drawer/copyerDr
import { WorkFlowNode } from '@/components/SimpleProcessDesigner/src/consts' import { WorkFlowNode } from '@/components/SimpleProcessDesigner/src/consts'
import { ref } from 'vue' import { ref } from 'vue'
import { saveBpmSimpleModel, getBpmSimpleModel } from '@/api/bpm/simple' import { saveBpmSimpleModel, getBpmSimpleModel } from '@/api/bpm/simple'
import { getModel } from '@/api/bpm/model'
import { getForm, FormVO } from '@/api/bpm/form'
defineOptions({ name: 'SimpleWorkflowDesignEditor' }) defineOptions({ name: 'SimpleWorkflowDesignEditor' })
const uid = getCurrentInstance().uid const uid = getCurrentInstance().uid
const router = useRouter() // const router = useRouter() //
@ -45,28 +47,28 @@ const nodeConfig = ref<WorkFlowNode>({
id: 'StartEvent_' + uid, id: 'StartEvent_' + uid,
childNode: undefined, childNode: undefined,
attributes: undefined, attributes: undefined,
conditionNodes: undefined conditionNodes: []
} })
) //
const defaultFieldsPermission: any[] = []
const test = async () => { const test = async () => {
if (!modelId) { if (!modelId) {
message.error('缺少模型 modelId 编号') message.error('缺少模型 modelId 编号')
return return
} }
const test = nodeConfig.value; const test = nodeConfig.value
console.log('test is ', test) console.log('test is ', test)
console.log('nodeConfig.value ', nodeConfig.value) console.log('nodeConfig.value ', nodeConfig.value)
const data = { const data1 = {
modelId: modelId, modelId: modelId,
simpleModelBody: toRaw(nodeConfig.value) simpleModelBody: toRaw(nodeConfig.value)
} }
const data1 = { const data = {
modelId: modelId, modelId: modelId,
simpleModelBody: nodeConfig.value simpleModelBody: nodeConfig.value
} }
console.log('request json data is ', data)
console.log('request json data1 is ', data1) console.log('request json data1 is ', data1)
const result = await saveBpmSimpleModel(data1) const result = await saveBpmSimpleModel(data)
console.log('save the result is ', result) console.log('save the result is ', result)
if (result) { if (result) {
message.success('修改成功') message.success('修改成功')
@ -74,17 +76,35 @@ const test = async () => {
} else { } else {
message.alert('修改失败') message.alert('修改失败')
} }
} }
const close = () => { const close = () => {
router.push({ path: '/bpm/manager/model' }) router.push({ path: '/bpm/manager/model' })
} }
onMounted(async () => { onMounted(async () => {
const bpmnModel = await getModel(modelId)
if (bpmnModel) {
const formType = bpmnModel.formType
if (formType === 10) {
const bpmnForm = await getForm(bpmnModel.formId) as unknown as FormVO
const formFields = bpmnForm?.fields
if (formFields) {
formFields.forEach((fieldStr: string) => {
const { field, title } = JSON.parse(fieldStr)
defaultFieldsPermission.push({
field,
title,
permission: '2'
})
})
}
console.log('defaultFieldsPermissions', defaultFieldsPermission);
}
}
console.log('the modelId is ', modelId) console.log('the modelId is ', modelId)
const result = await getBpmSimpleModel(modelId) const result = await getBpmSimpleModel(modelId)
if(result){ if (result) {
console.log('get the result is ', result) console.log('get the result is ', result)
nodeConfig.value = result; nodeConfig.value = result
} }
}) })
</script> </script>
@ -104,7 +124,7 @@ onMounted(async () => {
height: 40px; height: 40px;
font-size: 14px; font-size: 14px;
color: #f8f8fa; color: #f8f8fa;
background-image: linear-gradient(-30deg,#bbbbc4,#d5d5de),linear-gradient(#bcbcc5,#bcbcc5); background-image: linear-gradient(-30deg, #bbbbc4, #d5d5de), linear-gradient(#bcbcc5, #bcbcc5);
border-radius: 50%; border-radius: 50%;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -130,7 +150,7 @@ onMounted(async () => {
justify-content: center; justify-content: center;
font-size: 14px; font-size: 14px;
color: #f8f8fa; color: #f8f8fa;
background-image: linear-gradient(90deg,#ff6a00,#f78b3e),linear-gradient(#ff6a00,#ff6a00); background-image: linear-gradient(90deg, #ff6a00, #f78b3e), linear-gradient(#ff6a00, #ff6a00);
border-radius: 50%; border-radius: 50%;
} }
@ -142,7 +162,7 @@ onMounted(async () => {
height: 100%; height: 100%;
margin: auto; margin: auto;
background-color: #cacaca; background-color: #cacaca;
content: ""; content: '';
} }
.start-event-node-line { .start-event-node-line {