feat: 允许流程在某个节点单独控制是否可以明细表新加行

This commit is contained in:
gaoyunqi
2024-05-07 17:14:53 +08:00
parent 2994590e20
commit 30972d5881
3 changed files with 456 additions and 464 deletions

View File

@ -1,500 +1,485 @@
<template>
<div class="list-box">
<div class="opr-box">
<NodeHead :nodeName="t('表单列表')" />
<div class="button-box">
<SettingModal :list="[]" :isSingle="false" @submit="addItem">
<a-button type="primary">{{ t('添加表单') }}</a-button>
</SettingModal>
</div>
</div>
<div class="list">
<div class="row head">
<span class="up-or-down"></span>
<span class="form-name">{{ t('表单名称') }}</span>
<span class="form-type">{{ t('表单类型') }}</span>
<span class="opr">{{ t('操作') }}</span>
</div>
<div class="body" v-if="formSetting.list.length > 0">
<div class="box" v-for="(item, index) in formSetting.list" :key="index">
<div class="row item">
<div class="up-or-down" @click="item.showChildren = !item.showChildren">
<Icon
class="icon"
:icon="item.showChildren ? 'ant-design:up-outlined' : 'ant-design:down-outlined'"
/>
<div class="list-box">
<div class="opr-box">
<NodeHead :nodeName="t('表单列表')" />
<div class="button-box">
<SettingModal :isSingle="false" :list="[]" @submit="addItem">
<a-button type="primary">{{ t('添加表单') }}</a-button>
</SettingModal>
</div>
<span class="form-name">{{ item.formName }}</span>
<span class="form-type">{{ formTypeOptions[item.formType] }}</span>
<span class="opr">
<a-popconfirm @confirm="deleteItem(index)">
<template #title>
<div style="width: 300px">
<p>{{ t('删除表单') }}</p>
<p>{{ t('删除表单会清空已引用该表单数据的所有配置,请确认是否继续?') }}</p>
<p class="pop-desc">{{
t('如果引用该表单的配置较多,清空时间会相应变长,请耐心等待。')
}}</p>
</div>
</template>
<Icon icon="ant-design:delete-outlined" class="delete-icon" />
</a-popconfirm>
</span>
</div>
<div
class="children list"
v-if="item.showChildren && item.children && item.children.length > 0"
>
<div class="row head">
<span class="flex-baisc-4"></span>
<span>{{ t('字段名') }}</span>
<span>{{ t('字段ID') }}</span>
<span
><a-checkbox
v-model:checked="item.requiredAll"
size="small"
@change="requiredAll(item)"
>{{ t('必填') }}</a-checkbox
></span
>
<span
><a-checkbox v-model:checked="item.viewAll" size="small" @change="viewAll(item)">{{
t('查看')
}}</a-checkbox></span
>
<span
><a-checkbox v-model:checked="item.editAll" size="small" @change="editAll(item)">{{
t('编辑')
}}</a-checkbox></span
>
</div>
<div class="body" v-if="item.children.length > 0">
<div
v-for="(child, childIndex) in item.children"
:key="childIndex"
class="padding-left"
>
<div class="row item" v-if="child.type != hiddenComponentType">
<span
><em
class="flex-baisc-4"
v-if="child.isSubTable"
@click="child.showChildren = !child.showChildren"
>
<Icon
class="icon"
:icon="
child.showChildren ? 'ant-design:up-outlined' : 'ant-design:down-outlined'
"
/> </em
>{{ child.fieldName }}</span
>
<span>{{ child.fieldId }}</span>
<span>
<a-switch
v-if="!child.isSubTable && !doNotShowControl.includes(child.type)"
v-model:checked="child.required"
:disabled="requiredDisabled.includes(child.type) || child.isSaveTable"
@change="TableRequired(child.required, child, item)"
size="small"
/></span>
<span>
<a-switch
v-model:checked="child.view"
size="small"
@change="TableView(child.view, child, item)"
/></span>
<span
><a-switch
v-if="!child.isSubTable && !doNotShowControl.includes(child.type)"
:disabled="child.disabled"
v-model:checked="child.edit"
@change="TableEdit(child.edit, child, item)"
size="small"
/></span>
</div>
<template
v-if="child.showChildren && child.isSubTable && child.children.length > 0"
>
<div
class="row item padding-left"
v-for="(child2, childIndex2) in child.children"
:key="childIndex2"
>
<span>{{ child2.fieldName }}</span>
<span>{{ child2.fieldId }}</span>
<span
><a-switch
:disabled="child2.disabled || child2.isSaveTable"
v-model:checked="child2.required"
@change="TableRequired(child2.required, child2, item, child)"
size="small"
/></span>
<span
><a-switch
:disabled="child2.disabled"
v-model:checked="child2.view"
@change="TableView(child2.view, child2, item, child)"
size="small"
/></span>
<span
><a-switch
:disabled="child2.disabled || child2.isSaveTable"
v-model:checked="child2.edit"
@change="TableEdit(child2.edit, child2, item, child)"
size="small"
/></span>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
<div class="list">
<div class="row head">
<span class="up-or-down"></span>
<span class="form-name">{{ t('表单名称') }}</span>
<span class="form-type">{{ t('表单类型') }}</span>
<span class="opr">{{ t('操作') }}</span>
</div>
<div v-if="formSetting.list.length > 0" class="body">
<div v-for="(item, index) in formSetting.list" :key="index" class="box">
<div class="row item">
<div class="up-or-down" @click="item.showChildren = !item.showChildren">
<Icon :icon="item.showChildren ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" class="icon" />
</div>
<span class="form-name">{{ item.formName }}</span>
<span class="form-type">{{ formTypeOptions[item.formType] }}</span>
<span class="opr">
<a-popconfirm @confirm="deleteItem(index)">
<template #title>
<div style="width: 300px">
<p>{{ t('删除表单') }}</p>
<p>{{ t('删除表单会清空已引用该表单数据的所有配置,请确认是否继续?') }}</p>
<p class="pop-desc">{{ t('如果引用该表单的配置较多,清空时间会相应变长,请耐心等待。') }}</p>
</div>
</template>
<Icon class="delete-icon" icon="ant-design:delete-outlined" />
</a-popconfirm>
</span>
</div>
<div v-if="item.showChildren && item.children && item.children.length > 0" class="children list">
<div class="row head">
<span class="flex-baisc-4"></span>
<span>{{ t('字段名') }}</span>
<span>{{ t('字段ID') }}</span>
<span>
<a-checkbox v-model:checked="item.requiredAll" size="small" @change="requiredAll(item)">{{ t('必填') }}</a-checkbox>
</span>
<span>
<a-checkbox v-model:checked="item.viewAll" size="small" @change="viewAll(item)">{{ t('查看') }}</a-checkbox>
</span>
<span>
<a-checkbox v-model:checked="item.editAll" size="small" @change="editAll(item)">{{ t('编辑') }}</a-checkbox>
</span>
</div>
<div v-if="item.children.length > 0" class="body">
<div v-for="(child, childIndex) in item.children" :key="childIndex" class="padding-left">
<div v-if="child.type != hiddenComponentType" class="row item">
<span>
<em v-if="child.isSubTable" class="flex-baisc-4" @click="child.showChildren = !child.showChildren"> <Icon :icon="child.showChildren ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" class="icon" /> </em
>{{ child.fieldName }}
</span>
<span>{{ child.fieldId }}</span>
<span>
<a-switch
v-if="!child.isSubTable && !doNotShowControl.includes(child.type)"
v-model:checked="child.required"
:disabled="requiredDisabled.includes(child.type) || child.isSaveTable"
size="small"
@change="TableRequired(child.required, child, item)"
/>
</span>
<span><a-switch v-model:checked="child.view" size="small" @change="TableView(child.view, child, item)" /></span>
<span><a-switch v-if="!child.isSubTable && !doNotShowControl.includes(child.type)" v-model:checked="child.edit" :disabled="child.disabled" size="small" @change="TableEdit(child.edit, child, item)" /></span>
</div>
<template v-if="child.showChildren && child.isSubTable && child.children.length > 0">
<div v-for="(child2, childIndex2) in child.children" :key="childIndex2" class="row item padding-left">
<span>{{ child2.fieldName }}</span>
<span>{{ child2.fieldId }}</span>
<span>
<a-switch v-model:checked="child2.required" :disabled="child2.disabled || child2.isSaveTable || child2.fieldId === ROW_CTRL" size="small" @change="TableRequired(child2.required, child2, item, child)" />
</span>
<span>
<a-switch v-model:checked="child2.view" :disabled="child2.disabled || child2.fieldId === ROW_CTRL" size="small" @change="TableView(child2.view, child2, item, child)" />
</span>
<span>
<a-switch v-model:checked="child2.edit" :disabled="child2.disabled || child2.isSaveTable" size="small" @change="TableEdit(child2.edit, child2, item, child)" />
</span>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
<EmptyBox v-else :has-icon="false" />
<EmptyBox v-else :has-icon="false" />
</div>
</div>
</div>
</template>
<script setup lang="ts">
import useStateFormInfo from '/@bpmn/hooks/useStateFormInfo';
import Icon from '/@/components/Icon/index';
import { NodeHead, EmptyBox } from '/@/components/ModalPanel/index';
import SettingModal from '/@bpmn/components/formSettings/SettingModal.vue';
import { FormType } from '/@/enums/workflowEnum';
import { FormConfigItem } from '/@/model/workflow/formSetting';
<script lang="ts" setup>
import useStateFormInfo from '/@bpmn/hooks/useStateFormInfo';
import Icon from '/@/components/Icon/index';
import { NodeHead, EmptyBox } from '/@/components/ModalPanel/index';
import SettingModal from '/@bpmn/components/formSettings/SettingModal.vue';
import { FormType } from '/@/enums/workflowEnum';
import { FormConfigItem } from '/@/model/workflow/formSetting';
import { onMounted, reactive } from 'vue';
import {
formPermissionList,
hiddenComponentType,
requiredDisabled,
doNotShowControl,
} from '/@bpmn/config/formPermission';
import { updateFormDataInfo } from '/@bpmn/config/useUpdateAllFormInfo';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const { formInfo } = useStateFormInfo();
const formTypeOptions = {};
formTypeOptions[FormType.CUSTOM] = t('自定义表单');
formTypeOptions[FormType.SYSTEM] = t('系统表单');
let formSetting: { list: Array<FormConfigItem> } = reactive({ list: [] });
import { onMounted, reactive } from 'vue';
import { formPermissionList, hiddenComponentType, requiredDisabled, doNotShowControl } from '/@bpmn/config/formPermission';
import { updateFormDataInfo } from '/@bpmn/config/useUpdateAllFormInfo';
import { useI18n } from '/@/hooks/web/useI18n';
import { buildUUID } from '/@/utils/uuid';
onMounted(() => {
if (formInfo.value.formConfigs) formSetting.list = formInfo.value.formConfigs;
formSetting.list.forEach((val) => {
checkIsAll(val);
const { t } = useI18n();
const { formInfo } = useStateFormInfo();
const formTypeOptions = {};
const ROW_CTRL = '_row_ctrl_';
formTypeOptions[FormType.CUSTOM] = t('自定义表单');
formTypeOptions[FormType.SYSTEM] = t('系统表单');
let formSetting: { list: Array<FormConfigItem> } = reactive({ list: [] });
onMounted(() => {
if (formInfo.value.formConfigs) formSetting.list = formInfo.value.formConfigs;
formSetting.list.forEach((val) => {
addTableRowCtrl();
checkIsAll(val);
});
});
});
function deleteItem(index: number) {
updateFormDataInfo(formSetting.list[index]['key']);
formSetting.list.splice(index, 1);
}
async function addItem(list: Array<FormConfigItem>) {
let returnArr = await formPermissionList(list);
returnArr.forEach((val) => {
checkIsAll(val);
});
formSetting.list.push(...returnArr);
}
function requiredAll(item) {
// 必填所有为true 所有的必填编辑查看都为true除了disabled
// 必填所有为false 所有必填都取消除了disabled
let requiredAll = item.requiredAll;
if (requiredAll) {
item.viewAll = true;
item.editAll = true;
function addTableRowCtrl() {
formSetting.list.forEach((form) => {
recAddTableRowCtrl(form);
});
}
item.children = item.children.map((ele) => {
if (!ele.disabled) {
function recAddTableRowCtrl(parent) {
if (parent.isSubTable) {
if (!parent.children || parent.children.length === 0) {
return;
}
const hasRowCtrl = parent.children.find((item) => item.fieldId === '_row_ctrl_');
if (!hasRowCtrl) {
parent.children.push({
disabled: false,
edit: true,
fieldId: ROW_CTRL,
fieldName: '添加新行*',
isSaveTable: false,
isSubTable: true,
key: buildUUID(),
required: false,
showChildren: false,
tableName: parent.tableName,
view: true
});
}
return;
}
if (parent.children && parent.children.length) {
parent.children.forEach((child) => {
recAddTableRowCtrl(child);
});
return;
}
}
function deleteItem(index: number) {
updateFormDataInfo(formSetting.list[index]['key']);
formSetting.list.splice(index, 1);
}
async function addItem(list: Array<FormConfigItem>) {
let returnArr = await formPermissionList(list);
returnArr.forEach((val) => {
checkIsAll(val);
});
formSetting.list.push(...returnArr);
}
function requiredAll(item) {
// 必填所有为true 所有的必填编辑查看都为true除了disabled
// 必填所有为false 所有必填都取消除了disabled
let requiredAll = item.requiredAll;
if (requiredAll) {
ele.required = true;
ele.edit = true;
} else {
ele.required = false;
item.viewAll = true;
item.editAll = true;
}
}
if (requiredAll) ele.view = true;
if (ele.children && ele.children.length > 0) {
ele.children.map(
(ele2: { disabled: any; required: boolean; view: boolean; edit: boolean }) => {
if (!ele2.disabled) {
if (requiredAll) {
ele2.required = true;
ele2.edit = true;
} else {
ele2.required = false;
}
item.children = item.children.map((ele) => {
if (!ele.disabled) {
if (requiredAll) {
ele.required = true;
ele.edit = true;
} else {
ele.required = false;
}
}
if (requiredAll) ele2.view = true;
},
);
}
return ele;
});
}
function editAll(item) {
// 编辑所有为true 所有的编辑查看都为true除了disabled
// 编辑所有为false 所有编辑都为false除了disabled
let editAll = item.editAll;
if (editAll) {
item.viewAll = true;
} else {
item.requiredAll = false;
if (requiredAll) ele.view = true;
if (ele.children && ele.children.length > 0) {
ele.children.map((ele2: { disabled: any; required: boolean; view: boolean; edit: boolean }) => {
if (ele2.fieldId === ROW_CTRL) {
return;
}
if (!ele2.disabled) {
if (requiredAll) {
ele2.required = true;
ele2.edit = true;
} else {
ele2.required = false;
}
}
if (requiredAll) ele2.view = true;
});
}
return ele;
});
}
item.children = item.children.map((ele) => {
if (!ele.disabled) {
function editAll(item) {
// 编辑所有为true 所有的编辑查看都为true除了disabled
// 编辑所有为false 所有编辑都为false除了disabled
let editAll = item.editAll;
if (editAll) {
ele.edit = true;
item.viewAll = true;
} else {
ele.edit = false;
ele.required = false;
item.requiredAll = false;
}
}
if (editAll) ele.view = true;
if (ele.children && ele.children.length > 0) {
ele.children.map(
(ele2: { disabled: any; required: boolean; view: boolean; edit: boolean }) => {
if (!ele2.disabled) {
if (editAll) {
ele2.edit = true;
} else {
ele2.edit = false;
ele2.required = false;
}
item.children = item.children.map((ele) => {
if (!ele.disabled) {
if (editAll) {
ele.edit = true;
} else {
ele.edit = false;
ele.required = false;
}
}
if (editAll) ele2.view = true;
},
);
}
return ele;
});
}
function viewAll(item) {
// 查看所有为true 所有的查看都为true除了disabled
// 查看所有为false 所有查看都为false除了disabled
let viewAll = item.viewAll;
if (!viewAll) {
item.requiredAll = false;
item.editAll = false;
}
item.children = item.children.map((ele) => {
if (viewAll) {
ele.view = true;
} else {
ele.view = false;
ele.edit = false;
ele.required = false;
}
if (ele.children && ele.children.length > 0) {
ele.children.map((ele2) => {
if (viewAll) {
ele2.view = true;
} else {
ele2.view = false;
ele2.edit = false;
ele2.required = false;
}
if (editAll) ele.view = true;
if (ele.children && ele.children.length > 0) {
ele.children.map((ele2: { disabled: any; required: boolean; view: boolean; edit: boolean }) => {
if (!ele2.disabled) {
if (editAll) {
ele2.edit = true;
} else {
ele2.edit = false;
ele2.required = false;
}
}
if (editAll) ele2.view = true;
});
}
return ele;
});
}
return ele;
});
}
function TableRequired(required, child, item, cur?) {
if (required) {
child.view = true;
child.edit = true;
}
checkIsAll(item);
if (cur) {
checkCurTableIsEdit(cur);
}
}
function TableView(view, child, item, cur?) {
if (!view) {
child.required = view;
child.view = view;
child.edit = view;
}
if (child.children?.length > 0) {
child.children.forEach((o) => {
if (!view) {
o.required = view;
o.view = view;
o.edit = view;
} else {
o.view = view;
o.edit = view;
function viewAll(item) {
// 查看所有为true 所有的查看都为true除了disabled
// 查看所有为false 所有查看都为false除了disabled
let viewAll = item.viewAll;
if (!viewAll) {
item.requiredAll = false;
item.editAll = false;
}
});
}
checkIsAll(item);
if (cur) {
checkCurTableIsEdit(cur);
}
}
function TableEdit(edit, child, item, cur?) {
if (edit) {
child.view = true;
} else {
child.required = false;
}
checkIsAll(item);
if (cur) {
checkCurTableIsEdit(cur);
}
}
function checkCurTableIsEdit(item) {
let view = 0;
let edit = 0;
item.children.map((ele) => {
if (ele.view) view += 1;
if (ele.edit || ele.disabled) edit += 1;
});
item.view = view > 0 ? true : false;
item.edit = edit > 0 ? true : false;
}
function checkIsAll(item) {
let all = 0;
let required = 0;
let view = 0;
let edit = 0;
item.children.map((ele) => {
all += 1;
if (ele.required || ele.disabled) required += 1;
if (ele.view) view += 1;
if (ele.edit || ele.disabled) edit += 1;
if (ele.children && ele.children.length > 0) {
let childView = 0;
ele.children.map((ele2) => {
all += 1;
if (ele2.required || ele2.disabled) required += 1;
if (ele2.view) {
view += 1;
childView += 1;
}
if (ele2.edit || ele2.disabled) edit += 1;
item.children = item.children.map((ele) => {
if (viewAll) {
ele.view = true;
} else {
ele.view = false;
ele.edit = false;
ele.required = false;
}
if (ele.children && ele.children.length > 0) {
ele.children.map((ele2) => {
if (ele2.fieldId === ROW_CTRL) {
return;
}
if (viewAll) {
ele2.view = true;
} else {
ele2.view = false;
ele2.edit = false;
ele2.required = false;
}
});
}
return ele;
});
ele.view = childView > 0 ? true : false;
}
});
}
item.requiredAll = required == all ? true : false;
item.viewAll = view == all ? true : false;
item.editAll = edit == all ? true : false;
function TableRequired(required, child, item, cur?) {
if (required) {
child.view = true;
child.edit = true;
}
checkIsAll(item);
if (cur) {
checkCurTableIsEdit(cur);
}
}
// if (item.editAll) {
// item.viewAll = true;
// viewAll(item);
// }
//if (item.requiredAll) {
// item.viewAll = true;
// item.editAll = true;
// viewAll(item);
// editAll(item);
//}
}
function TableView(view, child, item, cur?) {
if (!view) {
child.required = view;
child.view = view;
child.edit = view;
}
if (child.children?.length > 0) {
child.children.forEach((o) => {
if (!view) {
o.required = view;
o.view = view;
o.edit = view;
} else {
o.view = view;
o.edit = view;
}
});
}
checkIsAll(item);
if (cur) {
checkCurTableIsEdit(cur);
}
}
function TableEdit(edit, child, item, cur?) {
if (edit) {
child.view = true;
} else {
child.required = false;
}
checkIsAll(item);
if (cur) {
checkCurTableIsEdit(cur);
}
}
function checkCurTableIsEdit(item) {
let view = 0;
let edit = 0;
item.children.map((ele) => {
if (ele.view) view += 1;
if (ele.edit || ele.disabled) edit += 1;
});
item.view = view > 0 ? true : false;
item.edit = edit > 0 ? true : false;
}
function checkIsAll(item) {
let all = 0;
let required = 0;
let view = 0;
let edit = 0;
item.children.map((ele) => {
all += 1;
if (ele.required || ele.disabled) required += 1;
if (ele.view) view += 1;
if (ele.edit || ele.disabled) edit += 1;
if (ele.children && ele.children.length > 0) {
let childView = 0;
ele.children.map((ele2) => {
all += 1;
if (ele2.required || ele2.disabled) required += 1;
if (ele2.view) {
view += 1;
childView += 1;
}
if (ele2.edit || ele2.disabled) edit += 1;
});
ele.view = childView > 0 ? true : false;
}
});
item.requiredAll = required == all ? true : false;
item.viewAll = view == all ? true : false;
item.editAll = edit == all ? true : false;
// if (item.editAll) {
// item.viewAll = true;
// viewAll(item);
// }
//if (item.requiredAll) {
// item.viewAll = true;
// item.editAll = true;
// viewAll(item);
// editAll(item);
//}
}
</script>
<style lang="less" scoped>
.list-box {
.opr-box {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
}
.list {
.row {
height: 40px;
line-height: 30px;
display: flex;
justify-content: center;
align-items: center;
span {
flex-basis: 20%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
.up-or-down {
flex-basis: 30px;
margin-left: 8px;
}
.form-name {
flex: 1;
}
.form-type {
flex-basis: 80px;
}
.opr {
flex-basis: 80px;
}
.small {
flex-basis: 60px;
}
.flex-baisc-35 {
flex-basis: 120px;
}
.flex-baisc-4 {
flex-basis: 40px;
}
.icon {
color: #ccc;
}
.list-box {
.opr-box {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
}
.padding-left {
padding-left: 40px;
.list {
.row {
height: 40px;
line-height: 30px;
display: flex;
justify-content: center;
align-items: center;
span {
flex-basis: 20%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
.up-or-down {
flex-basis: 30px;
margin-left: 8px;
}
.form-name {
flex: 1;
}
.form-type {
flex-basis: 80px;
}
.opr {
flex-basis: 80px;
}
.small {
flex-basis: 60px;
}
.flex-baisc-35 {
flex-basis: 120px;
}
.flex-baisc-4 {
flex-basis: 40px;
}
.icon {
color: #ccc;
}
}
.padding-left {
padding-left: 40px;
}
.head {
background-color: #f9f9f9;
}
.item {
border-bottom: 1px solid #f9f9f9;
}
.delete-icon {
color: @clear-color;
}
.empty-box {
height: 200px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #f9f9f9;
border-top: none;
}
}
.head {
background-color: #f9f9f9;
:deep(.slot-item) {
display: inline;
}
.item {
border-bottom: 1px solid #f9f9f9;
.pop-desc {
font-size: 12px;
color: rgb(0 0 0 / 40%);
}
.delete-icon {
color: @clear-color;
}
.empty-box {
height: 200px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #f9f9f9;
border-top: none;
}
}
:deep(.slot-item) {
display: inline;
}
.pop-desc {
font-size: 12px;
color: rgb(0 0 0 / 40%);
}
</style>