筛选
This commit is contained in:
parent
6493edce01
commit
b2eb6ee28e
@ -104,8 +104,12 @@ export async function changeName(name: string, token: string) {
|
|||||||
return await apiGet<unknown>(r)
|
return await apiGet<unknown>(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function ListUser(page: number, token: string) {
|
export async function ListUser(page: number, token: string, email: string, name: string) {
|
||||||
const r = await fetch(import.meta.env.VITE_APIADDR + "/api/v1/admin/users?page=" + String(page), {
|
const u = new URL(import.meta.env.VITE_APIADDR + "/api/v1/admin/users")
|
||||||
|
u.searchParams.set("page", String(page))
|
||||||
|
u.searchParams.set("email", email)
|
||||||
|
u.searchParams.set("name", name)
|
||||||
|
const r = await fetch(u.toString(), {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": "Bearer " + token
|
"Authorization": "Bearer " + token
|
||||||
|
@ -6,7 +6,7 @@ import TableHead from '@mui/material/TableHead';
|
|||||||
import TableRow from '@mui/material/TableRow';
|
import TableRow from '@mui/material/TableRow';
|
||||||
import Paper from '@mui/material/Paper';
|
import Paper from '@mui/material/Paper';
|
||||||
import useTitle from '@/hooks/useTitle';
|
import useTitle from '@/hooks/useTitle';
|
||||||
import { useRequest } from 'ahooks';
|
import { useMemoizedFn, useRequest } from 'ahooks';
|
||||||
import { ListUser } from '@/apis/apis';
|
import { ListUser } from '@/apis/apis';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
@ -15,28 +15,56 @@ import TablePagination from '@mui/material/TablePagination';
|
|||||||
import Alert from '@mui/material/Alert';
|
import Alert from '@mui/material/Alert';
|
||||||
import Snackbar from '@mui/material/Snackbar';
|
import Snackbar from '@mui/material/Snackbar';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
|
import TextField from '@mui/material/TextField';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Chip from '@mui/material/Chip';
|
||||||
|
import Dialog from '@mui/material/Dialog';
|
||||||
|
import DialogTitle from '@mui/material/DialogTitle';
|
||||||
|
import DialogContent from '@mui/material/DialogContent';
|
||||||
|
import DialogActions from '@mui/material/DialogActions';
|
||||||
|
import { UserInfo } from '@/apis/model';
|
||||||
|
import { produce } from 'immer'
|
||||||
|
|
||||||
export default function UserAdmin() {
|
export default function UserAdmin() {
|
||||||
useTitle("用户管理")
|
useTitle("用户管理")
|
||||||
const [page, setPage] = useState(1)
|
const [page, setPage] = useState(1)
|
||||||
const nowtoken = useAtomValue(token)
|
const nowtoken = useAtomValue(token)
|
||||||
const [err, setErr] = useState("")
|
const [err, setErr] = useState("")
|
||||||
|
const [email, setEmail] = useState("")
|
||||||
|
const [name, setName] = useState("")
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [row, setRow] = useState<UserInfo | null>(null)
|
||||||
|
|
||||||
|
|
||||||
|
const handleOpen = (row: UserInfo) => {
|
||||||
|
setRow(row)
|
||||||
|
setOpen(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const uq = new URLSearchParams("/api/v1/admin/users")
|
||||||
|
uq.set("page", String(page))
|
||||||
|
uq.set("email", email)
|
||||||
|
uq.set("name", name)
|
||||||
|
|
||||||
const { data, run } = useRequest(ListUser, {
|
const { data, run } = useRequest(ListUser, {
|
||||||
cacheKey: "/api/v1/admin/users?page=" + String(page),
|
cacheKey: uq.toString(),
|
||||||
|
debounceWait: 300,
|
||||||
onError: e => {
|
onError: e => {
|
||||||
setErr(String(e))
|
setErr(String(e))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
run(page, nowtoken)
|
run(page, nowtoken, email, name)
|
||||||
}, [page, nowtoken, run])
|
}, [page, nowtoken, run, email, name])
|
||||||
|
|
||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
<Paper>
|
<Paper>
|
||||||
|
<Box sx={{ p: "1em", display: "flex", gap: "1em", alignItems: "flex-end" }}>
|
||||||
|
<Chip label="前缀筛选" />
|
||||||
|
<TextField onChange={v => setEmail(v.target.value)} label="邮箱" variant="standard" />
|
||||||
|
<TextField onChange={v => setName(v.target.value)} label="用户名" variant="standard" />
|
||||||
|
</Box>
|
||||||
<TableContainer >
|
<TableContainer >
|
||||||
<Table>
|
<Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
@ -55,7 +83,7 @@ export default function UserAdmin() {
|
|||||||
<TableCell>{row.name}</TableCell>
|
<TableCell>{row.name}</TableCell>
|
||||||
<TableCell>{row.reg_ip}</TableCell>
|
<TableCell>{row.reg_ip}</TableCell>
|
||||||
<TableCell>{row.uuid}</TableCell>
|
<TableCell>{row.uuid}</TableCell>
|
||||||
<TableCell><Button>编辑</Button></TableCell>
|
<TableCell><Button onClick={() => handleOpen(row)}>编辑</Button></TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
@ -74,5 +102,49 @@ export default function UserAdmin() {
|
|||||||
<Alert onClose={() => setErr("")} severity="error">{err}</Alert>
|
<Alert onClose={() => setErr("")} severity="error">{err}</Alert>
|
||||||
</Snackbar>
|
</Snackbar>
|
||||||
|
|
||||||
|
<MyDialog open={open} setOpen={setOpen} row={row} />
|
||||||
</>);
|
</>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MyDialogProp {
|
||||||
|
open: boolean
|
||||||
|
setOpen: (b: boolean) => void
|
||||||
|
row: UserInfo | null
|
||||||
|
}
|
||||||
|
|
||||||
|
function MyDialog({ open, row, setOpen }: MyDialogProp) {
|
||||||
|
const handleClose = useMemoizedFn(() => {
|
||||||
|
setOpen(false)
|
||||||
|
})
|
||||||
|
const [nrow, setNrow] = useState(row)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setNrow(row)
|
||||||
|
}, [row])
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open}>
|
||||||
|
<DialogTitle>修改用户信息</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<TextField
|
||||||
|
margin="dense"
|
||||||
|
label="邮箱"
|
||||||
|
type="email"
|
||||||
|
fullWidth
|
||||||
|
variant="standard"
|
||||||
|
value={nrow?.email}
|
||||||
|
onChange={e => setNrow(produce(v => {
|
||||||
|
if (!v) return
|
||||||
|
v.email = e.target.value
|
||||||
|
return
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleClose}>取消</Button>
|
||||||
|
<Button onClick={handleClose}>确认</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
@ -70,8 +70,10 @@ func (h *Handel) ListUser() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
pagei = p
|
pagei = p
|
||||||
}
|
}
|
||||||
|
email := r.FormValue("email")
|
||||||
|
name := r.FormValue("name")
|
||||||
|
|
||||||
ul, uc, err := h.webService.ListUser(ctx, pagei)
|
ul, uc, err := h.webService.ListUser(ctx, pagei, email, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
||||||
return
|
return
|
||||||
|
@ -5,7 +5,9 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/xmdhs/authlib-skin/db/ent/predicate"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/user"
|
"github.com/xmdhs/authlib-skin/db/ent/user"
|
||||||
|
"github.com/xmdhs/authlib-skin/db/ent/userprofile"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
||||||
@ -32,8 +34,17 @@ func (w *WebService) IsAdmin(ctx context.Context, t *model.TokenClaims) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) ListUser(ctx context.Context, page int) ([]model.UserList, int, error) {
|
func (w *WebService) ListUser(ctx context.Context, page int, email, name string) ([]model.UserList, int, error) {
|
||||||
u, err := w.client.User.Query().WithProfile().Limit(20).Offset((page - 1) * 20).All(ctx)
|
whereL := []predicate.User{}
|
||||||
|
if email != "" {
|
||||||
|
whereL = append(whereL, user.EmailHasPrefix(email))
|
||||||
|
}
|
||||||
|
if name != "" {
|
||||||
|
whereL = append(whereL, user.HasProfileWith(userprofile.NameHasPrefix(name)))
|
||||||
|
}
|
||||||
|
u, err := w.client.User.Query().WithProfile().
|
||||||
|
Where(user.And(whereL...)).
|
||||||
|
Limit(20).Offset((page - 1) * 20).All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, fmt.Errorf("ListUser: %w", err)
|
return nil, 0, fmt.Errorf("ListUser: %w", err)
|
||||||
}
|
}
|
||||||
@ -55,7 +66,7 @@ func (w *WebService) ListUser(ctx context.Context, page int) ([]model.UserList,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
uc, err := w.client.User.Query().Count(ctx)
|
uc, err := w.client.User.Query().Where(user.And(whereL...)).Count(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, fmt.Errorf("ListUser: %w", err)
|
return nil, 0, fmt.Errorf("ListUser: %w", err)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user