Spaces:
Runtime error
Runtime error
<script lang="ts" setup> | |
import { h, onMounted, reactive, ref } from 'vue' | |
import { NButton, NDataTable, NModal, NSelect, NTag, useDialog, useMessage } from 'naive-ui' | |
import { Status, UserInfo, UserRole, userRoleOptions } from './model' | |
import { fetchGetUsers, fetchUpdateUserRole, fetchUpdateUserStatus } from '@/api' | |
import { t } from '@/locales' | |
const ms = useMessage() | |
const dialog = useDialog() | |
const loading = ref(false) | |
const show = ref(false) | |
const handleSaving = ref(false) | |
const userRef = ref(new UserInfo([UserRole.User])) | |
const users = ref([]) | |
const columns = [ | |
{ | |
title: 'Email', | |
key: 'email', | |
resizable: true, | |
width: 200, | |
minWidth: 100, | |
maxWidth: 200, | |
}, | |
{ | |
title: 'Register Time', | |
key: 'createTime', | |
width: 220, | |
}, | |
{ | |
title: 'Verify Time', | |
key: 'verifyTime', | |
width: 220, | |
}, | |
{ | |
title: 'Roles', | |
key: 'status', | |
width: 200, | |
render(row: any) { | |
const roles = row.roles.map((role: UserRole) => { | |
return h( | |
NTag, | |
{ | |
style: { | |
marginRight: '6px', | |
}, | |
type: 'info', | |
bordered: false, | |
}, | |
{ | |
default: () => UserRole[role], | |
}, | |
) | |
}) | |
return roles | |
}, | |
}, | |
{ | |
title: 'Status', | |
key: 'status', | |
width: 200, | |
render(row: any) { | |
return Status[row.status] | |
}, | |
}, | |
{ | |
title: 'Action', | |
key: '_id', | |
width: 220, | |
render(row: any) { | |
const actions: any[] = [] | |
actions.push(h( | |
NButton, | |
{ | |
size: 'small', | |
type: 'error', | |
style: { | |
marginRight: '6px', | |
}, | |
onClick: () => handleUpdateUserStatus(row._id, Status.Deleted), | |
}, | |
{ default: () => t('chat.deleteUser') }, | |
)) | |
if (row.status === Status.Normal) { | |
actions.push(h( | |
NButton, | |
{ | |
size: 'small', | |
type: 'primary', | |
style: { | |
marginRight: '6px', | |
}, | |
onClick: () => handleEditUser(row), | |
}, | |
{ default: () => t('chat.setUserRole') }, | |
)) | |
} | |
if (row.status === Status.PreVerify || row.status === Status.AdminVerify) { | |
actions.push(h( | |
NButton, | |
{ | |
size: 'small', | |
type: 'info', | |
onClick: () => handleUpdateUserStatus(row._id, Status.Normal), | |
}, | |
{ default: () => t('chat.verifiedUser') }, | |
)) | |
} | |
return actions | |
}, | |
}, | |
] | |
const pagination = reactive ({ | |
page: 1, | |
pageSize: 25, | |
pageCount: 1, | |
itemCount: 1, | |
prefix({ itemCount }: { itemCount: number | undefined }) { | |
return `Total is ${itemCount}.` | |
}, | |
showSizePicker: true, | |
pageSizes: [25, 50, 100], | |
onChange: (page: number) => { | |
pagination.page = page | |
handleGetUsers(pagination.page) | |
}, | |
onUpdatePageSize: (pageSize: number) => { | |
pagination.pageSize = pageSize | |
pagination.page = 1 | |
handleGetUsers(pagination.page) | |
}, | |
}) | |
async function handleGetUsers(page: number) { | |
if (loading.value) | |
return | |
users.value.length = 0 | |
loading.value = true | |
const size = pagination.pageSize | |
const data = (await fetchGetUsers(page, size)).data | |
data.users.forEach((user: never) => { | |
users.value.push(user) | |
}) | |
pagination.page = page | |
pagination.pageCount = data.total / size + (data.total % size === 0 ? 0 : 1) | |
pagination.itemCount = data.total | |
loading.value = false | |
} | |
async function handleUpdateUserStatus(userId: string, status: Status) { | |
if (status === Status.Deleted) { | |
dialog.warning({ | |
title: t('chat.deleteUser'), | |
content: t('chat.deleteUserConfirm'), | |
positiveText: t('common.yes'), | |
negativeText: t('common.no'), | |
onPositiveClick: async () => { | |
await fetchUpdateUserStatus(userId, status) | |
ms.info('OK') | |
await handleGetUsers(pagination.page) | |
}, | |
}) | |
} | |
else { | |
await fetchUpdateUserStatus(userId, status) | |
ms.info('OK') | |
await handleGetUsers(pagination.page) | |
} | |
} | |
function handleEditUser(user: UserInfo) { | |
userRef.value = user | |
show.value = true | |
} | |
async function handleUpdateUserRoles() { | |
if (!userRef.value._id) { | |
ms.error('User Error') | |
return | |
} | |
handleSaving.value = true | |
try { | |
await fetchUpdateUserRole(userRef.value._id, userRef.value.roles) | |
await handleGetUsers(pagination.page) | |
show.value = false | |
} | |
catch (error: any) { | |
ms.error(error.message) | |
} | |
handleSaving.value = false | |
} | |
onMounted(async () => { | |
await handleGetUsers(pagination.page) | |
}) | |
</script> | |
<template> | |
<div class="p-4 space-y-5 min-h-[200px]"> | |
<div class="space-y-6"> | |
<NDataTable | |
ref="table" | |
remote | |
:loading="loading" | |
:row-key="(rowData) => rowData._id" | |
:columns="columns" | |
:data="users" | |
:pagination="pagination" | |
:max-height="444" | |
striped | |
:scroll-x="1260" | |
@update:page="handleGetUsers" | |
/> | |
</div> | |
</div> | |
<NModal v-model:show="show" :auto-focus="false" preset="card" style="width:50%;"> | |
<div class="p-4 space-y-5 min-h-[200px]"> | |
<div class="space-y-6"> | |
<div class="flex items-center space-x-4"> | |
<span class="flex-shrink-0 w-[100px]">{{ $t('setting.userRoles') }}</span> | |
<div class="flex-1"> | |
<NSelect | |
style="width: 100%" | |
multiple | |
:value="userRef.roles" | |
:options="userRoleOptions" | |
@update-value="value => userRef.roles = value" | |
/> | |
</div> | |
</div> | |
<div class="flex items-center space-x-4"> | |
<span class="flex-shrink-0 w-[100px]" /> | |
<NButton type="primary" :loading="handleSaving" @click="handleUpdateUserRoles()"> | |
{{ $t('common.save') }} | |
</NButton> | |
</div> | |
</div> | |
</div> | |
</NModal> | |
</template> | |