Pre Merge pull request !121 from Jason/dev
commit
cacd758829
|
@ -0,0 +1,529 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Rule } from 'ant-design-vue/es/form';
|
||||||
|
|
||||||
|
import type { Ref } from 'vue';
|
||||||
|
|
||||||
|
import type { SimpleFlowNode } from '../../consts';
|
||||||
|
import type { CopyTaskFormType } from '../../helpers';
|
||||||
|
|
||||||
|
import { computed, onMounted, reactive, ref } from 'vue';
|
||||||
|
|
||||||
|
import { useVbenDrawer } from '@vben/common-ui';
|
||||||
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Col,
|
||||||
|
Form,
|
||||||
|
FormItem,
|
||||||
|
Input,
|
||||||
|
Radio,
|
||||||
|
RadioGroup,
|
||||||
|
Row,
|
||||||
|
Select,
|
||||||
|
SelectOption,
|
||||||
|
TabPane,
|
||||||
|
Tabs,
|
||||||
|
Textarea,
|
||||||
|
TreeSelect,
|
||||||
|
} from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { BpmModelFormType } from '#/utils';
|
||||||
|
|
||||||
|
import {
|
||||||
|
CANDIDATE_STRATEGY,
|
||||||
|
CandidateStrategy,
|
||||||
|
FieldPermissionType,
|
||||||
|
MULTI_LEVEL_DEPT,
|
||||||
|
NodeType,
|
||||||
|
} from '../../consts';
|
||||||
|
import {
|
||||||
|
useFormFieldsPermission,
|
||||||
|
useNodeForm,
|
||||||
|
useNodeName,
|
||||||
|
useWatchNode,
|
||||||
|
} from '../../helpers';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'CopyTaskNodeConfig',
|
||||||
|
});
|
||||||
|
const props = defineProps({
|
||||||
|
flowNode: {
|
||||||
|
type: Object as () => SimpleFlowNode,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const deptLevelLabel = computed(() => {
|
||||||
|
let label = '部门负责人来源';
|
||||||
|
label =
|
||||||
|
configForm.value.candidateStrategy ===
|
||||||
|
CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
|
||||||
|
? `${label}(指定部门向上)`
|
||||||
|
: `${label}(发起人部门向上)`;
|
||||||
|
return label;
|
||||||
|
});
|
||||||
|
// 抽屉配置
|
||||||
|
const [Drawer, drawerApi] = useVbenDrawer({
|
||||||
|
header: true,
|
||||||
|
closable: true,
|
||||||
|
title: '',
|
||||||
|
placement: 'right',
|
||||||
|
onCancel() {
|
||||||
|
drawerApi.close();
|
||||||
|
},
|
||||||
|
onConfirm() {
|
||||||
|
saveConfig();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// 当前节点
|
||||||
|
const currentNode = useWatchNode(props);
|
||||||
|
// 节点名称
|
||||||
|
const { nodeName, showInput, clickIcon, blurEvent } = useNodeName(
|
||||||
|
NodeType.COPY_TASK_NODE,
|
||||||
|
);
|
||||||
|
// 激活的 Tab 标签页
|
||||||
|
const activeTabName = ref('user');
|
||||||
|
// 表单字段权限配置
|
||||||
|
const {
|
||||||
|
formType,
|
||||||
|
fieldsPermissionConfig,
|
||||||
|
formFieldOptions,
|
||||||
|
getNodeConfigFormFields,
|
||||||
|
} = useFormFieldsPermission(FieldPermissionType.READ);
|
||||||
|
// 表单内用户字段选项, 必须是必填和用户选择器
|
||||||
|
const userFieldOnFormOptions = computed(() => {
|
||||||
|
return formFieldOptions.filter((item) => item.type === 'UserSelect');
|
||||||
|
});
|
||||||
|
// 表单内部门字段选项, 必须是必填和部门选择器
|
||||||
|
const deptFieldOnFormOptions = computed(() => {
|
||||||
|
return formFieldOptions.filter((item) => item.type === 'DeptSelect');
|
||||||
|
});
|
||||||
|
// 抄送人表单配置
|
||||||
|
const formRef = ref(); // 表单 Ref
|
||||||
|
// 表单校验规则
|
||||||
|
const formRules: Record<string, Rule[]> = reactive({
|
||||||
|
candidateStrategy: [
|
||||||
|
{ required: true, message: '抄送人设置不能为空', trigger: 'change' },
|
||||||
|
],
|
||||||
|
userIds: [{ required: true, message: '用户不能为空', trigger: 'change' }],
|
||||||
|
roleIds: [{ required: true, message: '角色不能为空', trigger: 'change' }],
|
||||||
|
deptIds: [{ required: true, message: '部门不能为空', trigger: 'change' }],
|
||||||
|
userGroups: [
|
||||||
|
{ required: true, message: '用户组不能为空', trigger: 'change' },
|
||||||
|
],
|
||||||
|
postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }],
|
||||||
|
formUser: [
|
||||||
|
{ required: true, message: '表单内用户字段不能为空', trigger: 'change' },
|
||||||
|
],
|
||||||
|
formDept: [
|
||||||
|
{ required: true, message: '表单内部门字段不能为空', trigger: 'change' },
|
||||||
|
],
|
||||||
|
expression: [
|
||||||
|
{ required: true, message: '流程表达式不能为空', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
configForm: tempConfigForm,
|
||||||
|
roleOptions,
|
||||||
|
postOptions,
|
||||||
|
userOptions,
|
||||||
|
userGroupOptions,
|
||||||
|
deptTreeOptions,
|
||||||
|
getShowText,
|
||||||
|
handleCandidateParam,
|
||||||
|
parseCandidateParam,
|
||||||
|
} = useNodeForm(NodeType.COPY_TASK_NODE);
|
||||||
|
const configForm = tempConfigForm as Ref<CopyTaskFormType>;
|
||||||
|
// 抄送人策略, 去掉发起人自选 和 发起人自己
|
||||||
|
const copyUserStrategies = computed(() => {
|
||||||
|
return CANDIDATE_STRATEGY.filter(
|
||||||
|
(item) => item.value !== CandidateStrategy.START_USER,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
// 改变抄送人设置策略
|
||||||
|
const changeCandidateStrategy = () => {
|
||||||
|
configForm.value.userIds = [];
|
||||||
|
configForm.value.deptIds = [];
|
||||||
|
configForm.value.roleIds = [];
|
||||||
|
configForm.value.postIds = [];
|
||||||
|
configForm.value.userGroups = [];
|
||||||
|
configForm.value.deptLevel = 1;
|
||||||
|
configForm.value.formUser = '';
|
||||||
|
configForm.value.formDept = '';
|
||||||
|
};
|
||||||
|
// 保存配置
|
||||||
|
const saveConfig = async () => {
|
||||||
|
activeTabName.value = 'user';
|
||||||
|
if (!formRef.value) return false;
|
||||||
|
const valid = await formRef.value.validate();
|
||||||
|
if (!valid) return false;
|
||||||
|
const showText = getShowText();
|
||||||
|
if (!showText) return false;
|
||||||
|
currentNode.value.name = nodeName.value!;
|
||||||
|
currentNode.value.candidateParam = handleCandidateParam();
|
||||||
|
currentNode.value.candidateStrategy = configForm.value.candidateStrategy;
|
||||||
|
currentNode.value.showText = showText;
|
||||||
|
currentNode.value.fieldsPermission = fieldsPermissionConfig.value;
|
||||||
|
drawerApi.close();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
// 显示抄送节点配置, 由父组件传过来
|
||||||
|
const showCopyTaskNodeConfig = (node: SimpleFlowNode) => {
|
||||||
|
nodeName.value = node.name;
|
||||||
|
// 抄送人设置
|
||||||
|
configForm.value.candidateStrategy = node.candidateStrategy!;
|
||||||
|
parseCandidateParam(node.candidateStrategy!, node?.candidateParam);
|
||||||
|
// 表单字段权限
|
||||||
|
getNodeConfigFormFields(node.fieldsPermission);
|
||||||
|
|
||||||
|
drawerApi.open();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 批量更新权限 */
|
||||||
|
const updatePermission = (type: string) => {
|
||||||
|
fieldsPermissionConfig.value.forEach((field) => {
|
||||||
|
if (type === 'READ') {
|
||||||
|
field.permission = FieldPermissionType.READ;
|
||||||
|
} else if (type === 'WRITE') {
|
||||||
|
field.permission = FieldPermissionType.WRITE;
|
||||||
|
} else {
|
||||||
|
field.permission = FieldPermissionType.NONE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 在组件初始化时对表单字段进行处理
|
||||||
|
onMounted(() => {
|
||||||
|
// 可以在这里进行初始化操作
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({ showCopyTaskNodeConfig }); // 暴露方法给父组件
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<Drawer class="w-[580px]">
|
||||||
|
<template #title>
|
||||||
|
<div class="config-header">
|
||||||
|
<Input
|
||||||
|
v-if="showInput"
|
||||||
|
type="text"
|
||||||
|
class="config-editable-input"
|
||||||
|
@blur="blurEvent()"
|
||||||
|
v-model:value="nodeName"
|
||||||
|
:placeholder="nodeName"
|
||||||
|
/>
|
||||||
|
<div v-else class="node-name">
|
||||||
|
{{ nodeName }}
|
||||||
|
<IconifyIcon class="ml-1" icon="ep:edit-pen" @click="clickIcon()" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<Tabs v-model:active-key="activeTabName">
|
||||||
|
<TabPane tab="抄送人" key="user">
|
||||||
|
<div>
|
||||||
|
<Form
|
||||||
|
ref="formRef"
|
||||||
|
:model="configForm"
|
||||||
|
:label-col="{ span: 24 }"
|
||||||
|
:wrapper-col="{ span: 24 }"
|
||||||
|
:rules="formRules"
|
||||||
|
>
|
||||||
|
<FormItem label="抄送人设置" name="candidateStrategy">
|
||||||
|
<RadioGroup
|
||||||
|
v-model:value="configForm.candidateStrategy"
|
||||||
|
@change="changeCandidateStrategy"
|
||||||
|
>
|
||||||
|
<Row :gutter="[0, 8]">
|
||||||
|
<Col
|
||||||
|
v-for="(dict, index) in copyUserStrategies"
|
||||||
|
:key="index"
|
||||||
|
:span="8"
|
||||||
|
>
|
||||||
|
<Radio :value="dict.value" :label="dict.value">
|
||||||
|
{{ dict.label }}
|
||||||
|
</Radio>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
v-if="configForm.candidateStrategy === CandidateStrategy.ROLE"
|
||||||
|
label="指定角色"
|
||||||
|
name="roleIds"
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
v-model:value="configForm.roleIds"
|
||||||
|
clearable
|
||||||
|
mode="multiple"
|
||||||
|
>
|
||||||
|
<SelectOption
|
||||||
|
v-for="item in roleOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</SelectOption>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
v-if="
|
||||||
|
configForm.candidateStrategy ===
|
||||||
|
CandidateStrategy.DEPT_MEMBER ||
|
||||||
|
configForm.candidateStrategy ===
|
||||||
|
CandidateStrategy.DEPT_LEADER ||
|
||||||
|
configForm.candidateStrategy ===
|
||||||
|
CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
|
||||||
|
"
|
||||||
|
label="指定部门"
|
||||||
|
name="deptIds"
|
||||||
|
>
|
||||||
|
<TreeSelect
|
||||||
|
v-model:value="configForm.deptIds"
|
||||||
|
:tree-data="deptTreeOptions"
|
||||||
|
:field-names="{
|
||||||
|
label: 'name',
|
||||||
|
value: 'id',
|
||||||
|
children: 'children',
|
||||||
|
}"
|
||||||
|
empty-text="加载中,请稍后"
|
||||||
|
multiple
|
||||||
|
:check-strictly="true"
|
||||||
|
allow-clear
|
||||||
|
tree-checkable
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
v-if="configForm.candidateStrategy === CandidateStrategy.POST"
|
||||||
|
label="指定岗位"
|
||||||
|
name="postIds"
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
v-model:value="configForm.postIds"
|
||||||
|
clearable
|
||||||
|
mode="multiple"
|
||||||
|
>
|
||||||
|
<SelectOption
|
||||||
|
v-for="item in postOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id!"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</SelectOption>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
v-if="configForm.candidateStrategy === CandidateStrategy.USER"
|
||||||
|
label="指定用户"
|
||||||
|
name="userIds"
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
v-model:value="configForm.userIds"
|
||||||
|
clearable
|
||||||
|
mode="multiple"
|
||||||
|
>
|
||||||
|
<SelectOption
|
||||||
|
v-for="item in userOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.nickname"
|
||||||
|
:value="item.id"
|
||||||
|
>
|
||||||
|
{{ item.nickname }}
|
||||||
|
</SelectOption>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
v-if="
|
||||||
|
configForm.candidateStrategy === CandidateStrategy.USER_GROUP
|
||||||
|
"
|
||||||
|
label="指定用户组"
|
||||||
|
name="userGroups"
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
v-model:value="configForm.userGroups"
|
||||||
|
clearable
|
||||||
|
mode="multiple"
|
||||||
|
>
|
||||||
|
<SelectOption
|
||||||
|
v-for="item in userGroupOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</SelectOption>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
v-if="
|
||||||
|
configForm.candidateStrategy === CandidateStrategy.FORM_USER
|
||||||
|
"
|
||||||
|
label="表单内用户字段"
|
||||||
|
name="formUser"
|
||||||
|
>
|
||||||
|
<Select v-model:value="configForm.formUser" clearable>
|
||||||
|
<SelectOption
|
||||||
|
v-for="(item, idx) in userFieldOnFormOptions"
|
||||||
|
:key="idx"
|
||||||
|
:label="item.title"
|
||||||
|
:value="item.field"
|
||||||
|
:disabled="!item.required"
|
||||||
|
>
|
||||||
|
{{ item.title }}
|
||||||
|
</SelectOption>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
v-if="
|
||||||
|
configForm.candidateStrategy ===
|
||||||
|
CandidateStrategy.FORM_DEPT_LEADER
|
||||||
|
"
|
||||||
|
label="表单内部门字段"
|
||||||
|
name="formDept"
|
||||||
|
>
|
||||||
|
<Select v-model:value="configForm.formDept" clearable>
|
||||||
|
<SelectOption
|
||||||
|
v-for="(item, idx) in deptFieldOnFormOptions"
|
||||||
|
:key="idx"
|
||||||
|
:label="item.title"
|
||||||
|
:value="item.field"
|
||||||
|
:disabled="!item.required"
|
||||||
|
>
|
||||||
|
{{ item.title }}
|
||||||
|
</SelectOption>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
v-if="
|
||||||
|
configForm.candidateStrategy ===
|
||||||
|
CandidateStrategy.MULTI_LEVEL_DEPT_LEADER ||
|
||||||
|
configForm.candidateStrategy ===
|
||||||
|
CandidateStrategy.START_USER_DEPT_LEADER ||
|
||||||
|
configForm.candidateStrategy ===
|
||||||
|
CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER ||
|
||||||
|
configForm.candidateStrategy ===
|
||||||
|
CandidateStrategy.FORM_DEPT_LEADER
|
||||||
|
"
|
||||||
|
:label="deptLevelLabel!"
|
||||||
|
name="deptLevel"
|
||||||
|
>
|
||||||
|
<Select v-model:value="configForm.deptLevel" clearable>
|
||||||
|
<SelectOption
|
||||||
|
v-for="(item, index) in MULTI_LEVEL_DEPT"
|
||||||
|
:key="index"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</SelectOption>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
v-if="
|
||||||
|
configForm.candidateStrategy === CandidateStrategy.EXPRESSION
|
||||||
|
"
|
||||||
|
label="流程表达式"
|
||||||
|
name="expression"
|
||||||
|
>
|
||||||
|
<Textarea v-model:value="configForm.expression" clearable />
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
</TabPane>
|
||||||
|
<TabPane
|
||||||
|
tab="表单字段权限"
|
||||||
|
key="fields"
|
||||||
|
v-if="formType === BpmModelFormType.NORMAL"
|
||||||
|
>
|
||||||
|
<div class="p-1">
|
||||||
|
<div class="mb-4 text-[16px] font-bold">字段权限</div>
|
||||||
|
|
||||||
|
<!-- 表头 -->
|
||||||
|
<Row class="border border-gray-200 px-4 py-3">
|
||||||
|
<Col :span="8" class="font-bold">字段名称</Col>
|
||||||
|
<Col :span="16">
|
||||||
|
<Row>
|
||||||
|
<Col :span="8" class="flex items-center justify-center">
|
||||||
|
<span
|
||||||
|
class="cursor-pointer font-bold"
|
||||||
|
@click="updatePermission('READ')"
|
||||||
|
>
|
||||||
|
只读
|
||||||
|
</span>
|
||||||
|
</Col>
|
||||||
|
<Col :span="8" class="flex items-center justify-center">
|
||||||
|
<span
|
||||||
|
class="cursor-pointer font-bold"
|
||||||
|
@click="updatePermission('WRITE')"
|
||||||
|
>
|
||||||
|
可编辑
|
||||||
|
</span>
|
||||||
|
</Col>
|
||||||
|
<Col :span="8" class="flex items-center justify-center">
|
||||||
|
<span
|
||||||
|
class="cursor-pointer font-bold"
|
||||||
|
@click="updatePermission('NONE')"
|
||||||
|
>
|
||||||
|
隐藏
|
||||||
|
</span>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<!-- 表格内容 -->
|
||||||
|
<div v-for="(item, index) in fieldsPermissionConfig" :key="index">
|
||||||
|
<Row class="border border-t-0 border-gray-200 px-4 py-2">
|
||||||
|
<Col :span="8" class="flex items-center truncate">
|
||||||
|
{{ item.title }}
|
||||||
|
</Col>
|
||||||
|
<Col :span="16">
|
||||||
|
<RadioGroup v-model:value="item.permission" class="w-full">
|
||||||
|
<Row>
|
||||||
|
<Col :span="8" class="flex items-center justify-center">
|
||||||
|
<Radio
|
||||||
|
:value="FieldPermissionType.READ"
|
||||||
|
size="large"
|
||||||
|
:label="FieldPermissionType.READ"
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col :span="8" class="flex items-center justify-center">
|
||||||
|
<Radio
|
||||||
|
:value="FieldPermissionType.WRITE"
|
||||||
|
size="large"
|
||||||
|
:label="FieldPermissionType.WRITE"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col :span="8" class="flex items-center justify-center">
|
||||||
|
<Radio
|
||||||
|
:value="FieldPermissionType.NONE"
|
||||||
|
size="large"
|
||||||
|
:label="FieldPermissionType.NONE"
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</RadioGroup>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TabPane>
|
||||||
|
</Tabs>
|
||||||
|
<template #footer>
|
||||||
|
<Button type="primary" @click="saveConfig">确 定</Button>
|
||||||
|
<Button @click="drawerApi.close()">取 消</Button>
|
||||||
|
</template>
|
||||||
|
</Drawer>
|
||||||
|
</template>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.config-editable-input {
|
||||||
|
&:focus {
|
||||||
|
outline: 0;
|
||||||
|
border-color: #40a9ff;
|
||||||
|
box-shadow: 0 0 0 2px rgb(24 144 255 / 20%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -34,6 +34,8 @@ import {
|
||||||
TypographyText,
|
TypographyText,
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { BpmModelFormType } from '#/utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
APPROVE_METHODS,
|
APPROVE_METHODS,
|
||||||
APPROVE_TYPE,
|
APPROVE_TYPE,
|
||||||
|
@ -626,11 +628,9 @@ onMounted(() => {
|
||||||
name="roleIds"
|
name="roleIds"
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
filterable
|
|
||||||
v-model:value="configForm.roleIds"
|
v-model:value="configForm.roleIds"
|
||||||
clearable
|
clearable
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
style="width: 100%"
|
|
||||||
>
|
>
|
||||||
<SelectOption
|
<SelectOption
|
||||||
v-for="item in roleOptions"
|
v-for="item in roleOptions"
|
||||||
|
@ -664,10 +664,8 @@ onMounted(() => {
|
||||||
}"
|
}"
|
||||||
empty-text="加载中,请稍后"
|
empty-text="加载中,请稍后"
|
||||||
multiple
|
multiple
|
||||||
node-key="id"
|
|
||||||
:check-strictly="true"
|
:check-strictly="true"
|
||||||
allow-clear
|
allow-clear
|
||||||
style="width: 100%"
|
|
||||||
tree-checkable
|
tree-checkable
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
@ -677,11 +675,9 @@ onMounted(() => {
|
||||||
name="postIds"
|
name="postIds"
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
filterable
|
|
||||||
v-model:value="configForm.postIds"
|
v-model:value="configForm.postIds"
|
||||||
clearable
|
clearable
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
style="width: 100%"
|
|
||||||
>
|
>
|
||||||
<SelectOption
|
<SelectOption
|
||||||
v-for="item in postOptions"
|
v-for="item in postOptions"
|
||||||
|
@ -699,11 +695,9 @@ onMounted(() => {
|
||||||
name="userIds"
|
name="userIds"
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
filterable
|
|
||||||
v-model:value="configForm.userIds"
|
v-model:value="configForm.userIds"
|
||||||
clearable
|
clearable
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
style="width: 100%"
|
|
||||||
>
|
>
|
||||||
<SelectOption
|
<SelectOption
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
|
@ -723,11 +717,9 @@ onMounted(() => {
|
||||||
name="userGroups"
|
name="userGroups"
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
filterable
|
|
||||||
v-model:value="configForm.userGroups"
|
v-model:value="configForm.userGroups"
|
||||||
clearable
|
clearable
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
style="width: 100%"
|
|
||||||
>
|
>
|
||||||
<SelectOption
|
<SelectOption
|
||||||
v-for="item in userGroupOptions"
|
v-for="item in userGroupOptions"
|
||||||
|
@ -746,12 +738,7 @@ onMounted(() => {
|
||||||
label="表单内用户字段"
|
label="表单内用户字段"
|
||||||
name="formUser"
|
name="formUser"
|
||||||
>
|
>
|
||||||
<Select
|
<Select v-model:value="configForm.formUser" clearable>
|
||||||
filterable
|
|
||||||
v-model:value="configForm.formUser"
|
|
||||||
clearable
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<SelectOption
|
<SelectOption
|
||||||
v-for="(item, idx) in userFieldOnFormOptions"
|
v-for="(item, idx) in userFieldOnFormOptions"
|
||||||
:key="idx"
|
:key="idx"
|
||||||
|
@ -771,12 +758,7 @@ onMounted(() => {
|
||||||
label="表单内部门字段"
|
label="表单内部门字段"
|
||||||
name="formDept"
|
name="formDept"
|
||||||
>
|
>
|
||||||
<Select
|
<Select v-model:value="configForm.formDept" clearable>
|
||||||
filterable
|
|
||||||
v-model:value="configForm.formDept"
|
|
||||||
clearable
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<SelectOption
|
<SelectOption
|
||||||
v-for="(item, idx) in deptFieldOnFormOptions"
|
v-for="(item, idx) in deptFieldOnFormOptions"
|
||||||
:key="idx"
|
:key="idx"
|
||||||
|
@ -802,7 +784,7 @@ onMounted(() => {
|
||||||
:label="deptLevelLabel!"
|
:label="deptLevelLabel!"
|
||||||
name="deptLevel"
|
name="deptLevel"
|
||||||
>
|
>
|
||||||
<Select filterable v-model:value="configForm.deptLevel" clearable>
|
<Select v-model:value="configForm.deptLevel" clearable>
|
||||||
<SelectOption
|
<SelectOption
|
||||||
v-for="(item, index) in MULTI_LEVEL_DEPT"
|
v-for="(item, index) in MULTI_LEVEL_DEPT"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
@ -821,11 +803,7 @@ onMounted(() => {
|
||||||
label="流程表达式"
|
label="流程表达式"
|
||||||
name="expression"
|
name="expression"
|
||||||
>
|
>
|
||||||
<Textarea
|
<Textarea v-model:value="configForm.expression" clearable />
|
||||||
v-model:value="configForm.expression"
|
|
||||||
clearable
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<!-- 多人审批/办理 方式 -->
|
<!-- 多人审批/办理 方式 -->
|
||||||
<FormItem :label="`多人${nodeTypeName}方式`" name="approveMethod">
|
<FormItem :label="`多人${nodeTypeName}方式`" name="approveMethod">
|
||||||
|
@ -890,12 +868,7 @@ onMounted(() => {
|
||||||
label="驳回节点"
|
label="驳回节点"
|
||||||
name="returnNodeId"
|
name="returnNodeId"
|
||||||
>
|
>
|
||||||
<Select
|
<Select v-model:value="configForm.returnNodeId" clearable>
|
||||||
filterable
|
|
||||||
v-model:value="configForm.returnNodeId"
|
|
||||||
clearable
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<SelectOption
|
<SelectOption
|
||||||
v-for="item in returnTaskList"
|
v-for="item in returnTaskList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
@ -963,8 +936,7 @@ onMounted(() => {
|
||||||
<Col>
|
<Col>
|
||||||
<FormItem name="timeDuration">
|
<FormItem name="timeDuration">
|
||||||
<InputNumber
|
<InputNumber
|
||||||
class="mr-2"
|
class="mr-2 mt-0.5"
|
||||||
:style="{ width: '100px' }"
|
|
||||||
v-model:value="configForm.timeDuration"
|
v-model:value="configForm.timeDuration"
|
||||||
:min="1"
|
:min="1"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
|
@ -973,7 +945,6 @@ onMounted(() => {
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<Select
|
<Select
|
||||||
filterable
|
|
||||||
v-model:value="timeUnit"
|
v-model:value="timeUnit"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
:style="{ width: '100px' }"
|
:style="{ width: '100px' }"
|
||||||
|
@ -1040,11 +1011,9 @@ onMounted(() => {
|
||||||
name="assignEmptyHandlerUserIds"
|
name="assignEmptyHandlerUserIds"
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
filterable
|
|
||||||
v-model:value="configForm.assignEmptyHandlerUserIds"
|
v-model:value="configForm.assignEmptyHandlerUserIds"
|
||||||
clearable
|
clearable
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
style="width: 100%"
|
|
||||||
>
|
>
|
||||||
<SelectOption
|
<SelectOption
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
|
@ -1151,7 +1120,11 @@ onMounted(() => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane tab="表单字段权限" key="fields" v-if="formType === 10">
|
<TabPane
|
||||||
|
tab="表单字段权限"
|
||||||
|
key="fields"
|
||||||
|
v-if="formType === BpmModelFormType.NORMAL"
|
||||||
|
>
|
||||||
<div class="p-1">
|
<div class="p-1">
|
||||||
<div class="mb-4 text-[16px] font-bold">字段权限</div>
|
<div class="mb-4 text-[16px] font-bold">字段权限</div>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { SimpleFlowNode } from '../../consts';
|
||||||
|
|
||||||
|
import { inject, ref } from 'vue';
|
||||||
|
|
||||||
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
|
||||||
|
import { Input } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { NODE_DEFAULT_TEXT, NodeType } from '../../consts';
|
||||||
|
import { useNodeName2, useTaskStatusClass, useWatchNode } from '../../helpers';
|
||||||
|
import CopyTaskNodeConfig from '../nodes-config/copy-task-node-config.vue';
|
||||||
|
import NodeHandler from './node-handler.vue';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'CopyTaskNode',
|
||||||
|
});
|
||||||
|
const props = defineProps({
|
||||||
|
flowNode: {
|
||||||
|
type: Object as () => SimpleFlowNode,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// 定义事件,更新父组件。
|
||||||
|
const emits = defineEmits<{
|
||||||
|
'update:flowNode': [node: SimpleFlowNode | undefined];
|
||||||
|
}>();
|
||||||
|
// 是否只读
|
||||||
|
const readonly = inject<Boolean>('readonly');
|
||||||
|
// 监控节点的变化
|
||||||
|
const currentNode = useWatchNode(props);
|
||||||
|
// 节点名称编辑
|
||||||
|
const { showInput, blurEvent, clickTitle } = useNodeName2(
|
||||||
|
currentNode,
|
||||||
|
NodeType.COPY_TASK_NODE,
|
||||||
|
);
|
||||||
|
|
||||||
|
const nodeSetting = ref();
|
||||||
|
// 打开节点配置
|
||||||
|
const openNodeConfig = () => {
|
||||||
|
if (readonly) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nodeSetting.value.showCopyTaskNodeConfig(currentNode.value);
|
||||||
|
nodeSetting.value.openDrawer();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除节点。更新当前节点为孩子节点
|
||||||
|
const deleteNode = () => {
|
||||||
|
emits('update:flowNode', currentNode.value.childNode);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="node-wrapper">
|
||||||
|
<div class="node-container">
|
||||||
|
<div
|
||||||
|
class="node-box"
|
||||||
|
:class="[
|
||||||
|
{ 'node-config-error': !currentNode.showText },
|
||||||
|
`${useTaskStatusClass(currentNode?.activityStatus)}`,
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="node-title-container">
|
||||||
|
<div class="node-title-icon copy-task">
|
||||||
|
<span class="iconfont icon-copy"></span>
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
v-if="!readonly && showInput"
|
||||||
|
type="text"
|
||||||
|
class="editable-title-input"
|
||||||
|
@blur="blurEvent()"
|
||||||
|
v-model="currentNode.name"
|
||||||
|
:placeholder="currentNode.name"
|
||||||
|
/>
|
||||||
|
<div v-else class="node-title" @click="clickTitle">
|
||||||
|
{{ currentNode.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="node-content" @click="openNodeConfig">
|
||||||
|
<div
|
||||||
|
class="node-text"
|
||||||
|
:title="currentNode.showText"
|
||||||
|
v-if="currentNode.showText"
|
||||||
|
>
|
||||||
|
{{ currentNode.showText }}
|
||||||
|
</div>
|
||||||
|
<div class="node-text" v-else>
|
||||||
|
{{ NODE_DEFAULT_TEXT.get(NodeType.COPY_TASK_NODE) }}
|
||||||
|
</div>
|
||||||
|
<IconifyIcon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||||
|
</div>
|
||||||
|
<div v-if="!readonly" class="node-toolbar">
|
||||||
|
<div class="toolbar-icon">
|
||||||
|
<IconifyIcon
|
||||||
|
color="#0089ff"
|
||||||
|
icon="ep:circle-close-filled"
|
||||||
|
:size="18"
|
||||||
|
@click="deleteNode"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
|
||||||
|
<NodeHandler
|
||||||
|
v-if="currentNode"
|
||||||
|
v-model:child-node="currentNode.childNode"
|
||||||
|
:current-node="currentNode"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<CopyTaskNodeConfig
|
||||||
|
v-if="!readonly && currentNode"
|
||||||
|
ref="nodeSetting"
|
||||||
|
:flow-node="currentNode"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style lang="scss" scoped></style>
|
|
@ -3,6 +3,7 @@ import type { SimpleFlowNode } from '../consts';
|
||||||
|
|
||||||
import { NodeType } from '../consts';
|
import { NodeType } from '../consts';
|
||||||
import { useWatchNode } from '../helpers';
|
import { useWatchNode } from '../helpers';
|
||||||
|
import CopyTaskNode from './nodes/copy-task-node.vue';
|
||||||
import EndEventNode from './nodes/end-event-node.vue';
|
import EndEventNode from './nodes/end-event-node.vue';
|
||||||
import StartUserNode from './nodes/start-user-node.vue';
|
import StartUserNode from './nodes/start-user-node.vue';
|
||||||
import UserTaskNode from './nodes/user-task-node.vue';
|
import UserTaskNode from './nodes/user-task-node.vue';
|
||||||
|
@ -77,11 +78,11 @@ const recursiveFindParentNode = (
|
||||||
@find-parent-node="findParentNode"
|
@find-parent-node="findParentNode"
|
||||||
/>
|
/>
|
||||||
<!-- 抄送节点 -->
|
<!-- 抄送节点 -->
|
||||||
<!-- <CopyTaskNode
|
<CopyTaskNode
|
||||||
v-if="currentNode && currentNode.type === NodeType.COPY_TASK_NODE"
|
v-if="currentNode && currentNode.type === NodeType.COPY_TASK_NODE"
|
||||||
:flow-node="currentNode"
|
:flow-node="currentNode"
|
||||||
@update:flow-node="handleModelValueUpdate"
|
@update:flow-node="handleModelValueUpdate"
|
||||||
/> -->
|
/>
|
||||||
<!-- 条件节点 -->
|
<!-- 条件节点 -->
|
||||||
<!-- <ExclusiveNode
|
<!-- <ExclusiveNode
|
||||||
v-if="currentNode && currentNode.type === NodeType.CONDITION_BRANCH_NODE"
|
v-if="currentNode && currentNode.type === NodeType.CONDITION_BRANCH_NODE"
|
||||||
|
|
Loading…
Reference in New Issue