Skip to content

Commit

Permalink
feat: user search
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Jul 20, 2022
1 parent 82c6db1 commit b5c8b6a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
17 changes: 17 additions & 0 deletions GZCTF/ClientApp/src/Api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,23 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
options?: MutatorOptions
) => mutate<UserInfoModel[]>([`/api/admin/users`, query], data, options),

/**
* @description 使用此接口搜索用户,需要Admin权限
*
* @tags Admin
* @name AdminSearchUsers
* @summary 搜索用户
* @request POST:/api/admin/users/search
*/
adminSearchUsers: (query?: { hint?: string }, params: RequestParams = {}) =>
this.request<UserInfoModel[], RequestResponse>({
path: `/api/admin/users/search`,
method: 'POST',
query: query,
format: 'json',
...params,
}),

/**
* @description 使用此接口获取全部队伍,需要Admin权限
*
Expand Down
40 changes: 31 additions & 9 deletions GZCTF/ClientApp/src/components/admin/UserManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@ import {
Badge,
Avatar,
Paper,
NumberInput,
useMantineTheme,
TextInput,
} from '@mantine/core'
import { useModals } from '@mantine/modals'
import { showNotification } from '@mantine/notifications'
import {
mdiArrowLeftBold,
mdiArrowRightBold,
mdiCheck,
mdiMagnify,
mdiClose,
mdiDeleteOutline,
mdiFileEditOutline,
} from '@mdi/js'
import Icon from '@mdi/react'
import api, { Role, UserInfoModel } from '../../Api'
import UserEditModal from './edit/UserEditModal'
import { useInputState } from '@mantine/hooks'

const ITEM_COUNT_PER_PAGE = 30

Expand All @@ -39,6 +41,8 @@ const UserManager: FC = () => {
const [isEditModalOpen, setIsEditModalOpen] = useState(false)
const [activeUser, setActiveUser] = useState<UserInfoModel>({})
const [users, setUsers] = useState<UserInfoModel[]>([])
const [hint, setHint] = useInputState('');
const [searching, setSearching] = useState(false)

const theme = useMantineTheme()
const { data: currentUser } = api.account.useAccountProfile({
Expand All @@ -58,6 +62,24 @@ const UserManager: FC = () => {
})
}, [page])

const onSearch = () => {
setSearching(true)
api.admin.adminSearchUsers({
hint
}).then((res) => {
setUsers(res.data)
}).catch((err) => {
showNotification({
color: 'red',
title: '遇到了问题',
message: `${err.error.title}`,
icon: <Icon path={mdiClose} size={1} />,
})
}).finally(() => {
setSearching(false)
})
}

const modals = useModals()

const onConfirmDelete = (user: UserInfoModel) => {
Expand Down Expand Up @@ -110,9 +132,14 @@ const UserManager: FC = () => {
<Paper shadow="md" p="md">
<Stack>
<Group position="apart">
<Badge size="xl" radius="sm" variant="outline">
{page}
</Badge>
<TextInput
icon={<Icon path={mdiMagnify} size={1} />}
style={{ width: '30%' }}
placeholder="搜索用户名/邮箱/学号/姓名"
value={hint}
onChange={setHint}
onKeyDown={(e) => {!searching && e.key === 'Enter' && onSearch()}}
/>
<Group position="right">
<ActionIcon
size="lg"
Expand Down Expand Up @@ -216,11 +243,6 @@ const UserManager: FC = () => {
a.id! < b.id! ? -1 : 1
)
)
console.log(
[user, ...(users?.filter((n) => n.id !== user.id) ?? [])].sort((a, b) =>
a.id! < b.id! ? -1 : 1
)
)
}}
/>
</Stack>
Expand Down
24 changes: 24 additions & 0 deletions GZCTF/Controllers/AdminController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,30 @@ from user in userManager.Users.OrderBy(e => e.Id).Skip(skip).Take(count)
select UserInfoModel.FromUserInfo(user)
).ToArrayAsync(token));

/// <summary>
/// 搜索用户
/// </summary>
/// <remarks>
/// 使用此接口搜索用户,需要Admin权限
/// </remarks>
/// <response code="200">用户列表</response>
/// <response code="401">未授权用户</response>
/// <response code="403">禁止访问</response>
[HttpPost("Users/Search")]
[ProducesResponseType(typeof(UserInfoModel[]), StatusCodes.Status200OK)]
public async Task<IActionResult> SearchUsers([FromQuery] string hint, CancellationToken token = default)
=> Ok(await (
from user in userManager.Users
.Where(item =>
EF.Functions.Like(item.UserName, $"%{hint}%") ||
EF.Functions.Like(item.StdNumber, $"%{hint}%") ||
EF.Functions.Like(item.Email, $"%{hint}%") ||
EF.Functions.Like(item.RealName, $"%{hint}%")
)
.Take(20)
select UserInfoModel.FromUserInfo(user)
).ToArrayAsync(token));

/// <summary>
/// 获取全部队伍信息
/// </summary>
Expand Down

0 comments on commit b5c8b6a

Please sign in to comment.