feat: 1.配置刷新token相关逻辑,2.添加后台服务页面 3.优化样式。
This commit is contained in:
1 parent
934bc15cb8
commit
63ab8544d7
8 files changed
+171
-20
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
<template><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M256 112v288"></path><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M400 256H112"></path></svg></template>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512"><path d="M100.18 241.19a15.93 15.93 0 0 0 13.37-13.25C126.6 145.59 186.34 96 256 96c64.69 0 107.79 42.36 124.92 87a16.11 16.11 0 0 0 12.53 10.18C449.36 202.06 496 239.21 496 304c0 66-54 112-120 112H116c-55 0-100-27.44-100-88c0-54.43 43.89-80.81 84.18-86.81z" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32"></path></svg>
|
||||||
|
</template>
|
||||||
@@ -20,9 +20,16 @@ export const useUserStore = defineStore("user", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const token = computed(() => {
|
const token = computed(() => {
|
||||||
|
console.log('token')
|
||||||
if (_token.value) {
|
if (_token.value) {
|
||||||
return _token.value;
|
return _token.value;
|
||||||
}
|
}
|
||||||
|
if(tokenExpireTime.value < Date.now()) {
|
||||||
|
localStorage.removeItem("miao-token");
|
||||||
|
localStorage.removeItem("miao-token-expire-time");
|
||||||
|
_token.value = undefined;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
const res = localStorage.getItem("miao-token") || ""
|
const res = localStorage.getItem("miao-token") || ""
|
||||||
_token.value = res;
|
_token.value = res;
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -18,11 +18,6 @@ export default defineNuxtConfig({
|
|||||||
vite: {
|
vite: {
|
||||||
server: {},
|
server: {},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
test: {
|
|
||||||
deps: {
|
|
||||||
inline: ['element-plus']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
modules: ["@pinia/nuxt", '@element-plus/nuxt'],
|
modules: ["@pinia/nuxt", '@element-plus/nuxt'],
|
||||||
compatibilityDate: "2025-01-12",
|
compatibilityDate: "2025-01-12",
|
||||||
|
|||||||
+13
-10
@@ -11,22 +11,22 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row style="width: 100%;" :gutter="20">
|
<el-row style="width: 100%;" :gutter="20">
|
||||||
<el-col :span="16" class="col-flex-end">
|
<el-col :span="13" class="col-flex-end">
|
||||||
<el-text size="large">刷赞数:</el-text>
|
<el-text size="large" style="margin-right: 7px;">赞数</el-text>
|
||||||
<el-input-number v-model="likes" :min="1" :max="300" />
|
<el-input-number style="width: 130px;" v-model="likes" :min="1" :max="300" />
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4" class="col-flex-end">
|
<el-col :span="4" class="col-flex-end">
|
||||||
<el-button type="primary" style="width: 100%"
|
<el-button type="primary" style="width: 100%"
|
||||||
:disabled="status === 'busy' || id === undefined" @click="handleStart">开始</el-button>
|
:disabled="status === 'busy' || id === undefined" @click="handleStart">开始</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4" class="col-flex-end">
|
<el-col :span="7" class="col-flex-end">
|
||||||
<el-button type="primary" style="width: 100%" :disabled="messages.length === 0" @click="handleClear">清空输出</el-button>
|
<el-button type="primary" style="width: 100%" :disabled="messages.length === 0" @click="handleClear">清空输出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="message-container-wrapper">
|
<div class="message-container-wrapper">
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<div class="message-container">
|
<div class="message-container">
|
||||||
<el-text v-for="(message, index) in messages" :key="message.timestamp" class="message-container-message">
|
<el-text v-for="(message) in messages" :key="message.id" class="message-container-message">
|
||||||
<span style="margin-right: 7px;">{{ `${_fd(message.timestamp)} ==>`
|
<span style="margin-right: 7px;">{{ `${_fd(message.timestamp)} ==>`
|
||||||
}}</span>
|
}}</span>
|
||||||
<span>{{ message.message }}</span>
|
<span>{{ message.message }}</span>
|
||||||
@@ -46,13 +46,15 @@ const status = ref<'waiting' | 'busy'>('waiting')
|
|||||||
|
|
||||||
const messages = reactive<{
|
const messages = reactive<{
|
||||||
timestamp: number,
|
timestamp: number,
|
||||||
message: string
|
message: string,
|
||||||
|
id: number
|
||||||
}[]>([])
|
}[]>([])
|
||||||
|
|
||||||
const log = (...message: string[]) => {
|
const log = (...message: string[]) => {
|
||||||
messages.push({
|
messages.unshift({
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
message: message.join('')
|
message: message.join(''),
|
||||||
|
id: Math.random()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,13 +130,14 @@ watchEffect(() => {
|
|||||||
/* padding: 5px 10px; */
|
/* padding: 5px 10px; */
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
/* max-height: 500px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-container {
|
.message-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
height: 100%;
|
height: calc( 100vh - 350px );
|
||||||
max-height: 500px;
|
max-height: calc( 100vh - 350px );
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
+22
-4
@@ -26,11 +26,29 @@ const userStore = useUserStore()
|
|||||||
// ]
|
// ]
|
||||||
// })
|
// })
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(async () => {
|
||||||
if (userStore.isLogin === false) {
|
if (userStore && userStore.isLogin) {
|
||||||
return router.replace('/user/login')
|
|
||||||
} else {
|
|
||||||
return router.replace('/user/main')
|
return router.replace('/user/main')
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if(userStore.token) {
|
||||||
|
const response = await $fetch('/api/user/refreshToken', {
|
||||||
|
method: 'POST',
|
||||||
|
body: {
|
||||||
|
token: userStore.token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
userStore.setToken(response.token)
|
||||||
|
userStore.setTokenExpireTime(response.expiresIn)
|
||||||
|
userStore.setLoginStatus(true)
|
||||||
|
router.replace('/user/main')
|
||||||
|
} else {
|
||||||
|
router.replace('/user/login')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
router.replace('/user/login')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+7
-1
@@ -44,6 +44,7 @@ import Cat from '~/components/icons/cat.vue'
|
|||||||
import chevronDown from '~/components/icons/chevronDown.vue';
|
import chevronDown from '~/components/icons/chevronDown.vue';
|
||||||
import Documents from '~/components/icons/documents.vue';
|
import Documents from '~/components/icons/documents.vue';
|
||||||
import Home from '~/components/icons/home.vue';
|
import Home from '~/components/icons/home.vue';
|
||||||
|
import Cloud from '~/components/icons/cloud.vue';
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
@@ -63,11 +64,16 @@ const menuItem = shallowReactive([
|
|||||||
title: '账户',
|
title: '账户',
|
||||||
icon: Cat,
|
icon: Cat,
|
||||||
to: '/user/main/account'
|
to: '/user/main/account'
|
||||||
|
}, {
|
||||||
|
title: '服务',
|
||||||
|
icon: Cloud,
|
||||||
|
iconFill: true,
|
||||||
|
to: '/user/main/server'
|
||||||
}, {
|
}, {
|
||||||
title: '测试',
|
title: '测试',
|
||||||
icon: Cat,
|
icon: Cat,
|
||||||
to: '/user/main/test'
|
to: '/user/main/test'
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const showSidebar = ref(true)
|
const showSidebar = ref(true)
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<div class="user-server-config">
|
||||||
|
<el-container>
|
||||||
|
<el-header>
|
||||||
|
<h1>服务端配置</h1>
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
|
<el-divider content-position="left">
|
||||||
|
<h2>更新服务端</h2>
|
||||||
|
|
||||||
|
</el-divider>
|
||||||
|
<p>上传更新包并更新服务端</p>
|
||||||
|
<el-upload
|
||||||
|
:auto-upload="false"
|
||||||
|
v-model="fileList"
|
||||||
|
action="/api/system/update"
|
||||||
|
ref="uploadRef"
|
||||||
|
:headers="headers"
|
||||||
|
drag
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:on-change="handleUploadChange"
|
||||||
|
:limit="1"
|
||||||
|
>
|
||||||
|
<template #trigger>
|
||||||
|
<div class="server-upload">
|
||||||
|
<add class="server-upload-icon"></add>
|
||||||
|
<el-text style="margin: 0;">拖拽 output.tar.gz 至此<br />或单击此处选择文件</el-text>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24" class="flex-end">
|
||||||
|
<el-button type="success" @click="submitUpload">
|
||||||
|
点击上传更新包并更新服务
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { UploadInstance, UploadRawFile, UploadUserFile } from 'element-plus/es/components/index.mjs';
|
||||||
|
import useUserStore from '~/hooks/pinia/useUserStore';
|
||||||
|
import add from '~/components/icons/add.vue';
|
||||||
|
import { genFileId } from 'element-plus'
|
||||||
|
|
||||||
|
|
||||||
|
const fileList = ref<UploadUserFile[]>([])
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
|
||||||
|
const uploadRef = ref<UploadInstance>()
|
||||||
|
|
||||||
|
const headers = computed(() => {
|
||||||
|
return {
|
||||||
|
Authorization: `Bearer ${userStore.token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleExceed = (files: UploadUserFile[]) => {
|
||||||
|
uploadRef.value!.clearFiles()
|
||||||
|
const file = files[0] as UploadRawFile
|
||||||
|
file.uid = genFileId()
|
||||||
|
uploadRef.value!.handleStart(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUploadChange = (_file: UploadUserFile, files: UploadUserFile[]) => {
|
||||||
|
for (let i = files.length - 1; i >= 0; i--) {
|
||||||
|
if (files[i].name !== 'output.tar.gz') {
|
||||||
|
files.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitUpload = () => {
|
||||||
|
uploadRef.value!.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.user-server-config {
|
||||||
|
position: relative;
|
||||||
|
padding: 10px 20px;
|
||||||
|
.server-upload {
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all .2s ease;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
&-icon {
|
||||||
|
width: 45px;
|
||||||
|
color: #595959;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: xx-large;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: larger;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: #595959;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-end {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in new issue
Block a user