13 changed files with 421 additions and 51 deletions
@ -0,0 +1,119 @@ |
|||||
|
<script setup lang="ts"> |
||||
|
import type { IdentityUserClaimDto } from '../../types/users'; |
||||
|
|
||||
|
import { useVbenForm, useVbenModal } from '@vben/common-ui'; |
||||
|
import { $t } from '@vben/locales'; |
||||
|
|
||||
|
import { getAssignableClaimsApi } from '../../api/claim-types'; |
||||
|
import { createClaimApi, updateClaimApi } from '../../api/users'; |
||||
|
|
||||
|
interface IdentityUserClaimVto extends IdentityUserClaimDto { |
||||
|
userId: string; |
||||
|
} |
||||
|
|
||||
|
const emits = defineEmits<{ |
||||
|
(event: 'change', data: IdentityUserClaimDto): void; |
||||
|
}>(); |
||||
|
|
||||
|
const [Form, formApi] = useVbenForm({ |
||||
|
commonConfig: { |
||||
|
// 所有表单项 |
||||
|
componentProps: { |
||||
|
class: 'w-full', |
||||
|
}, |
||||
|
}, |
||||
|
handleSubmit: onSubmit, |
||||
|
schema: [ |
||||
|
{ |
||||
|
component: 'Select', |
||||
|
fieldName: 'claimType', |
||||
|
label: $t('AbpIdentity.DisplayName:ClaimType'), |
||||
|
rules: 'required', |
||||
|
}, |
||||
|
{ |
||||
|
component: 'Textarea', |
||||
|
fieldName: 'claimValue', |
||||
|
label: $t('AbpIdentity.DisplayName:ClaimValue'), |
||||
|
rules: 'required', |
||||
|
}, |
||||
|
], |
||||
|
showDefaultActions: false, |
||||
|
}); |
||||
|
const [Modal, modalApi] = useVbenModal({ |
||||
|
draggable: true, |
||||
|
fullscreenButton: false, |
||||
|
async onConfirm() { |
||||
|
await formApi.validateAndSubmitForm(); |
||||
|
}, |
||||
|
async onOpenChange(isOpen: boolean) { |
||||
|
if (isOpen) { |
||||
|
try { |
||||
|
modalApi.setState({ loading: true }); |
||||
|
const claimVto = modalApi.getData<IdentityUserClaimVto>(); |
||||
|
formApi.setValues({ |
||||
|
...claimVto, |
||||
|
newClaimValue: claimVto.claimValue, |
||||
|
}); |
||||
|
// 新增可选, 修改不可选 |
||||
|
formApi.updateSchema([ |
||||
|
{ |
||||
|
disabled: !!claimVto.id, |
||||
|
fieldName: 'claimType', |
||||
|
}, |
||||
|
]); |
||||
|
// 新增时初始化可选声明 |
||||
|
!claimVto.id && (await initAssignableClaims()); |
||||
|
} finally { |
||||
|
modalApi.setState({ loading: false }); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
title: $t('AbpIdentity.ManageClaim'), |
||||
|
}); |
||||
|
/** 初始化可用声明类型 */ |
||||
|
async function initAssignableClaims() { |
||||
|
const { items } = await getAssignableClaimsApi(); |
||||
|
formApi.updateSchema([ |
||||
|
{ |
||||
|
componentProps: { |
||||
|
fieldNames: { |
||||
|
label: 'name', |
||||
|
value: 'name', |
||||
|
}, |
||||
|
options: items, |
||||
|
}, |
||||
|
fieldName: 'claimType', |
||||
|
}, |
||||
|
]); |
||||
|
} |
||||
|
/** 提交声明类型变更 */ |
||||
|
async function onSubmit(values: Record<string, any>) { |
||||
|
try { |
||||
|
modalApi.setState({ confirmLoading: true }); |
||||
|
const claimVto = modalApi.getData<IdentityUserClaimVto>(); |
||||
|
const api = claimVto.id |
||||
|
? updateClaimApi(claimVto.userId, { |
||||
|
claimType: claimVto.claimType, |
||||
|
claimValue: claimVto.claimValue, |
||||
|
newClaimValue: values.claimValue, |
||||
|
}) |
||||
|
: createClaimApi(claimVto.userId, { |
||||
|
claimType: values.claimType, |
||||
|
claimValue: values.claimValue, |
||||
|
}); |
||||
|
await api; |
||||
|
emits('change', values as IdentityUserClaimDto); |
||||
|
modalApi.close(); |
||||
|
} finally { |
||||
|
modalApi.setState({ confirmLoading: false }); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<Modal> |
||||
|
<Form /> |
||||
|
</Modal> |
||||
|
</template> |
||||
|
|
||||
|
<style scoped></style> |
||||
@ -0,0 +1,159 @@ |
|||||
|
<script setup lang="ts"> |
||||
|
import type { VxeGridProps } from '@abp/ui'; |
||||
|
|
||||
|
import type { IdentityUserClaimDto, IdentityUserDto } from '../../types'; |
||||
|
|
||||
|
import { defineAsyncComponent, h } from 'vue'; |
||||
|
|
||||
|
import { useVbenModal } from '@vben/common-ui'; |
||||
|
import { $t } from '@vben/locales'; |
||||
|
|
||||
|
import { useVbenVxeGrid } from '@abp/ui'; |
||||
|
import { DeleteOutlined, EditOutlined } from '@ant-design/icons-vue'; |
||||
|
import { Button, Popconfirm } from 'ant-design-vue'; |
||||
|
|
||||
|
import { deleteClaimApi, getClaimsApi } from '../../api/users'; |
||||
|
import { IdentityUserPermissions } from '../../constants/permissions'; |
||||
|
|
||||
|
const ClaimEditModal = defineAsyncComponent( |
||||
|
() => import('./UserClaimEditModal.vue'), |
||||
|
); |
||||
|
|
||||
|
const [Modal, modalApi] = useVbenModal({ |
||||
|
draggable: true, |
||||
|
fullscreenButton: false, |
||||
|
onCancel() { |
||||
|
modalApi.close(); |
||||
|
}, |
||||
|
onConfirm: async () => {}, |
||||
|
showCancelButton: false, |
||||
|
showConfirmButton: false, |
||||
|
title: $t('AbpIdentity.ManageClaim'), |
||||
|
}); |
||||
|
const gridOptions: VxeGridProps<IdentityUserClaimDto> = { |
||||
|
columns: [ |
||||
|
{ |
||||
|
field: 'claimType', |
||||
|
minWidth: 120, |
||||
|
title: $t('AbpIdentity.DisplayName:ClaimType'), |
||||
|
}, |
||||
|
{ |
||||
|
field: 'claimValue', |
||||
|
title: $t('AbpIdentity.DisplayName:ClaimValue'), |
||||
|
width: 'auto', |
||||
|
}, |
||||
|
{ |
||||
|
field: 'action', |
||||
|
fixed: 'right', |
||||
|
slots: { default: 'action' }, |
||||
|
title: $t('AbpUi.Actions'), |
||||
|
width: 180, |
||||
|
}, |
||||
|
], |
||||
|
exportConfig: {}, |
||||
|
keepSource: true, |
||||
|
pagerConfig: { |
||||
|
enabled: false, |
||||
|
}, |
||||
|
proxyConfig: { |
||||
|
ajax: { |
||||
|
query: async () => { |
||||
|
const { id } = modalApi.getData<IdentityUserDto>(); |
||||
|
return await getClaimsApi(id); |
||||
|
}, |
||||
|
}, |
||||
|
response: { |
||||
|
total: 'totalCount', |
||||
|
list: 'items', |
||||
|
}, |
||||
|
}, |
||||
|
toolbarConfig: { |
||||
|
custom: true, |
||||
|
export: true, |
||||
|
// import: true, |
||||
|
refresh: true, |
||||
|
zoom: true, |
||||
|
}, |
||||
|
}; |
||||
|
const [Grid, { query }] = useVbenVxeGrid({ |
||||
|
gridOptions, |
||||
|
}); |
||||
|
|
||||
|
const [UserClaimEditModal, editModalApi] = useVbenModal({ |
||||
|
connectedComponent: ClaimEditModal, |
||||
|
}); |
||||
|
function onCreate() { |
||||
|
const { id } = modalApi.getData<IdentityUserDto>(); |
||||
|
editModalApi.setData({ |
||||
|
userId: id, |
||||
|
}); |
||||
|
editModalApi.open(); |
||||
|
} |
||||
|
|
||||
|
async function onDelete(row: IdentityUserClaimDto) { |
||||
|
const { id } = modalApi.getData<IdentityUserDto>(); |
||||
|
await deleteClaimApi(id, { |
||||
|
claimType: row.claimType, |
||||
|
claimValue: row.claimValue, |
||||
|
}).then(() => query()); |
||||
|
} |
||||
|
|
||||
|
function onUpdate(row: IdentityUserClaimDto) { |
||||
|
const { id } = modalApi.getData<IdentityUserDto>(); |
||||
|
editModalApi.setData({ |
||||
|
userId: id, |
||||
|
...row, |
||||
|
}); |
||||
|
editModalApi.open(); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<Modal> |
||||
|
<Grid> |
||||
|
<template #toolbar-tools> |
||||
|
<Button |
||||
|
type="primary" |
||||
|
v-access:code="[IdentityUserPermissions.ManageClaims]" |
||||
|
@click="onCreate" |
||||
|
> |
||||
|
{{ $t('AbpIdentity.AddClaim') }} |
||||
|
</Button> |
||||
|
</template> |
||||
|
<template #action="{ row }"> |
||||
|
<div class="flex flex-row"> |
||||
|
<div class="basis-1/2"> |
||||
|
<Button |
||||
|
:icon="h(EditOutlined)" |
||||
|
block |
||||
|
type="link" |
||||
|
v-access:code="[IdentityUserPermissions.ManageClaims]" |
||||
|
@click="onUpdate(row)" |
||||
|
> |
||||
|
{{ $t('AbpUi.Edit') }} |
||||
|
</Button> |
||||
|
</div> |
||||
|
<div class="basis-1/2"> |
||||
|
<Popconfirm |
||||
|
:title="$t('AbpIdentity.WillDeleteClaim', [row.claimType])" |
||||
|
@confirm="onDelete(row)" |
||||
|
> |
||||
|
<Button |
||||
|
:icon="h(DeleteOutlined)" |
||||
|
block |
||||
|
danger |
||||
|
type="link" |
||||
|
v-access:code="[IdentityUserPermissions.Delete]" |
||||
|
> |
||||
|
{{ $t('AbpUi.Delete') }} |
||||
|
</Button> |
||||
|
</Popconfirm> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
</Grid> |
||||
|
<UserClaimEditModal @change="() => query()" /> |
||||
|
</Modal> |
||||
|
</template> |
||||
|
|
||||
|
<style scoped></style> |
||||
Loading…
Reference in new issue