修改边距 适配多重侧边栏

This commit is contained in:
niyyzf 2024-07-22 21:05:18 +08:00
parent 1f0275a3a2
commit 5148df4491
21 changed files with 175 additions and 100 deletions

View File

@ -273,7 +273,7 @@ public class ServerController(IServiceProvider serviceProvider, ApplicationDbCon
var serverConfigs = JobConfigHelper.GetServers().ToList(); var serverConfigs = JobConfigHelper.GetServers().ToList();
var server = serverConfigs.Find(x =>x.Id == serverId); var server = serverConfigs.Find(x =>x.Id == serverId);
if (server == null) return BadRequest(); if (server == null) return BadRequest();
var output = await sshClient?.ExecuteCommandAsync(serverId,"awk -F: '$1 != \"nobody\" && $1 != \"build\" && $3 >= 1000 {print $1}'","/etc/passwd")!; var output = await sshClient?.ExecuteCommandAsync(serverId,"awk -F: '$1 != \"nobody\" &&$1 != \"build\" {print $1 \":\"$3}' /etc/passwd | sort -t: -k2nr")!;
if (string.IsNullOrEmpty(output)) return BadRequest("无法获得用户树"); if (string.IsNullOrEmpty(output)) return BadRequest("无法获得用户树");
var data = output.Split('\n', StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList(); var data = output.Split('\n', StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList();
output = await sshClient?.ExecuteCommandAsync(serverId,"w -husf","|"," awk '$2 !~ /^tty/ {print$1, $2}'"," |"," sort ","|"," uniq")!; output = await sshClient?.ExecuteCommandAsync(serverId,"w -husf","|"," awk '$2 !~ /^tty/ {print$1, $2}'"," |"," sort ","|"," uniq")!;
@ -461,6 +461,11 @@ public class ServerController(IServiceProvider serviceProvider, ApplicationDbCon
public async Task<IActionResult> GetWordList([FromQuery] string serverId) public async Task<IActionResult> GetWordList([FromQuery] string serverId)
{ {
var path = Path.Combine(AppContext.BaseDirectory, "markdowns", serverId); var path = Path.Combine(AppContext.BaseDirectory, "markdowns", serverId);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
var files = Directory.GetFiles(path); var files = Directory.GetFiles(path);
var wordList = new List<WordFileModel>(); var wordList = new List<WordFileModel>();
foreach (var file in files) foreach (var file in files)

View File

@ -20,10 +20,11 @@ $dark-text-color: #D3D3D3;
$dark-unfocused-color: $unfocused-color; $dark-unfocused-color: $unfocused-color;
$border:1px solid rgba(51, 51, 51, 0.17); $border:1px solid rgba(51, 51, 51, 0.17);
$border-dark:1px solid rgba(255, 255, 255, 0.17);
$gap: 8px; $gap: 4px;
$padding: 16px; $padding: 8px;
$radius: 8px; $radius: 4px;
.dark-mode html { .dark-mode html {
$dark-bg-color: red; $dark-bg-color: red;

View File

@ -82,7 +82,7 @@ const uploadFile=()=>{
$fetch('/Api/Server/UpLoadWord', { $fetch('/Api/Server/UpLoadWord', {
method: 'POST', method: 'POST',
params:{ params:{
serverId: mainLayoutStore.SelectServer.id, serverId: mainLayoutStore.SelectServer.value,
userName:mainLayoutStore.UserInfo.userName, userName:mainLayoutStore.UserInfo.userName,
wordId: id, wordId: id,
}, },
@ -108,7 +108,7 @@ onBeforeMount(()=>{
$fetch('/Api/Server/GetWordContent', { $fetch('/Api/Server/GetWordContent', {
method: 'GET', method: 'GET',
params:{ params:{
serverId: mainLayoutStore.SelectServer.id, serverId: mainLayoutStore.SelectServer.value,
wordId: props.wordId, wordId: props.wordId,
}, },
headers: { headers: {
@ -128,19 +128,18 @@ onBeforeMount(()=>{
<template> <template>
<div class="editor-layout"> <div class="editor-layout">
<Dialog <n-modal
v-model:visible="filenameVisible" v-model:show="filenameVisible"
modal preset="dialog"
header="输入文件名" title="输入文件名"
> >
<div class="fileName"> <div class="fileName">
<input v-model="fileName"> <input v-model="fileName">
<Button label="保存" @click="saveFileName" /> <n-button type="info" @click="saveFileName">
保存
</n-button>
</div> </div>
</Dialog> </n-modal>
<div class="actions">
<Icon name="X" @click="closeCallBack" ></Icon>
</div>
<MdEditor v-model="text" v-if="!preview" :theme="$colorMode.value as 'light'| 'dark'" class="editor" codeTheme="kimbie" <MdEditor v-model="text" v-if="!preview" :theme="$colorMode.value as 'light'| 'dark'" class="editor" codeTheme="kimbie"
@onSave="onSave" @onUploadImg="onUploadImg" /> @onSave="onSave" @onUploadImg="onUploadImg" />
<MdPreview :modelValue="text" v-else class="editor-preview"/> <MdPreview :modelValue="text" v-else class="editor-preview"/>
@ -170,8 +169,10 @@ onBeforeMount(()=>{
.fileName{ .fileName{
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center;
gap: $gap*4;
input{ input{
width: 70%; flex: 1;
border: $border; border: $border;
background: rgba(51, 51, 51, 0.1); background: rgba(51, 51, 51, 0.1);
border-radius: $radius; border-radius: $radius;

View File

@ -16,7 +16,7 @@ const GetServerUserList = () => {
$fetch('/Api/Server/GetServerUserList', { $fetch('/Api/Server/GetServerUserList', {
method: 'GET', method: 'GET',
params: { params: {
ServerId: mainLayoutStore.SelectServer.id ServerId: mainLayoutStore.SelectServer.value
}, },
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -36,7 +36,13 @@ const refresh = () => {
userList.value=[] userList.value=[]
GetServerUserList() GetServerUserList()
} }
const page=ref<number>(1)
const filterPage=computed(()=>{
if(userList.value.length<=10){
return userList.value
}
return userList.value.slice((page.value-1)*14,page.value*14)
})
</script> </script>
<template> <template>
@ -49,32 +55,39 @@ const refresh = () => {
<div class="user-list-body"> <div class="user-list-body">
<div class="user-list-item" @click="navigateTo(`/serverUser/all`)"> <div class="user-list-item" @click="navigateTo(`/serverUser/all`)">
<div class="avatar"> <div class="avatar">
<Avatar size="xlarge" shape="circle" class="avatar" label="全"/> <n-avatar
:size="48"> 全部 </n-avatar>
</div> </div>
<div class="info"> <div class="info">
<div class="top"> <div class="top">
<h3>全部</h3> <h3>全部</h3>
</div> </div>
<p>NULL</p>
</div> </div>
</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="{'user-list-item':true,'user-list-item-active':$route.params.id===item.name}" v-for="item in filterPage" @click="navigateTo(`/serverUser/${item.name.split(':')[0]}`)">
<div class="avatar"> <div class="avatar">
<Avatar size="xlarge" shape="circle" class="avatar" :label="item.name[0].toUpperCase()"/> <n-avatar
:size="48">
{{item.name.slice(0,3).toUpperCase()}}
</n-avatar>
</div> </div>
<div class="info"> <div class="info">
<div class="top"> <div class="top">
<h3>{{ item.name }}</h3> <h3>{{ item.name.split(':')[0] }}</h3>
<div class="tags"> <div class="tags">
<Tag v-if="item.isOnline">在线</Tag> <n-tag type="info" :bordered="false">UID:{{item.name.split(':')[1]}}</n-tag>
<Tag v-if="item.isOnline">{{item.port}}</Tag> <n-Tag v-if="item.isOnline">在线</n-Tag>
<Tag v-if="item.isOnline">{{item.address}}</Tag> <n-Tag v-if="item.isOnline">{{item.port}}</n-Tag>
<n-Tag v-if="item.isOnline">{{item.address}}</n-Tag>
</div> </div>
</div> </div>
<p>{{item.lastLoginTime}}</p> <p>{{item.lastLoginTime}}</p>
</div> </div>
</div> </div>
</div> </div>
<div class="pages">
<n-pagination v-model:page="page" :page-count="Math.floor(userList.length/13)" size="medium"/>
</div>
</div> </div>
</template> </template>
@ -87,6 +100,8 @@ const refresh = () => {
border: $border; border: $border;
padding: $padding 0; padding: $padding 0;
grid-row: 1/3; grid-row: 1/3;
display: flex;
flex-direction: column;
*{ *{
@include SC_Font; @include SC_Font;
} }
@ -124,19 +139,29 @@ const refresh = () => {
} }
} }
} }
.pages{
padding: $padding;
display: flex;
justify-content: center;
align-items: center;
}
.user-list-body{ .user-list-body{
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 1;
gap: $gap; gap: $gap;
padding: $padding*2 $padding; padding: $padding*2 $padding;
} }
.user-list-item{ .user-list-item{
display: flex; display: flex;
align-items: center; align-items: center;
gap: $gap; gap: $gap*4;
padding: 8px; padding: 8px;
border-radius: $radius; border-radius: $radius;
cursor: pointer; cursor: pointer;
.avatar{
display: flex;
}
h3,p{ h3,p{
color: $light-text-color; color: $light-text-color;
} }

View File

@ -9,10 +9,6 @@ const userInfo = toRef(MainLayoutStore.UserInfo)
<template> <template>
<div class="User-Mini-Box"> <div class="User-Mini-Box">
<NuxtImg :src="userInfo.avatar" alt="Avatar" height="45" width="45"/> <NuxtImg :src="userInfo.avatar" alt="Avatar" height="45" width="45"/>
<div>
<h3>{{ userInfo.nickName }}</h3>
<p>{{ userInfo.desc ?? "荒芜之地 ~ ~" }}</p>
</div>
</div> </div>
</template> </template>

View File

@ -5,6 +5,7 @@
<template> <template>
<div class="BottomBar-Box"> <div class="BottomBar-Box">
<div class="Left-Text-Box"> <div class="Left-Text-Box">
<p @click="$colorMode.preference = $colorMode.value == 'dark' ? 'light' : 'dark'" style="cursor: pointer">{{$colorMode.value=='dark'?'深色':'浅色'}}</p>
<p>隐私策略</p> <p>隐私策略</p>
<p>关于我们</p> <p>关于我们</p>
</div> </div>
@ -25,6 +26,10 @@
padding: 16px 24px; padding: 16px 24px;
align-items: center; align-items: center;
background: $light-bg-color; background: $light-bg-color;
border-top: $border;
.dark-mode &{
border-top: $border-dark;
}
} }
.Left-Text-Box { .Left-Text-Box {

View File

@ -92,8 +92,10 @@ watch(()=>activeKey.value,async (newValue)=>{
@collapse="collapsed = true" @collapse="collapsed = true"
@expand="collapsed = false" @expand="collapsed = false"
:width="200" :width="200"
:inverted="$colorMode.value == 'dark'"
> >
<n-menu <n-menu
:inverted="$colorMode.value == 'dark'"
:collapsed="collapsed" :collapsed="collapsed"
v-model:value="activeKey" v-model:value="activeKey"
:collapsed-width="64" :collapsed-width="64"
@ -102,6 +104,7 @@ watch(()=>activeKey.value,async (newValue)=>{
/> />
</n-layout-sider> </n-layout-sider>
</n-layout> </n-layout>
<div class="bottom"> <div class="bottom">
<PanelLeftOpen v-if="collapsed" @click="collapsed=false" /> <PanelLeftOpen v-if="collapsed" @click="collapsed=false" />
<PanelLeftClose v-else @click="collapsed=true" /> <PanelLeftClose v-else @click="collapsed=true" />
@ -119,6 +122,7 @@ watch(()=>activeKey.value,async (newValue)=>{
justify-content: space-between; justify-content: space-between;
align-items: flex-start; align-items: flex-start;
gap: $gap; gap: $gap;
border-right: $border;
background: $light-bg-color; background: $light-bg-color;
position: relative; position: relative;
*{ *{
@ -126,6 +130,7 @@ watch(()=>activeKey.value,async (newValue)=>{
} }
.dark-mode & { .dark-mode & {
background: $dark-bg-color; background: $dark-bg-color;
border-right: $border-dark;
} }
} }
@ -145,22 +150,31 @@ watch(()=>activeKey.value,async (newValue)=>{
} }
.header { .header {
height: 76px; height: 62px;
display: flex; display: flex;
width: 100%; width: 100%;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: $gap; gap: $gap;
h1{ h1{
font-size: 30px; font-size: 30px;
font-weight: 600; font-weight: 600;
} }
} }
.bottom{ .bottom{
height: 49px; height: 50px;
display: flex; display: flex;
align-items: center; align-items: center;
width: 100%; width: 100%;
padding: 20px; padding: 20px;
border-top: $border;
.dark-mode & {border-top: $border-dark;}
}
.n-layout{
background: unset;
}
.n-layout-sider{
background: unset;
} }
</style> </style>

View File

@ -46,11 +46,13 @@ const options = ref(['@gmail.com', '@outlook.com', '@yahoo.com'])
grid-template-columns: auto 1fr auto auto; grid-template-columns: auto 1fr auto auto;
grid-template-rows: 1fr; grid-template-rows: 1fr;
align-items: center; align-items: center;
padding: 0 $padding; padding: 0 $padding*2;
border-bottom: $border;
gap: $gap*2; gap: $gap*2;
@include SC_Font(); @include SC_Font();
.dark-mode & { .dark-mode & {
background: $dark-bg-color; background: $dark-bg-color;
border-bottom: $border-dark;
} }
} }

View File

@ -19,15 +19,19 @@ onMounted(() => {
@import "base"; @import "base";
.login-layout{ .login-layout{
background: white;
height: 100%; height: 100%;
min-height: 100vh; min-height: 100vh;
background: $light-bg-color;
width: 100%; width: 100%;
padding: 32px; padding: 32px;
gap: 32px; gap: 32px;
background: unset;
display: grid; display: grid;
grid-template-columns: 1fr minmax(800px,1fr); grid-template-columns: 1fr minmax(800px,1fr);
grid-template-rows: 1fr; grid-template-rows: 1fr;
.dark-mode &{
background: $dark-bg-color;
}
*{ *{
@include SC_Font; @include SC_Font;
} }
@ -39,6 +43,9 @@ onMounted(() => {
background: url("/bg1.jpg") no-repeat center center / cover; background: url("/bg1.jpg") no-repeat center center / cover;
//border: $border; //border: $border;
box-shadow: 2px 2px 10px rgba(0,0,0,0.1); box-shadow: 2px 2px 10px rgba(0,0,0,0.1);
.dark-mode &{
background-image: url("/bg2.jpg");
}
} }
.left-content{ .left-content{
position: relative; position: relative;

View File

@ -231,7 +231,7 @@ onKeyStroke('Shift', (e) => {
max-width: 100vw; max-width: 100vw;
display: grid; display: grid;
grid: grid:
"sidebar titlebar" 76px "sidebar titlebar" auto
"sidebar main" 1fr "sidebar main" 1fr
"sidebar folder" auto "sidebar folder" auto
/ auto 1fr; / auto 1fr;
@ -250,7 +250,7 @@ onKeyStroke('Shift', (e) => {
.main { .main {
display: grid; display: grid;
width: 100%; width: 100%;
grid-template-rows: 145px 55px 1fr; grid-template-rows: 125px 75px 1fr;
will-change: scroll-position; will-change: scroll-position;
padding-bottom: 400px; padding-bottom: 400px;
} }
@ -265,15 +265,15 @@ onKeyStroke('Shift', (e) => {
.hero-box { .hero-box {
position: absolute; position: absolute;
z-index: 11; z-index: 11;
left: $padding*2; left: $padding*3;
top: $padding; top: $padding*3;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: $gap; gap: $gap;
h3, p { h3, p {
color: #FFF; color: #FFF;
font-size: 40px; font-size: 30px;
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
line-height: normal; line-height: normal;
@ -291,8 +291,8 @@ onKeyStroke('Shift', (e) => {
.server-dropdown { .server-dropdown {
position: absolute; position: absolute;
z-index: 11; z-index: 11;
right: $padding*2.5; right: $padding*3;
top: $padding*2; top: $padding*3;
:deep(.n-select>.n-base-selection){ :deep(.n-select>.n-base-selection){
.n-base-selection__border{ .n-base-selection__border{
border: unset; border: unset;
@ -314,7 +314,7 @@ onKeyStroke('Shift', (e) => {
z-index: 10; z-index: 10;
width: 100%; width: 100%;
display: flex; display: flex;
padding: 0 40px 40px; padding: 0 20px 20px;
} }

View File

@ -24,7 +24,7 @@ const headers = computed(() => {
route: '/host/cpu' route: '/host/cpu'
}, { }, {
label: '内存', label: '内存',
icon: 'Cpu', icon: 'MemoryStick',
route: '/host/memory' route: '/host/memory'
}, },
...diskRoute.value.map(x => { ...diskRoute.value.map(x => {
@ -59,7 +59,7 @@ const getRote = () => {
$fetch('/Api/Server/GetServerDiskList', { $fetch('/Api/Server/GetServerDiskList', {
method: 'GET', method: 'GET',
params: { params: {
ServerId: mainLayoutStore.SelectServer.id ServerId: mainLayoutStore.SelectServer.value
}, },
baseURL: useRuntimeConfig().public.baseUrl, baseURL: useRuntimeConfig().public.baseUrl,
headers: { headers: {
@ -79,7 +79,7 @@ const getRote = () => {
$fetch('/Api/Server/GetServerNetworkEquipmentList', { $fetch('/Api/Server/GetServerNetworkEquipmentList', {
method: 'GET', method: 'GET',
params: { params: {
ServerId: mainLayoutStore.SelectServer.id ServerId: mainLayoutStore.SelectServer.value
}, },
baseURL: useRuntimeConfig().public.baseUrl, baseURL: useRuntimeConfig().public.baseUrl,
headers: { headers: {
@ -96,7 +96,7 @@ const getRote = () => {
}) })
}) })
} }
watch(() => mainLayoutStore.SelectServer.id, () => { watch(() => mainLayoutStore.SelectServer.value, () => {
getRote() getRote()
navigateTo('/host/cpu') navigateTo('/host/cpu')
reLoad.value = true reLoad.value = true

View File

@ -15,7 +15,7 @@ const getSystemInfo = () => {
method: 'GET', method: 'GET',
responseType: "json", responseType: "json",
params: { params: {
serverId: mainLayoutStore.SelectServer.id serverId: mainLayoutStore.SelectServer.value
}, },
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@ -16,7 +16,7 @@ onMounted(() => {
$fetch('/Api/Server/GetServerDiskInfo', { $fetch('/Api/Server/GetServerDiskInfo', {
method: 'GET', method: 'GET',
params: { params: {
ServerId: mainLayoutStore.SelectServer.id, ServerId: mainLayoutStore.SelectServer.value,
DiskId: id.value DiskId: id.value
}, },
headers: { headers: {
@ -212,7 +212,7 @@ onMounted(() => {
display: grid; display: grid;
grid-template-columns: 4px 1fr; grid-template-columns: 4px 1fr;
grid-template-rows: 1fr 1fr; grid-template-rows: 1fr 1fr;
grid-column-gap: $gap; grid-column-gap: $gap*2;
& > div { & > div {
height: 100%; height: 100%;

View File

@ -15,7 +15,7 @@ const getSystemInfo = () => {
method: 'GET', method: 'GET',
responseType: "json", responseType: "json",
params: { params: {
serverId: mainLayoutStore.SelectServer.id serverId: mainLayoutStore.SelectServer.value
}, },
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -39,7 +39,7 @@ onMounted(() => {
<div class="memory-layout"> <div class="memory-layout">
<div class="left-chart"> <div class="left-chart">
<div class="memory-title"> <div class="memory-title">
<h1>CPU</h1> <h1>内存</h1>
<h2>{{ (Number(dataStore.data["MemoryTotal"]) / 1024 / 1024).toFixed(2) }} GB</h2> <h2>{{ (Number(dataStore.data["MemoryTotal"]) / 1024 / 1024).toFixed(2) }} GB</h2>
</div> </div>
<div class="memory-chart-top"> <div class="memory-chart-top">

View File

@ -12,7 +12,7 @@ onMounted(() => {
$fetch('/Api/Server/GetServerNetworkEquipmentInfo', { $fetch('/Api/Server/GetServerNetworkEquipmentInfo', {
method: 'GET', method: 'GET',
params: { params: {
ServerId: mainLayoutStore.SelectServer.id, ServerId: mainLayoutStore.SelectServer.value,
NetworkId: id.value NetworkId: id.value
}, },
headers: { headers: {
@ -187,7 +187,7 @@ onMounted(() => {
display: grid; display: grid;
grid-template-columns: 4px 1fr; grid-template-columns: 4px 1fr;
grid-template-rows: 1fr 1fr; grid-template-rows: 1fr 1fr;
grid-column-gap: $gap; grid-column-gap: $gap*2;
& > div { & > div {
height: 100%; height: 100%;

View File

@ -40,7 +40,7 @@ const getNetworkList=()=>{
$fetch('/Api/Server/GetServerNetworkList',{ $fetch('/Api/Server/GetServerNetworkList',{
method:'GET', method:'GET',
params:{ params:{
ServerId:mainLayoutStore.SelectServer.id, ServerId:mainLayoutStore.SelectServer.value,
}, },
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@ -28,7 +28,7 @@ const getProcessList = async () => {
const response = await $fetch('/Api/Server/GetServerProcessesList', { const response = await $fetch('/Api/Server/GetServerProcessesList', {
method: 'GET', method: 'GET',
params: { params: {
ServerId: mainLayoutStore.SelectServer.id, ServerId: mainLayoutStore.SelectServer.value,
UserName:props.userName UserName:props.userName
}, },
baseURL: useRuntimeConfig().public.baseUrl, baseURL: useRuntimeConfig().public.baseUrl,

View File

@ -38,7 +38,7 @@ const getWordList = ()=>{
$fetch('/Api/Server/GetWordList',{ $fetch('/Api/Server/GetWordList',{
method:'GET', method:'GET',
params:{ params:{
ServerId:mainLayoutStore.SelectServer.id, ServerId:mainLayoutStore.SelectServer.value,
}, },
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -68,34 +68,33 @@ const templateContent= ref<string>()
const selectTemplate = (template:string)=>{ const selectTemplate = (template:string)=>{
templateContent.value=template templateContent.value=template
editVisible.value = true editVisible.value = true
templateVisible.value = false
} }
watch(()=>mainLayoutStore.SelectServer.id,()=>{ watch(()=>mainLayoutStore.SelectServer.value,()=>{
getWordList() getWordList()
}) })
</script> </script>
<template> <template>
<div class="inspection-layout"> <div class="inspection-layout">
<Dialog <n-modal
v-model:visible="editVisible" v-model:show="editVisible"
:pt="{ title="编辑器"
root: { :mask-closable="false"
style:'border:unset;background-color:unset;' :close-on-esc="false"
}, size="medium"
mask: { preset="card"
style: 'backdrop-filter: blur(20px)' transform-origin="center"
} style="width: auto"
}"
modal
> >
<template #container="{ closeCallback }"> <MarkdownEdit :word-id="selectWord" :preview="isPreview" :template="templateContent" />
<MarkdownEdit :word-id="selectWord" :preview="isPreview" :template="templateContent" :close-call-back="closeCallback"/> </n-modal>
</template> <n-modal
</Dialog> title="选择一个模板"
<Dialog size="medium"
v-model:visible="templateVisible" preset="card"
modal style="width: 500px"
header="选择一个模板" v-model:show="templateVisible"
> >
<div class="template-layout"> <div class="template-layout">
<div class="template-item" @click="selectTemplate('')"> <div class="template-item" @click="selectTemplate('')">
@ -107,25 +106,20 @@ watch(()=>mainLayoutStore.SelectServer.id,()=>{
<h5>{{t.name}}</h5> <h5>{{t.name}}</h5>
</div> </div>
</div> </div>
</Dialog> </n-modal>
<Toolbar class="inspection-toolbar"> <div class="inspection-toolbar">
<template #start> <input class="search" placeholder="搜索"/>
<input class="search" placeholder="搜索"/> <div class="toolbar-start">
</template> <button @click="templateVisible=true">
<Icon name="Plus" :stroke-width="1.2" />
<template #end> <span>新建</span>
<div class="toolbar-start"> </button>
<button @click="templateVisible=true"> <button @click="getWordList" >
<Icon name="Plus" :stroke-width="1.2" /> <Icon name="ListRestart" :stroke-width="1.2" />
<span>新建</span> <span>刷新</span>
</button> </button>
<button @click="getWordList" > </div>
<Icon name="ListRestart" :stroke-width="1.2" /> </div>
<span>刷新</span>
</button>
</div>
</template>
</Toolbar>
<div class="inspection-content"> <div class="inspection-content">
<div class="doc-item" v-for="doc in documentList" :key="doc.wordId"> <div class="doc-item" v-for="doc in documentList" :key="doc.wordId">
<div class="icon"> <div class="icon">
@ -169,6 +163,10 @@ watch(()=>mainLayoutStore.SelectServer.id,()=>{
} }
.inspection-toolbar{ .inspection-toolbar{
border: $border; border: $border;
display: flex;
padding: $padding*2;
border-radius: $radius;
justify-content: space-between;
background: $light-bg-color; background: $light-bg-color;
.dark-mode &{ .dark-mode &{
background: $dark-bg-color; background: $dark-bg-color;
@ -324,9 +322,9 @@ watch(()=>mainLayoutStore.SelectServer.id,()=>{
} }
} }
.template-layout{ .template-layout{
display: grid; display: flex;
grid-template-columns:repeat(3,minmax(0,auto));
gap: $gap; gap: $gap;
flex-wrap: wrap;
.template-item:first-of-type{ .template-item:first-of-type{
svg{ svg{
filter: grayscale(100%) filter: grayscale(100%)

View File

@ -20,7 +20,7 @@ watch(()=>userId.value,()=>{
reload.value=false; reload.value=false;
}) })
}) })
watch(()=>mainLayoutStore.SelectServer.id,()=>{ watch(()=>mainLayoutStore.SelectServer.value,()=>{
pageReload.value=true; pageReload.value=true;
setTimeout(()=> { setTimeout(()=> {
pageReload.value = false; pageReload.value = false;
@ -30,7 +30,7 @@ const processList=ref<string[]>([])
const updateProcessList=(data:string[])=>{ const updateProcessList=(data:string[])=>{
processList.value=data processList.value=data
} }
watch(() => mainLayoutStore.SelectServer.id, () => { watch(() => mainLayoutStore.SelectServer.value, () => {
navigateTo('/serverUser/all') navigateTo('/serverUser/all')
}) })
</script> </script>

View File

@ -144,6 +144,9 @@ const onSuccess = () => {
font-weight: 800; font-weight: 800;
line-height: 100%; /* 36px */ line-height: 100%; /* 36px */
letter-spacing: 0.36px; letter-spacing: 0.36px;
.dark-mode &{
color: #FFF;
}
} }
h2{ h2{
color: #313957; color: #313957;
@ -152,6 +155,10 @@ const onSuccess = () => {
font-weight: 400; font-weight: 400;
line-height: 160%; /* 32px */ line-height: 160%; /* 32px */
letter-spacing: 0.2px; letter-spacing: 0.2px;
.dark-mode &{
color: #e3e3e3;
}
} }
} }
.login-form{ .login-form{
@ -162,6 +169,16 @@ const onSuccess = () => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
.dark-mode &{
label{
color: #FFF;
}
input{
background: #0C1421;
color: #FFF;
}
}
label{ label{
color: #0C1421; color: #0C1421;
font-feature-settings: 'clig' off, 'liga' off; font-feature-settings: 'clig' off, 'liga' off;
@ -201,6 +218,10 @@ const onSuccess = () => {
font-weight: 400; font-weight: 400;
line-height: 100%; /* 20px */ line-height: 100%; /* 20px */
letter-spacing: 2px; letter-spacing: 2px;
.dark-mode &{
background: #FFF;
color: #162D3A;
}
} }
} }
.social-sign-in{ .social-sign-in{

BIN
web/public/bg2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 KiB