178 lines
3.9 KiB
Vue
178 lines
3.9 KiB
Vue
<script setup lang="ts">
|
|
import {useMainLayoutStore} from "~/strores/UseMainLayoutStore";
|
|
import {useToast} from "vue-toastification";
|
|
|
|
const toast = useToast()
|
|
const mainLayoutStore = useMainLayoutStore()
|
|
const userList = ref<UserListItem[]>([])
|
|
type UserListItem = {
|
|
"name": string,
|
|
"isOnline": boolean,
|
|
"lastLoginTime": string,
|
|
"address": string,
|
|
"port": string,
|
|
}
|
|
const GetServerUserList = () => {
|
|
$fetch('/Api/Server/GetServerUserList', {
|
|
method: 'GET',
|
|
params: {
|
|
ServerId: mainLayoutStore.SelectServer.id
|
|
},
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': "Bearer " + useCookie('token').value
|
|
},
|
|
baseURL: useRuntimeConfig().public.baseUrl
|
|
}).then(res => {
|
|
userList.value=res as UserListItem[];
|
|
}).catch(err => {
|
|
toast.error(err)
|
|
})
|
|
}
|
|
onMounted(() => {
|
|
GetServerUserList()
|
|
})
|
|
const refresh = () => {
|
|
userList.value=[]
|
|
GetServerUserList()
|
|
}
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<div class="user-list-layout">
|
|
<div class="user-list-header">
|
|
<Icon name="ArrowDownUp" :size="24" :stroke-width="1.5"></Icon>
|
|
<h3>用户列表</h3>
|
|
<Icon name="Repeat2" :size="24" :stroke-width="1.5" @click="refresh"/>
|
|
</div>
|
|
<div class="user-list-body">
|
|
<div class="user-list-item" @click="navigateTo(`/serverUser/all`)">
|
|
<div class="avatar">
|
|
<Avatar size="xlarge" shape="circle" class="avatar" label="全"/>
|
|
</div>
|
|
<div class="info">
|
|
<div class="top">
|
|
<h3>全部</h3>
|
|
</div>
|
|
<p>NULL</p>
|
|
</div>
|
|
</div>
|
|
<div :class="{'user-list-item':true,'user-list-item-active':$route.params.id===item.name}" v-for="item in userList" @click="navigateTo(`/serverUser/${item.name}`)">
|
|
<div class="avatar">
|
|
<Avatar size="xlarge" shape="circle" class="avatar" :label="item.name[0].toUpperCase()"/>
|
|
</div>
|
|
<div class="info">
|
|
<div class="top">
|
|
<h3>{{ item.name }}</h3>
|
|
<div class="tags">
|
|
<Tag v-if="item.isOnline">在线</Tag>
|
|
<Tag v-if="item.isOnline">{{item.port}}</Tag>
|
|
<Tag v-if="item.isOnline">{{item.address}}</Tag>
|
|
</div>
|
|
</div>
|
|
<p>{{item.lastLoginTime}}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
@import "base";
|
|
|
|
.user-list-layout {
|
|
background: $light-bg-color;
|
|
border-radius: $radius;
|
|
border: $border;
|
|
padding: $padding 0;
|
|
grid-row: 1/3;
|
|
*{
|
|
@include SC_Font;
|
|
}
|
|
.dark-mode &{
|
|
background: $dark-bg-color;
|
|
}
|
|
}
|
|
|
|
.user-list-header {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0 $padding;
|
|
justify-content: space-between;
|
|
h3{
|
|
color: $light-text-color;
|
|
}
|
|
svg {
|
|
color: rgba(51, 51, 51, 0.34);
|
|
stroke: rgba(51, 51, 51, 0.44);
|
|
cursor: pointer;
|
|
&:hover {
|
|
stroke: rgba(51, 51, 51, 0.64);
|
|
}
|
|
}
|
|
.dark-mode &{
|
|
h3{
|
|
color: $dark-text-color;
|
|
}
|
|
svg{
|
|
color: rgba(255, 255, 255, 0.34);
|
|
stroke: rgba(255, 255, 255, 0.44);
|
|
&:hover {
|
|
stroke: rgba(255, 255, 255, 0.64);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.user-list-body{
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: $gap;
|
|
padding: $padding*2 $padding;
|
|
}
|
|
.user-list-item{
|
|
display: flex;
|
|
align-items: center;
|
|
gap: $gap;
|
|
padding: 8px;
|
|
border-radius: $radius;
|
|
cursor: pointer;
|
|
h3,p{
|
|
color: $light-text-color;
|
|
}
|
|
.dark-mode &{
|
|
h3,p{
|
|
color: $dark-text-color;
|
|
}
|
|
}
|
|
&:hover{
|
|
background: rgba(51, 51, 51, 0.06);
|
|
}
|
|
.dark-mode &{
|
|
&:hover{
|
|
background: rgba(255, 255, 255, 0.06);
|
|
}
|
|
}
|
|
.info{
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex:1;
|
|
gap: $gap;
|
|
.top{
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
.tags{
|
|
display: flex;
|
|
gap: $gap;
|
|
}
|
|
}
|
|
}
|
|
.user-list-item-active{
|
|
background: rgba(51, 51, 51, 0.2);
|
|
|
|
.dark-mode &{
|
|
background: rgba(255, 255, 255, 0.2);
|
|
}
|
|
}
|
|
</style> |