LoongPanel-Asp/web/pages/inspectionRecords.vue

304 lines
6.8 KiB
Vue
Raw Normal View History

2024-06-29 18:16:29 +08:00
<script setup lang="ts">
import {useMainLayoutStore} from "~/strores/UseMainLayoutStore";
definePageMeta({
layout: 'main',
middleware: ['auth']
})
const mainLayoutStore = useMainLayoutStore()
const selectWord = ref<string>()
type Document = {
wordId: string,
wordName: string,
lastModifyAt: string,
createAt: string,
fileSize: string
userName: string
}
type template = {
name: string,
content: string,
}
const documentList = ref<Document[]>([])
const templateList = ref<template[]>([])
onMounted(() => {
getWordList()
$fetch('/Api/Server/GetWordTemplates',{
method:'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': "Bearer " + useCookie('token').value
},
baseURL:useRuntimeConfig().public.baseUrl
}).then(res=>{
templateList.value = res as template[]
})
})
const getWordList = ()=>{
$fetch('/Api/Server/GetWordList',{
method:'GET',
params:{
ServerId:mainLayoutStore.SelectServer.id,
},
headers: {
'Content-Type': 'application/json',
'Authorization': "Bearer " + useCookie('token').value
},
baseURL:useRuntimeConfig().public.baseUrl
}).then(res=>{
documentList.value = res as Document[]
})
}
const editVisible= ref(false)
const isPreview = ref(false)
const selectWordChange=(wordId:string,preview:boolean=false)=>{
selectWord.value = wordId
editVisible.value = true
isPreview.value = preview
}
watch(editVisible,()=>{
if(!editVisible.value){
selectWord.value = undefined
isPreview.value = false
templateContent.value = undefined
}
})
const templateVisible = ref(false)
const templateContent= ref<string>()
const selectTemplate = (template:string)=>{
templateContent.value=template
editVisible.value = true
}
watch(()=>mainLayoutStore.SelectServer.id,()=>{
getWordList()
})
</script>
<template>
<div class="inspection-layout">
<Dialog
v-model:visible="editVisible"
:pt="{
root: {
style:'border:unset;background-color:unset;'
},
mask: {
style: 'backdrop-filter: blur(20px)'
}
}"
modal
>
<template #container="{ closeCallback }">
<MarkdownEdit :word-id="selectWord" :preview="isPreview" :template="templateContent"/>
</template>
</Dialog>
<Dialog
v-model:visible="templateVisible"
modal
header="选择一个模板"
>
<div class="template-layout">
<div class="template-item" @click="selectTemplate('')">
<doc-icons-word/>
<h5>不使用模板</h5>
</div>
<div class="template-item" v-for="t in templateList" :key="t.name" @click="selectTemplate(t.content)">
<doc-icons-word/>
<h5>{{t.name}}</h5>
</div>
</div>
</Dialog>
<Toolbar class="inspection-toolbar">
<template #start>
<input class="search" placeholder="搜索"/>
</template>
<template #end>
<div class="toolbar-start">
<button @click="templateVisible=true">
<Icon name="Plus" :stroke-width="1.2" />
<span>新建</span>
</button>
<button @click="getWordList" >
<Icon name="ListRestart" :stroke-width="1.2" />
<span>刷新</span>
</button>
</div>
</template>
</Toolbar>
<div class="inspection-content">
<div class="doc-item" v-for="doc in documentList" :key="doc.wordId">
<div class="icon">
<doc-icons-word/>
<h5>{{doc.wordName}}</h5>
</div>
<div class="info">
<p>创建日期:</p>
<p>{{doc.createAt}}</p>
<p>最后修改日期</p>
<p>{{doc.lastModifyAt}}</p>
<p>大小:</p>
<p>{{doc.fileSize}} KiB</p>
<p>创建者:</p>
<p>{{doc.userName}}</p>
</div>
<div class="action">
<button>删除</button>
<button @click="selectWordChange(doc.wordId,true)">查看</button>
<button @click="selectWordChange(doc.wordId)">编辑</button>
</div>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
@import "base";
.inspection-layout{
width: 100%;
min-height: 800px;
padding-top: 20px;
display: flex;
flex-direction: column;
gap: $gap*2;
container-type: layout/inline-size;
*{
@include SC_Font
}
}
.inspection-toolbar{
border: $border;
}
.toolbar-start{
display: flex;
gap: $gap;
button{
border: unset;
display: flex;
height: 100%;
gap: $gap*.5;
align-items: center;
justify-content: center;
border-radius: $radius;
background: unset;
svg,span{
stroke: rgba(51, 51, 51, 0.6);
color: rgba(51, 51, 51, 0.6);
}
&:hover,*:hover{
cursor: pointer;
svg,span{
stroke: rgba(51, 51, 51, 1);
color: rgba(51, 51, 51, 1);
}
}
}
}
.inspection-content{
border-radius: $radius;
display: grid;
grid-template-columns: repeat(20, 1fr);
gap: $gap*2;
}
@for $i from 1 through 20 {
@media (min-width: #{$i * 450}px) {
.inspection-content {
grid-template-columns: repeat($i, 1fr);
}
}
}
.doc-item{
background: $light-bg-color;
border-radius: $radius;
border: $border;
display: grid;
padding: $padding;
grid-template-columns: 80px 1fr;
grid-template-rows: 1fr auto;
gap: $gap*2;
.icon{
width: 100%;
height: min-content;
display: flex;
flex-direction: column;
gap: $gap*.5;
padding-bottom: $padding*.5;
align-items: center;
background: $light-bg-underline-color;
border-radius: $radius;
h5{
text-align: center;
padding: 0 $padding*.5;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
}
.info{
display: grid;
grid-template-columns: 1fr 1fr;
grid-row-gap: $gap*.5;
}
.action{
display: flex;
grid-column: 1/3;
border-top: $border;
padding: $padding 0 0;
gap: $gap;
button{
flex: 1;
background: unset;
border: unset;
border-radius: $radius;
&:hover{
cursor: pointer;
}
button:focus {
outline: unset;
border: unset;
}
}
}
}
.template-item{
width: 120px;
display: flex;
flex-direction: column;
gap: $gap*.5;
padding-bottom: $padding*.5;
align-items: center;
background: $light-bg-underline-color;
border: $border;
border-radius: $radius;
h5{
text-align: center;
padding: 0 $padding*.5;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
}
.template-layout{
display: grid;
grid-template-columns:repeat(3,minmax(0,auto));
gap: $gap;
.template-item:first-of-type{
svg{
filter: grayscale(100%)
}
}
}
.search{
border: $border;
padding: $padding*.5;
border-radius: $radius;
background: rgba(51, 51, 51, 0.1);
}
</style>