用户管理
This commit is contained in:
parent
4cf7c8aca0
commit
63808f0a14
@ -51,8 +51,9 @@ export interface ApiConfig {
|
|||||||
|
|
||||||
export interface UserInfo {
|
export interface UserInfo {
|
||||||
uid: number
|
uid: number
|
||||||
uuid: number
|
uuid: string
|
||||||
is_admin: boolean
|
is_admin: boolean
|
||||||
|
is_disable: boolean
|
||||||
email: string
|
email: string
|
||||||
reg_ip: string
|
reg_ip: string
|
||||||
name: string
|
name: string
|
||||||
@ -63,4 +64,6 @@ export interface EditUser {
|
|||||||
name: string
|
name: string
|
||||||
password: string
|
password: string
|
||||||
is_admin: boolean
|
is_admin: boolean
|
||||||
|
is_disable: boolean
|
||||||
|
del_textures: boolean
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ export default function Loading() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Backdrop
|
<Backdrop
|
||||||
sx={{ color: '#fff', zIndex: (theme) => theme.zIndex.drawer + 1 }}
|
sx={{ color: '#fff', zIndex: (theme) => theme.zIndex.modal + 1 }}
|
||||||
open={true}
|
open={true}
|
||||||
>
|
>
|
||||||
<CircularProgress color="inherit" />
|
<CircularProgress color="inherit" />
|
||||||
|
89
frontend/src/components/SkinViewUUID.tsx
Normal file
89
frontend/src/components/SkinViewUUID.tsx
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import { yggProfile } from "@/apis/apis";
|
||||||
|
import { decodeSkin } from "@/utils/skin";
|
||||||
|
import Skeleton from "@mui/material/Skeleton";
|
||||||
|
import { useHover, useMemoizedFn, useRequest, useUnmount } from "ahooks";
|
||||||
|
import { memo, useEffect, useRef, useState } from "react";
|
||||||
|
import ReactSkinview3d, { ReactSkinview3dOptions } from "@/components/Skinview3d";
|
||||||
|
import { SkinViewer, WalkingAnimation } from "skinview3d";
|
||||||
|
import Box from "@mui/material/Box";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
|
||||||
|
interface prop {
|
||||||
|
uuid: string
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const SkinViewUUID = memo(function SkinViewUUID({ uuid, width, height }: prop) {
|
||||||
|
const [textures, setTextures] = useState({ skin: "", cape: "", model: "default" })
|
||||||
|
const [err, setErr] = useState("")
|
||||||
|
|
||||||
|
const SkinInfo = useRequest(() => yggProfile(uuid), {
|
||||||
|
cacheKey: "/api/yggdrasil/sessionserver/session/minecraft/profile/" + uuid,
|
||||||
|
onError: e => {
|
||||||
|
console.warn(e)
|
||||||
|
setErr(String(e))
|
||||||
|
},
|
||||||
|
refreshDeps: [uuid],
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!SkinInfo.data) return
|
||||||
|
const [skin, cape, model] = decodeSkin(SkinInfo.data)
|
||||||
|
setTextures({ cape: cape, skin: skin, model: model })
|
||||||
|
}, [SkinInfo.data])
|
||||||
|
|
||||||
|
if (err != "") {
|
||||||
|
return <Typography color={"error"}>{err}</Typography>
|
||||||
|
}
|
||||||
|
return (<>
|
||||||
|
{
|
||||||
|
(SkinInfo.loading && !SkinInfo.data) ? <Skeleton variant="rectangular" width={width} height={height} />
|
||||||
|
: (textures.skin != "" || textures.cape != "") ? (
|
||||||
|
<MySkin
|
||||||
|
skinUrl={textures.skin}
|
||||||
|
capeUrl={textures.cape}
|
||||||
|
height={width}
|
||||||
|
width={height}
|
||||||
|
options={{ model: textures.model as "default" | "slim" }}
|
||||||
|
/>) : <Box sx={{ minHeight: height + "px" }}>
|
||||||
|
<Typography>还没有设置皮肤</Typography>
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
</>)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const MySkin = function MySkin(p: ReactSkinview3dOptions) {
|
||||||
|
const refSkinview3d = useRef(null);
|
||||||
|
const skinisHovering = useHover(refSkinview3d);
|
||||||
|
const skinview3dView = useRef<SkinViewer | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (skinview3dView.current) {
|
||||||
|
skinview3dView.current.autoRotate = !skinisHovering
|
||||||
|
}
|
||||||
|
if (skinview3dView.current?.animation) {
|
||||||
|
skinview3dView.current.animation.paused = skinisHovering
|
||||||
|
}
|
||||||
|
}, [skinisHovering])
|
||||||
|
|
||||||
|
useUnmount(() => {
|
||||||
|
skinview3dView.current?.dispose()
|
||||||
|
})
|
||||||
|
|
||||||
|
const handelOnReady = useMemoizedFn(v => {
|
||||||
|
v.viewer.animation = new WalkingAnimation()
|
||||||
|
v.viewer.autoRotate = true
|
||||||
|
skinview3dView.current = v.viewer
|
||||||
|
})
|
||||||
|
|
||||||
|
return <div ref={refSkinview3d}>
|
||||||
|
<ReactSkinview3d
|
||||||
|
{...p}
|
||||||
|
onReady={handelOnReady}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SkinViewUUID
|
@ -34,7 +34,7 @@ import PersonIcon from '@mui/icons-material/Person';
|
|||||||
import SecurityIcon from '@mui/icons-material/Security';
|
import SecurityIcon from '@mui/icons-material/Security';
|
||||||
import SettingsIcon from '@mui/icons-material/Settings';
|
import SettingsIcon from '@mui/icons-material/Settings';
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import GroupIcon from '@mui/icons-material/Group';
|
||||||
|
|
||||||
const drawerWidth = 240;
|
const drawerWidth = 240;
|
||||||
const DrawerOpen = atom(false)
|
const DrawerOpen = atom(false)
|
||||||
@ -242,8 +242,9 @@ const MyDrawer = function MyDrawer() {
|
|||||||
|
|
||||||
const adminDrawerList = React.useMemo(() => [
|
const adminDrawerList = React.useMemo(() => [
|
||||||
{
|
{
|
||||||
icon: <PersonIcon />,
|
icon: <GroupIcon />,
|
||||||
title: 'test'
|
title: '用户管理',
|
||||||
|
link: '/admin/user'
|
||||||
}
|
}
|
||||||
] as ListItem[], [])
|
] as ListItem[], [])
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ 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 { useRequest } from 'ahooks';
|
||||||
import { ListUser } from '@/apis/apis';
|
import { ListUser, editUser } from '@/apis/apis';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
import { token } from '@/store/store';
|
import { token } from '@/store/store';
|
||||||
@ -22,8 +22,13 @@ import Dialog from '@mui/material/Dialog';
|
|||||||
import DialogTitle from '@mui/material/DialogTitle';
|
import DialogTitle from '@mui/material/DialogTitle';
|
||||||
import DialogContent from '@mui/material/DialogContent';
|
import DialogContent from '@mui/material/DialogContent';
|
||||||
import DialogActions from '@mui/material/DialogActions';
|
import DialogActions from '@mui/material/DialogActions';
|
||||||
import { UserInfo } from '@/apis/model';
|
import { EditUser, UserInfo } from '@/apis/model';
|
||||||
import { produce } from 'immer'
|
import { produce } from 'immer'
|
||||||
|
import Checkbox from '@mui/material/Checkbox';
|
||||||
|
import FormGroup from '@mui/material/FormGroup';
|
||||||
|
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||||
|
import SkinViewUUID from '@/components/SkinViewUUID';
|
||||||
|
import Loading from '@/components/Loading';
|
||||||
|
|
||||||
export default function UserAdmin() {
|
export default function UserAdmin() {
|
||||||
useTitle("用户管理")
|
useTitle("用户管理")
|
||||||
@ -102,7 +107,7 @@ 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} />
|
<MyDialog open={open} setOpen={setOpen} row={row} onUpdate={() => run(page, nowtoken, email, name)} />
|
||||||
</>);
|
</>);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,45 +115,109 @@ interface MyDialogProp {
|
|||||||
open: boolean
|
open: boolean
|
||||||
setOpen: (b: boolean) => void
|
setOpen: (b: boolean) => void
|
||||||
row: UserInfo | null
|
row: UserInfo | null
|
||||||
|
onUpdate: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
function MyDialog({ open, row, setOpen }: MyDialogProp) {
|
function MyDialog({ open, row, setOpen, onUpdate }: MyDialogProp) {
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
}
|
}
|
||||||
const [nrow, setNrow] = useState(row)
|
const [erow, setErow] = useState<EditUser>({
|
||||||
|
email: "",
|
||||||
|
name: "",
|
||||||
|
password: "",
|
||||||
|
is_admin: false,
|
||||||
|
is_disable: false,
|
||||||
|
del_textures: false,
|
||||||
|
})
|
||||||
|
const [load, setLoad] = useState(false)
|
||||||
|
const nowToken = useAtomValue(token)
|
||||||
|
const [err, setErr] = useState("")
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setNrow(row)
|
setErow({
|
||||||
|
email: row?.email ?? "",
|
||||||
|
name: row?.name ?? "",
|
||||||
|
password: "",
|
||||||
|
is_admin: row?.is_admin ?? false,
|
||||||
|
is_disable: row?.is_disable ?? false,
|
||||||
|
del_textures: false,
|
||||||
|
})
|
||||||
}, [row])
|
}, [row])
|
||||||
|
|
||||||
const handleOpen = () => {
|
const handleOpen = () => {
|
||||||
|
if (load) return
|
||||||
|
setLoad(true)
|
||||||
|
editUser(erow, nowToken, String(row?.uid)).then(() => [setOpen(false), onUpdate()]).finally(() => setLoad(false)).
|
||||||
|
catch(e => setErr(String(e)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (<>
|
||||||
<Dialog open={open}>
|
<Dialog open={open}>
|
||||||
<DialogTitle>修改用户信息</DialogTitle>
|
<DialogTitle>修改用户信息</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent sx={{
|
||||||
|
display: "grid", gap: '1em', gridTemplateColumns: {
|
||||||
|
md: "auto 175px",
|
||||||
|
xs: "1fr"
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<Box sx={{ display: "flex", flexDirection: 'column', gap: '0.5em' }}>
|
||||||
<TextField
|
<TextField
|
||||||
margin="dense"
|
margin="dense"
|
||||||
label="邮箱"
|
label="邮箱"
|
||||||
type="email"
|
type="email"
|
||||||
fullWidth
|
|
||||||
variant="standard"
|
variant="standard"
|
||||||
value={nrow?.email}
|
value={erow?.email}
|
||||||
onChange={e => setNrow(produce(v => {
|
onChange={e => setErow(produce(v => {
|
||||||
if (!v) return
|
|
||||||
v.email = e.target.value
|
v.email = e.target.value
|
||||||
return
|
return
|
||||||
}))}
|
}))}
|
||||||
/>
|
/>
|
||||||
|
<TextField
|
||||||
|
margin="dense"
|
||||||
|
label="用户名"
|
||||||
|
type="text"
|
||||||
|
variant="standard"
|
||||||
|
value={erow?.name}
|
||||||
|
onChange={e => setErow(produce(v => {
|
||||||
|
v.name = e.target.value
|
||||||
|
return
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
margin="dense"
|
||||||
|
label="密码"
|
||||||
|
type="text"
|
||||||
|
variant="standard"
|
||||||
|
value={erow?.password}
|
||||||
|
onChange={e => setErow(produce(v => {
|
||||||
|
v.password = e.target.value
|
||||||
|
return
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
<FormGroup>
|
||||||
|
<FormControlLabel control={<Checkbox checked={erow?.is_admin} onChange={e => setErow(produce(v => {
|
||||||
|
v.is_admin = e.target.checked
|
||||||
|
}))} />} label="管理权限" />
|
||||||
|
<FormControlLabel control={<Checkbox checked={erow?.is_disable} onChange={e => setErow(produce(v => {
|
||||||
|
v.is_disable = e.target.checked
|
||||||
|
}))} />} label="禁用" />
|
||||||
|
<FormControlLabel control={<Checkbox checked={erow?.del_textures} onChange={e => setErow(produce(v => {
|
||||||
|
v.del_textures = e.target.checked
|
||||||
|
}))} />} label="清空材质" />
|
||||||
|
</FormGroup>
|
||||||
|
</Box>
|
||||||
|
<SkinViewUUID uuid={row?.uuid ?? ""} width={175} height={175} />
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={handleClose}>取消</Button>
|
<Button onClick={handleClose}>取消</Button>
|
||||||
<Button onClick={handleOpen}>确认</Button>
|
<Button onClick={handleOpen}>确认</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
{load && <Loading />}
|
||||||
|
<Snackbar anchorOrigin={{ vertical: 'top', horizontal: 'center' }} open={err != ""} >
|
||||||
|
<Alert onClose={() => setErr("")} severity="error">{err}</Alert>
|
||||||
|
</Snackbar>
|
||||||
|
</>)
|
||||||
}
|
}
|
@ -4,48 +4,20 @@ import CardContent from '@mui/material/CardContent';
|
|||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import CardHeader from '@mui/material/CardHeader';
|
import CardHeader from '@mui/material/CardHeader';
|
||||||
import { useHover, useMemoizedFn, useRequest, useUnmount } from 'ahooks';
|
import { user } from '@/store/store';
|
||||||
import { LayoutAlertErr, user } from '@/store/store';
|
import { useAtomValue } from 'jotai';
|
||||||
import { useAtomValue, useSetAtom } from 'jotai';
|
|
||||||
import { yggProfile } from '@/apis/apis';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
|
||||||
import { decodeSkin } from '@/utils/skin';
|
|
||||||
import ReactSkinview3d from '@/components/Skinview3d'
|
|
||||||
import type { ReactSkinview3dOptions } from '@/components/Skinview3d'
|
|
||||||
import { WalkingAnimation } from "skinview3d"
|
|
||||||
import type { SkinViewer } from "skinview3d"
|
|
||||||
import Skeleton from '@mui/material/Skeleton';
|
|
||||||
import useTitle from '@/hooks/useTitle';
|
import useTitle from '@/hooks/useTitle';
|
||||||
|
import SkinViewUUID from '@/components/SkinViewUUID';
|
||||||
|
|
||||||
const Profile = function Profile() {
|
const Profile = function Profile() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const setErr = useSetAtom(LayoutAlertErr)
|
|
||||||
const userinfo = useAtomValue(user)
|
const userinfo = useAtomValue(user)
|
||||||
|
|
||||||
const [textures, setTextures] = useState({ skin: "", cape: "", model: "default" })
|
|
||||||
useTitle("个人信息")
|
useTitle("个人信息")
|
||||||
|
|
||||||
|
|
||||||
const SkinInfo = useRequest(() => yggProfile(userinfo.uuid ?? ""), {
|
|
||||||
cacheKey: "/api/yggdrasil/sessionserver/session/minecraft/profile/" + userinfo?.uuid,
|
|
||||||
onError: e => {
|
|
||||||
console.warn(e)
|
|
||||||
setErr(String(e))
|
|
||||||
},
|
|
||||||
refreshDeps: [userinfo?.uuid],
|
|
||||||
})
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!SkinInfo.data) return
|
|
||||||
const [skin, cape, model] = decodeSkin(SkinInfo.data)
|
|
||||||
setTextures({ cape: cape, skin: skin, model: model })
|
|
||||||
}, [SkinInfo.data])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
@ -69,20 +41,7 @@ const Profile = function Profile() {
|
|||||||
<Card sx={{ gridArea: "b" }}>
|
<Card sx={{ gridArea: "b" }}>
|
||||||
<CardHeader title="皮肤" />
|
<CardHeader title="皮肤" />
|
||||||
<CardContent sx={{ display: "flex", justifyContent: 'center' }}>
|
<CardContent sx={{ display: "flex", justifyContent: 'center' }}>
|
||||||
{
|
<SkinViewUUID uuid={userinfo?.uuid ?? ""} width={250} height={250} />
|
||||||
(SkinInfo.loading && !SkinInfo.data) ? <Skeleton variant="rectangular" width={250} height={250} />
|
|
||||||
: (textures.skin != "" || textures.cape != "") ? (
|
|
||||||
<MySkin
|
|
||||||
skinUrl={textures.skin}
|
|
||||||
capeUrl={textures.cape}
|
|
||||||
height="250"
|
|
||||||
width="250"
|
|
||||||
options={{ model: textures.model as "default" | "slim" }}
|
|
||||||
/>) : <Box sx={{ minHeight: "250px" }}>
|
|
||||||
<Typography>你还没有设置皮肤</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
}
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardActions>
|
<CardActions>
|
||||||
<Button onClick={() => navigate('/textures')} size="small">更改</Button>
|
<Button onClick={() => navigate('/textures')} size="small">更改</Button>
|
||||||
@ -101,39 +60,6 @@ const Profile = function Profile() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const MySkin = function MySkin(p: ReactSkinview3dOptions) {
|
|
||||||
const refSkinview3d = useRef(null);
|
|
||||||
const skinisHovering = useHover(refSkinview3d);
|
|
||||||
const skinview3dView = useRef<SkinViewer | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (skinview3dView.current) {
|
|
||||||
skinview3dView.current.autoRotate = !skinisHovering
|
|
||||||
}
|
|
||||||
if (skinview3dView.current?.animation) {
|
|
||||||
skinview3dView.current.animation.paused = skinisHovering
|
|
||||||
}
|
|
||||||
}, [skinisHovering])
|
|
||||||
|
|
||||||
useUnmount(() => {
|
|
||||||
skinview3dView.current?.dispose()
|
|
||||||
})
|
|
||||||
|
|
||||||
const handelOnReady = useMemoizedFn(v => {
|
|
||||||
v.viewer.animation = new WalkingAnimation()
|
|
||||||
v.viewer.autoRotate = true
|
|
||||||
skinview3dView.current = v.viewer
|
|
||||||
})
|
|
||||||
|
|
||||||
return <div ref={refSkinview3d}>
|
|
||||||
<ReactSkinview3d
|
|
||||||
{...p}
|
|
||||||
onReady={handelOnReady}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
function getYggRoot() {
|
function getYggRoot() {
|
||||||
const u = new URL((import.meta.env.VITE_APIADDR ?? location.origin) + "/api/yggdrasil")
|
const u = new URL((import.meta.env.VITE_APIADDR ?? location.origin) + "/api/yggdrasil")
|
||||||
return u.toString()
|
return u.toString()
|
||||||
|
@ -51,6 +51,7 @@ type UserList struct {
|
|||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
RegIp string `json:"reg_ip"`
|
RegIp string `json:"reg_ip"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
IsDisable bool `json:"is_disable"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChangeName struct {
|
type ChangeName struct {
|
||||||
|
@ -66,6 +66,7 @@ func (w *WebService) ListUser(ctx context.Context, page int, email, name string)
|
|||||||
Email: v.Email,
|
Email: v.Email,
|
||||||
RegIp: v.RegIP,
|
RegIp: v.RegIP,
|
||||||
Name: v.Edges.Profile.Name,
|
Name: v.Edges.Profile.Name,
|
||||||
|
IsDisable: utilsService.IsDisable(v.State),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ func (w *WebService) ListUser(ctx context.Context, page int, email, name string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) EditUser(ctx context.Context, u model.EditUser, uid int) error {
|
func (w *WebService) EditUser(ctx context.Context, u model.EditUser, uid int) error {
|
||||||
|
uuid := ""
|
||||||
err := utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
err := utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
||||||
up := tx.User.UpdateOneID(uid).SetEmail(u.Email)
|
up := tx.User.UpdateOneID(uid).SetEmail(u.Email)
|
||||||
if u.Password != "" {
|
if u.Password != "" {
|
||||||
@ -93,13 +95,14 @@ func (w *WebService) EditUser(ctx context.Context, u model.EditUser, uid int) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
if u.DelTextures {
|
if u.DelTextures {
|
||||||
up, err := tx.UserProfile.Query().Where(userprofile.ID(uid)).First(ctx)
|
userProfile, err := tx.UserProfile.Query().Where(userprofile.ID(uid)).First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
uuid = userProfile.UUID
|
||||||
tl := []string{"skin", "cape"}
|
tl := []string{"skin", "cape"}
|
||||||
for _, v := range tl {
|
for _, v := range tl {
|
||||||
err := utilsService.DelTexture(ctx, up.ID, v, w.client, w.config)
|
err := utilsService.DelTexture(ctx, userProfile.ID, v, w.client, w.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -122,9 +125,14 @@ func (w *WebService) EditUser(ctx context.Context, u model.EditUser, uid int) er
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("EditUser: %w", err)
|
return fmt.Errorf("EditUser: %w", err)
|
||||||
}
|
}
|
||||||
|
if uuid != "" {
|
||||||
|
err = w.cache.Del([]byte("Profile" + uuid))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("EditUser: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user