feat: 1.配置刷新token相关逻辑,2.添加后台服务页面 3.优化样式。

This commit is contained in:
539943419 committed 2025-01-16 22:25:46 +08:00
1 parent 934bc15cb8
commit 63ab8544d7
8 files changed
+171 -20

No files matched your search

+1
View File
@@ -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>
+3
View File
@@ -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>
+7
View File
@@ -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;
-5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+118
View File
@@ -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>