<script lang="ts" setup>
|
import type { DmsAccessExclusionBatch, DmsPermissionResource } from '#/api/x/dms/permission';
|
|
import { computed, ref } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
import { BasicDrawer, useDrawerInner } from '@jnpf/ui/drawer';
|
import { BasicForm, useForm } from '@jnpf/ui/form';
|
|
import dayjs from 'dayjs';
|
import { v4 as uuidv4 } from 'uuid';
|
|
import { createAccessExclusions } from '#/api/x/dms/permission';
|
import { onlineUtils } from '#/utils/jnpf';
|
|
import { canExcludeRead, normalizePrincipalId, permissionDateToIso, permissionResourceDisplayName } from './permissionRules';
|
|
interface ExclusionFormState {
|
excludeReason: string;
|
userId?: string;
|
validity?: [number, number];
|
}
|
|
const emit = defineEmits<{
|
reload: [];
|
}>();
|
|
const resource = ref<DmsPermissionResource>();
|
const sourceId = ref('');
|
const { createMessage } = useMessage();
|
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
|
baseColProps: { span: 24 },
|
layout: 'vertical',
|
schemas: [
|
{
|
field: 'userId',
|
label: '排除用户',
|
component: 'UserSelect',
|
rules: [{ required: true, message: '请选择需要排除的用户', trigger: 'change' }],
|
},
|
{
|
field: 'validity',
|
label: '有效期',
|
component: 'DateRange',
|
componentProps: () => ({ format: 'YYYY-MM-DD HH:mm', placeholder: ['开始时间', '结束时间'], startTime: dayjs().startOf('day').valueOf() }),
|
extra: '不填写表示立即生效且长期有效。',
|
},
|
{
|
field: 'excludeReason',
|
label: '排除原因',
|
component: 'Textarea',
|
componentProps: { maxlength: 1000, placeholder: '说明拒绝该用户读取的原因', rows: 4, showCount: true },
|
},
|
],
|
showActionButtonGroup: false,
|
});
|
const [registerDrawer, { changeOkLoading, closeDrawer }] = useDrawerInner(init);
|
|
const exclusionScope = computed(() => (resource.value?.resourceType === 'DOCUMENT' ? '该文件及其全部版本' : '当前指定文件版本'));
|
|
function defaultForm(): ExclusionFormState {
|
return {
|
excludeReason: '',
|
};
|
}
|
|
function newSourceId() {
|
return `manual-exclusion-${uuidv4()}`;
|
}
|
|
async function init(data: { resource: DmsPermissionResource }) {
|
if (!canExcludeRead(data.resource.resourceType)) return;
|
resource.value = data.resource;
|
sourceId.value = newSourceId();
|
await resetFields();
|
await setFieldsValue(defaultForm());
|
}
|
|
async function handleSubmit() {
|
if (!resource.value || !canExcludeRead(resource.value.resourceType)) return;
|
const values = await validate();
|
if (!values) return;
|
const form = values as ExclusionFormState;
|
const currentResource = resource.value;
|
const data: DmsAccessExclusionBatch = {
|
sourceId: sourceId.value,
|
sourceType: 'MANUAL',
|
items: [
|
{
|
excludeReason: form.excludeReason.trim() || undefined,
|
resourceId: currentResource.id,
|
resourceType: currentResource.resourceType as 'DOCUMENT' | 'FILE_VERSION',
|
userId: normalizePrincipalId(form.userId || ''),
|
validFrom: permissionDateToIso(form.validity?.[0]),
|
validTo: permissionDateToIso(form.validity?.[1]),
|
},
|
],
|
};
|
onlineUtils.sign({
|
title: '电子签名',
|
isFaceToFace: false,
|
metaData: {
|
biz_button: '排除拒绝',
|
biz_data: [data],
|
biz_module: '文件夹权限管理',
|
biz_title: currentResource.fileName || currentResource.name,
|
is_biz_form: false,
|
is_review_button: false,
|
},
|
onCancel: () => {},
|
onSubmit: (signData) => submitExclusions(data, signData?.biz_sign),
|
});
|
}
|
|
async function submitExclusions(data: DmsAccessExclusionBatch, bizSign?: string) {
|
changeOkLoading(true);
|
try {
|
const response = await createAccessExclusions(data, bizSign);
|
createMessage.success(response.msg || `已创建 ${response.data.length} 条读取排除`);
|
closeDrawer();
|
emit('reload');
|
} finally {
|
changeOkLoading(false);
|
}
|
}
|
</script>
|
|
<template>
|
<BasicDrawer
|
v-bind="$attrs"
|
@register="registerDrawer"
|
title="新增排除拒绝"
|
width="min(620px, calc(100vw - 16px))"
|
:mask-closable="false"
|
destroy-on-close
|
show-footer
|
@ok="handleSubmit">
|
<div v-if="resource" class="exclusion-drawer-body">
|
<a-alert class="mb-[20px]" type="warning" show-icon>
|
<template #message> 排除资源:{{ permissionResourceDisplayName(resource) }} </template>
|
<template #description> 对指定用户拒绝读取{{ exclusionScope }}。即使用户同时拥有目录或文件的允许权限,排除拒绝也优先生效。 </template>
|
</a-alert>
|
<BasicForm @register="registerForm" />
|
</div>
|
</BasicDrawer>
|
</template>
|
|
<style lang="scss" scoped>
|
.exclusion-drawer-body {
|
padding: 20px 24px 28px;
|
}
|
</style>
|