完成管理页面的结构
This commit is contained in:
parent
bd903154ab
commit
07230156e6
@ -1,19 +1,22 @@
|
||||
<template>
|
||||
<div>
|
||||
<button @click="showMessage">显示消息</button>
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
// 主要实现应用的初始化
|
||||
import message from "./components/message";
|
||||
import {useUserStore} from "./service/store";
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
|
||||
setup() {
|
||||
useUserStore().updateInfo();
|
||||
// TODO 进行系统数据的初始化
|
||||
return {
|
||||
// login->index->具体某个业务页面
|
||||
showMessage() {
|
||||
message.toast('test display')
|
||||
}
|
||||
|
@ -1,5 +1,44 @@
|
||||
:root {
|
||||
--primary-color: #fff;
|
||||
--primary-color: #1890ff;
|
||||
--primary-color-hover: #40a9ff;
|
||||
--primary-color-active: #096dd9;
|
||||
--primary-color-outline: rgba(24, 144, 255, .2);
|
||||
--primary-1: #e6f7ff;
|
||||
--primary-2: #bae7ff;
|
||||
--primary-3: #91d5ff;
|
||||
--primary-4: #69c0ff;
|
||||
--primary-5: #40a9ff;
|
||||
--primary-6: #1890ff;
|
||||
--primary-7: #096dd9;
|
||||
--primary-color-deprecated-l-35: #cbe6ff;
|
||||
--primary-color-deprecated-l-20: #7ec1ff;
|
||||
--primary-color-deprecated-t-20: #46a6ff;
|
||||
--primary-color-deprecated-t-50: #8cc8ff;
|
||||
--primary-color-deprecated-f-12: rgba(24, 144, 255, .12);
|
||||
--primary-color-active-deprecated-f-30: rgba(230, 247, 255, .3);
|
||||
--primary-color-active-deprecated-d-02: #dcf4ff;
|
||||
--success-color: #52c41a;
|
||||
--success-color-hover: #73d13d;
|
||||
--success-color-active: #389e0d;
|
||||
--success-color-outline: rgba(82, 196, 26, .2);
|
||||
--success-color-deprecated-bg: #f6ffed;
|
||||
--success-color-deprecated-border: #b7eb8f;
|
||||
--error-color: #ff4d4f;
|
||||
--error-color-hover: #ff7875;
|
||||
--error-color-active: #d9363e;
|
||||
--error-color-outline: rgba(255, 77, 79, .2);
|
||||
--error-color-deprecated-bg: #fff2f0;
|
||||
--error-color-deprecated-border: #ffccc7;
|
||||
--warning-color: #faad14;
|
||||
--warning-color-hover: #ffc53d;
|
||||
--warning-color-active: #d48806;
|
||||
--warning-color-outline: rgba(250, 173, 20, .2);
|
||||
--warning-color-deprecated-bg: #fffbe6;
|
||||
--warning-color-deprecated-border: #ffe58f;
|
||||
--info-color: #1890ff;
|
||||
--info-color-deprecated-bg: #e6f7ff;
|
||||
--info-color-deprecated-border: #91d5ff;
|
||||
|
||||
--primary-color-text: #333;
|
||||
--font-size: 14px;
|
||||
--font-size-small: calc(var(--font-size) - 2px);
|
||||
@ -8,12 +47,16 @@
|
||||
--border-radius: 1px;
|
||||
--border-radius-middle: calc(var(--border-radius) + 2px);
|
||||
--border-radius-large: calc(var(--border-radius) + 3px);
|
||||
|
||||
--header-height: 80px;
|
||||
--left-menu-width: 200px;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
*, *:before, *:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@ -21,10 +64,12 @@
|
||||
input[type=text], input[type=password], input[type=number], textarea {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
[class^=p-]::-ms-clear, [class*=p-]::-ms-clear, [class^=p-] input::-ms-clear,
|
||||
[class*=p-] input::-ms-clear, [class^=p-] input::-ms-reveal, [class*=p-] input::-ms-reveal {
|
||||
display: none
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, 'Source Han Sans SC', 'Microsoft YaHei', 'Microsoft YaHei UI', "Helvetica Neue", sans-serif;
|
||||
scroll-behavior: smooth;
|
||||
@ -70,6 +115,7 @@ body {
|
||||
|
||||
.icon-svg {
|
||||
}
|
||||
|
||||
.pointer-cursor {
|
||||
cursor: pointer;
|
||||
}
|
3
admin-fe/src/components/input/index.ts
Normal file
3
admin-fe/src/components/input/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import PInput from './input.vue'
|
||||
|
||||
export default PInput
|
@ -12,4 +12,5 @@ const app = createApp(App)
|
||||
// 使用路由
|
||||
app.use(router)
|
||||
app.use(createPinia());
|
||||
// 将应用实例挂载到 模板中
|
||||
app.mount('#vue-root-app')
|
@ -3,15 +3,22 @@ import Home from '../views/admin/Home.vue'
|
||||
import Login from '../views/Login.vue'
|
||||
import NotFound from '../views/NotFound.vue'
|
||||
import Test from '../views/Test.vue'
|
||||
import AdminLayout from '../views/layout/AdminLayout.vue'
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/',
|
||||
component: Test
|
||||
component: AdminLayout,
|
||||
children: [
|
||||
{
|
||||
path: 'home',
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: '/home',
|
||||
component: Home
|
||||
path: 'test',
|
||||
component: Test
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
|
@ -16,7 +16,8 @@ export const useTestStore = defineStore('test-store', {
|
||||
},
|
||||
actions: {}
|
||||
})
|
||||
|
||||
// 保存数据的key
|
||||
const TOKEN_KEY = "user-login-token";
|
||||
export const useUserStore = defineStore('user-store', () => {
|
||||
const userinfo = ref<AdminLoginModel>()
|
||||
|
||||
@ -25,11 +26,16 @@ export const useUserStore = defineStore('user-store', () => {
|
||||
userinfo.value = data
|
||||
}
|
||||
|
||||
function token() {
|
||||
if (userinfo.value && userinfo.value.token) return userinfo.value.token;
|
||||
return localStorage.getItem(TOKEN_KEY)
|
||||
}
|
||||
|
||||
async function login(params: any) {
|
||||
try {
|
||||
const data = await http.post<AdminLoginModel>('/admin/user/login', params)
|
||||
userinfo.value = data
|
||||
localStorage.setItem("user-login-token", data.token)
|
||||
localStorage.setItem(TOKEN_KEY, data.token)
|
||||
} catch (e) {
|
||||
message.toast('登录失败:' + e.message)
|
||||
throw e;
|
||||
@ -38,10 +44,10 @@ export const useUserStore = defineStore('user-store', () => {
|
||||
|
||||
async function logout() {
|
||||
const data = await http.get<AdminLoginModel>('/admin/user/info')
|
||||
localStorage.removeItem('user-login-token')
|
||||
localStorage.removeItem(TOKEN_KEY)
|
||||
userinfo.value = null
|
||||
|
||||
}
|
||||
|
||||
return {userinfo, login, logout}
|
||||
return {userinfo, login, logout, updateInfo, token}
|
||||
})
|
@ -1,4 +1,6 @@
|
||||
import {toast} from "../components/message";
|
||||
import {useUserStore} from "../service/store";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
|
||||
export type HttpMethod = 'get' | 'post' | 'delete' | 'put'
|
||||
|
||||
@ -69,12 +71,16 @@ class Http {
|
||||
}
|
||||
}
|
||||
|
||||
const headers: any = {
|
||||
'Content-Type': contentType
|
||||
}
|
||||
const token = useUserStore().token();
|
||||
if (token) headers.token = token
|
||||
const r = useRoute(), router = useRouter();
|
||||
fetch(httpConfig.baseURL + url, {
|
||||
method,
|
||||
body: data,
|
||||
headers: {
|
||||
'Content-Type': contentType
|
||||
}
|
||||
headers,
|
||||
})
|
||||
.then(res => res.json()) // 只要json的响应数据
|
||||
.then((res: ResponseModel<T>) => {
|
||||
@ -84,6 +90,9 @@ class Http {
|
||||
// 需要统一处理数据
|
||||
if (code === 403) {
|
||||
toast("登录凭证无效或者已过期")
|
||||
if (r.fullPath != '/login') {
|
||||
router.replace('/login');
|
||||
}
|
||||
return;
|
||||
} else if (err) {
|
||||
toast(httpConfig.globalErrorHandler[code])
|
||||
|
@ -2,10 +2,10 @@
|
||||
<div class="login-wrapper">
|
||||
<form @submit="onLogin">
|
||||
<p>
|
||||
<input placeholder="请输入账号" type="text" v-model="data.account">
|
||||
<PInput placeholder="请输入密码" type="text" v-model="data.account"/>
|
||||
</p>
|
||||
<p>
|
||||
<input placeholder="请输入密码" type="text" v-model="data.password">
|
||||
<PInput placeholder="请输入密码" type="password" v-model="data.password"/>
|
||||
</p>
|
||||
<button :disabled="loading" :type="loading?'button':'submit'">{{ loading ? '正在登录' : '登录' }}</button>
|
||||
</form>
|
||||
@ -14,12 +14,13 @@
|
||||
|
||||
<script lang="ts">
|
||||
import {reactive, ref} from "vue";
|
||||
import http from "../util/http";
|
||||
import PInput from './../components/input'
|
||||
import {useUserStore} from "../service/store";
|
||||
import {useRouter} from "vue-router";
|
||||
|
||||
export default {
|
||||
name: "User",
|
||||
components: {PInput},
|
||||
setup() {
|
||||
// vue 数据双向绑定(响应式原理)
|
||||
// vue2 Object.definedProperty
|
||||
@ -58,7 +59,9 @@ export default {
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
p{
|
||||
margin: 10px 0;
|
||||
}
|
||||
.login-wrapper {
|
||||
width: 500px;
|
||||
margin: 50px auto;
|
||||
|
@ -20,7 +20,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import PInput from "../components/input/index.vue";
|
||||
import PInput from "../components/input";
|
||||
import {reactive} from "vue";
|
||||
|
||||
const data = reactive({
|
||||
|
@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<h1>Home</h1>
|
||||
<h1> Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home</h1>
|
||||
<h1> Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home</h1>
|
||||
<h1> Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home</h1>
|
||||
<h1> Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home</h1>
|
||||
<h1> Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home</h1>
|
||||
<router-link to="/user">User</router-link>
|
||||
</template>
|
||||
|
||||
|
71
admin-fe/src/views/layout/AdminLayout.vue
Normal file
71
admin-fe/src/views/layout/AdminLayout.vue
Normal file
@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div class="app-admin-layout">
|
||||
<div class="header">
|
||||
<!-- 头部 -->
|
||||
<div class="user-info">
|
||||
<span>
|
||||
{{ userStore.userinfo?.account }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="left-menu">左侧的菜单
|
||||
<div>
|
||||
<router-link to="/test">TEST</router-link>
|
||||
</div>
|
||||
<div>
|
||||
<router-link to="/home">HOME</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-wrapper">
|
||||
<!-- 内容区域-->
|
||||
<router-view/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import {useUserStore} from "../../service/store";
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
</script>
|
||||
<style lang="less">
|
||||
.app-admin-layout {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
line-height: 80px;
|
||||
padding: 0 20px;
|
||||
text-align: right;
|
||||
position: fixed;
|
||||
height: 80px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.main {
|
||||
background-color: #eee;
|
||||
padding-top: var(--header-height);
|
||||
padding-left: var(--left-menu-width);
|
||||
|
||||
.left-menu {
|
||||
width: 200px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
padding: 20px;
|
||||
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
}
|
||||
}
|
||||
</style>
|
@ -2,6 +2,7 @@ import vue from '@vitejs/plugin-vue'
|
||||
import vueJsxPlugin from "@vitejs/plugin-vue-jsx";
|
||||
|
||||
export default {
|
||||
// 开发服务信息
|
||||
server: {
|
||||
host:'::'
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user