feat(back): 后台布局、书籍加载完成
This commit is contained in:
parent
fe388551db
commit
1a5453bb32
1
package-lock.json
generated
1
package-lock.json
generated
@ -11,6 +11,7 @@
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.8.2",
|
||||
"dayjs": "^1.11.13",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0",
|
||||
"vue3-slide-verify": "^1.1.6",
|
||||
|
@ -12,6 +12,7 @@
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.8.2",
|
||||
"dayjs": "^1.11.13",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0",
|
||||
"vue3-slide-verify": "^1.1.6",
|
||||
|
10
src/App.vue
10
src/App.vue
@ -1,9 +1,19 @@
|
||||
<script setup>
|
||||
import zhCN from 'ant-design-vue/es/locale/zh_CN';
|
||||
import dayjs from 'dayjs';
|
||||
import 'dayjs/locale/zh-cn';
|
||||
|
||||
// 设置 dayjs 的语言为中文
|
||||
dayjs.locale('zh-cn');
|
||||
|
||||
// 定义响应式数据
|
||||
const locale = zhCN;
|
||||
</script>
|
||||
|
||||
<template style="width: 100%;height: 100%;margin: 0;padding: 0">
|
||||
<a-config-provider :locale="locale">
|
||||
<router-view style="width: 100%;height: 100%"></router-view>
|
||||
</a-config-provider>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
24
src/apis/apis_book.js
Normal file
24
src/apis/apis_book.js
Normal file
@ -0,0 +1,24 @@
|
||||
// apis_book.js
|
||||
|
||||
// 获取所有图书
|
||||
import {get, post,put, deleteRequest} from "./api.js";
|
||||
|
||||
// 分页查询(查询参数通过URL传递)
|
||||
export const getBooks = async (data) => {
|
||||
return get(`/book/books`,data);
|
||||
};
|
||||
|
||||
// 新增(POST)
|
||||
export const addBook = async (bookData) => {
|
||||
return post("/book/books", bookData);
|
||||
};
|
||||
|
||||
// 更新(PUT,注意路径拼接ID)
|
||||
export const updateBook = async (bookId, bookData) => {
|
||||
return put(`/book/books/${bookId}`, bookData); // 关键修正:拼接ID
|
||||
};
|
||||
|
||||
// 删除(DELETE,注意路径拼接ID)
|
||||
export const deleteBook = async (bookId) => {
|
||||
return deleteRequest(`/book/books/${bookId}`); // 关键修正:拼接ID
|
||||
};
|
71
src/components/back/layout/AsideVue.vue
Normal file
71
src/components/back/layout/AsideVue.vue
Normal file
@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div style="width: 100%;height: 100%">
|
||||
<a-menu
|
||||
v-model:openKeys="openKeys"
|
||||
v-model:selectedKeys="selectedKeys"
|
||||
style="width: 100%;height: 100%"
|
||||
mode="inline"
|
||||
:theme="theme"
|
||||
:items="items"
|
||||
@click="handleMenuClick"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { h, ref } from 'vue';
|
||||
import {
|
||||
MailOutlined,
|
||||
CalendarOutlined,
|
||||
AppstoreOutlined,
|
||||
SettingOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import {useRouter} from "vue-router";
|
||||
const router = useRouter();
|
||||
const theme = ref('light');
|
||||
const selectedKeys = ref(['1']);
|
||||
const openKeys = ref(['sub1']);
|
||||
const items = ref([
|
||||
{
|
||||
key: '1',
|
||||
icon: () => h(AppstoreOutlined),
|
||||
label: '首页',
|
||||
title: '首页',
|
||||
path: '/back/index',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
icon: () => h(CalendarOutlined),
|
||||
label: '书籍管理',
|
||||
title: '书籍管理',
|
||||
path: '/back/admin/book',
|
||||
},
|
||||
{
|
||||
key: 'sub1',
|
||||
icon: () => h(SettingOutlined),
|
||||
label: '系统管理',
|
||||
title: '系统管理',
|
||||
children: [
|
||||
{
|
||||
key: '3',
|
||||
label: '用户管理',
|
||||
title: '用户管理',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
icon: () => h(MailOutlined),
|
||||
label: '消息',
|
||||
title: '消息',
|
||||
},
|
||||
]);
|
||||
const changeTheme = checked => {
|
||||
theme.value = checked ? 'dark' : 'light';
|
||||
};
|
||||
const handleMenuClick = ({ key }) => {
|
||||
const item = items.value.find(item => item.key === key);
|
||||
if (item && item.path) {
|
||||
router.push(item.path);
|
||||
}
|
||||
};
|
||||
</script>
|
59
src/components/back/layout/HeaderVue.vue
Normal file
59
src/components/back/layout/HeaderVue.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<a-row>
|
||||
<a-col flex="100px">
|
||||
<span style="font-size: 24px; font-weight: bold">Libroro</span>
|
||||
</a-col>
|
||||
<a-col flex="auto" style="text-align: right">
|
||||
{{ userName }}
|
||||
<a-button style="margin-left: 1em;" @click="handleLogout" danger type="primary">退出登录</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useStore } from 'vuex';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { computed, onMounted } from 'vue';
|
||||
|
||||
const store = useStore();
|
||||
const router = useRouter();
|
||||
|
||||
// 获取用户信息
|
||||
const userInfo = computed(() => store.state.user.info);
|
||||
|
||||
// 初始化检查登录状态
|
||||
onMounted(async () => {
|
||||
try {
|
||||
// 调用初始化方法(根据你的 Vuex 模块结构调整 action 路径)
|
||||
await store.dispatch('user/initialize');
|
||||
|
||||
// 检查用户信息是否存在
|
||||
if (!userInfo.value) {
|
||||
await router.push('/auth');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('初始化失败:', error);
|
||||
await router.push('/auth');
|
||||
}
|
||||
});
|
||||
|
||||
// 安全获取用户名的计算属性
|
||||
const userName = computed(() => userInfo.value?.name || '');
|
||||
|
||||
// 退出登录处理函数
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
await store.dispatch('user/logout');
|
||||
await router.push('/auth');
|
||||
} catch (error) {
|
||||
console.error('退出登录失败:', error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 可以在这里添加一些样式 */
|
||||
a-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
@ -4,6 +4,8 @@ import router from "./router/index.js";
|
||||
import Antd from 'ant-design-vue';
|
||||
import App from './App.vue'
|
||||
import 'ant-design-vue/dist/reset.css';
|
||||
import store from "@/store/index.js";
|
||||
let app = createApp(App)
|
||||
app.use(store)
|
||||
app.use(router).use(Antd).mount('#app')
|
||||
|
||||
|
@ -14,7 +14,13 @@ const isAdmin = computed(() => store.state.user.info?.isAdmin || false)
|
||||
onMounted(async () => {
|
||||
await store.dispatch('user/initialize')
|
||||
})
|
||||
|
||||
// 跳转后台
|
||||
const goToBackend = () => {
|
||||
console.log("go to backend")
|
||||
router.push({
|
||||
path: '/back',
|
||||
})
|
||||
}
|
||||
const logout = () => {
|
||||
// 调用 Vuex action
|
||||
store.dispatch('user/logout')
|
||||
@ -98,7 +104,7 @@ const handleBorrow = (book) => {
|
||||
|
||||
|
||||
<p style="text-align: center;">
|
||||
<span class="inline-btn"><a-button type="primary">进入后台</a-button></span>
|
||||
<span class="inline-btn"><a-button @click="goToBackend()" type="primary">进入后台</a-button></span>
|
||||
<span class="inline-btn"><a-button type="primary" danger @click="logout()">退出登录</a-button></span>
|
||||
</p>
|
||||
</a-card>
|
||||
|
5
src/pages/back/BackIndex.vue
Normal file
5
src/pages/back/BackIndex.vue
Normal file
@ -0,0 +1,5 @@
|
||||
<template>
|
||||
|
||||
</template>
|
||||
<script setup>
|
||||
</script>
|
0
src/pages/back/BackUser.vue
Normal file
0
src/pages/back/BackUser.vue
Normal file
333
src/pages/back/BookVueAdmin.vue
Normal file
333
src/pages/back/BookVueAdmin.vue
Normal file
@ -0,0 +1,333 @@
|
||||
<template>
|
||||
<div class="book-management">
|
||||
<div style="width: 100%;height: 10%;text-align: left">
|
||||
<a-button type="primary" @click="openAdd">
|
||||
添加图书
|
||||
</a-button>
|
||||
</div>
|
||||
<div style="height: 80%;">
|
||||
<a-table
|
||||
:data-source="dataSource"
|
||||
:columns="columns"
|
||||
:pagination="pagination"
|
||||
:loading="loading"
|
||||
:scroll="{ x: '100%' }"
|
||||
@change="handleTableChange"
|
||||
bordered
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-button type="link" @click="openEdit(record)">编辑</a-button>
|
||||
<a-popconfirm
|
||||
title="确定要删除这本图书吗?"
|
||||
@confirm="handleDelete(record.id)"
|
||||
>
|
||||
<a-button type="link" danger>删除</a-button>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<a-modal
|
||||
v-model:open="visible"
|
||||
:title="isEdit ? '编辑图书' : '添加图书'"
|
||||
@ok="handleSubmit"
|
||||
:confirm-loading="confirmLoading"
|
||||
>
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="formState"
|
||||
:rules="rules"
|
||||
layout="vertical"
|
||||
>
|
||||
<a-form-item label="图书名称" name="name">
|
||||
<a-input v-model:value="formState.name"/>
|
||||
</a-form-item>
|
||||
<a-form-item label="作者" name="author">
|
||||
<a-input v-model:value="formState.author"/>
|
||||
</a-form-item>
|
||||
<a-form-item label="出版日期" name="publishDate">
|
||||
<a-date-picker
|
||||
v-model:value="formState.publishDate"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="简介" name="description">
|
||||
<a-textarea v-model:value="formState.description"/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {reactive, ref, onMounted} from 'vue';
|
||||
import {message} from 'ant-design-vue';
|
||||
import {
|
||||
getBooks,
|
||||
addBook,
|
||||
updateBook,
|
||||
deleteBook
|
||||
} from '@/apis/apis_book.js';
|
||||
|
||||
// 表格数据
|
||||
const dataSource = ref([]);
|
||||
const loading = ref(false);
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
// 表单相关
|
||||
const visible = ref(false);
|
||||
const isEdit = ref(false);
|
||||
const confirmLoading = ref(false);
|
||||
const formRef = ref();
|
||||
const formState = reactive({
|
||||
id: undefined,
|
||||
name: '',
|
||||
author: '',
|
||||
publishDate: null,
|
||||
description: '',
|
||||
});
|
||||
const columns = reactive([
|
||||
{
|
||||
title: '图书名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
sorter: (a, b) => a.name.localeCompare(b.name), // 支持按图书名称排序
|
||||
ellipsis: true, // 超长文本省略显示
|
||||
width: 200, // 设置列宽
|
||||
},
|
||||
{
|
||||
title: '作者',
|
||||
dataIndex: 'author',
|
||||
key: 'author',
|
||||
sorter: (a, b) => a.author.localeCompare(b.author), // 支持按作者排序
|
||||
ellipsis: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '国际标准书号(ISBN)',
|
||||
dataIndex: 'isbn',
|
||||
key: 'isbn',
|
||||
ellipsis: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '内部图书编码',
|
||||
dataIndex: 'code',
|
||||
key: 'code',
|
||||
ellipsis: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '出版社',
|
||||
dataIndex: 'publisher',
|
||||
key: 'publisher',
|
||||
sorter: (a, b) => a.publisher.localeCompare(b.publisher), // 支持按出版社排序
|
||||
ellipsis: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '出版日期',
|
||||
dataIndex: 'publication_date',
|
||||
key: 'publication_date',
|
||||
sorter: (a, b) => new Date(a.publication_date) - new Date(b.publication_date), // 支持按出版日期排序
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '版次',
|
||||
dataIndex: 'edition',
|
||||
key: 'edition',
|
||||
sorter: (a, b) => a.edition - b.edition, // 支持按版次排序
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '定价(元)',
|
||||
dataIndex: 'price',
|
||||
key: 'price',
|
||||
sorter: (a, b) => a.price - b.price, // 支持按定价排序
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '分类',
|
||||
dataIndex: 'category',
|
||||
key: 'category',
|
||||
sorter: (a, b) => a.category.localeCompare(b.category), // 支持按分类排序
|
||||
filters: [
|
||||
// 可以根据实际数据动态生成筛选选项
|
||||
{text: 'I247.5/悬疑小说', value: 'I247.5/悬疑小说'},
|
||||
],
|
||||
onFilter: (value, record) => record.category.includes(value),
|
||||
ellipsis: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '总数量',
|
||||
dataIndex: 'num',
|
||||
key: 'num',
|
||||
sorter: (a, b) => a.num - b.num, // 支持按总数量排序
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '库存量',
|
||||
dataIndex: 'stock',
|
||||
key: 'stock',
|
||||
sorter: (a, b) => a.stock - b.stock, // 支持按库存量排序
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '是否绝版',
|
||||
dataIndex: 'is_out_of_print',
|
||||
key: 'is_out_of_print',
|
||||
render: (text) => (text === 1 ? '是' : '否'),
|
||||
sorter: (a, b) => a.is_out_of_print - b.is_out_of_print, // 支持按是否绝版排序
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'create_time',
|
||||
key: 'create_time',
|
||||
sorter: (a, b) => new Date(a.create_time) - new Date(b.create_time), // 支持按创建时间排序
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '最后更新时间',
|
||||
dataIndex: 'update_time',
|
||||
key: 'update_time',
|
||||
sorter: (a, b) => new Date(a.update_time) - new Date(b.update_time), // 支持按最后更新时间排序
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
// render: (_, record) => (
|
||||
// // 这里可以添加具体的操作按钮,如编辑、删除等
|
||||
// <div>
|
||||
// <a-button type="primary" size="small">编辑</a-button>
|
||||
// <a-button type="danger" size="small" style="margin-left: 8px">删除</a-button>
|
||||
// </div>
|
||||
// ),
|
||||
},
|
||||
]);
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
name: [
|
||||
{required: true, message: '请输入图书名称', trigger: 'blur'},
|
||||
],
|
||||
author: [
|
||||
{required: true, message: '请输入作者姓名', trigger: 'blur'},
|
||||
],
|
||||
});
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
fetchData();
|
||||
});
|
||||
|
||||
// 获取数据
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await getBooks({
|
||||
page: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
});
|
||||
console.log(res);
|
||||
|
||||
dataSource.value = res.data.list;
|
||||
pagination.total = res.data.total;
|
||||
} catch (error) {
|
||||
message.error('获取数据失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 分页变化处理
|
||||
const handleTableChange = (pag) => {
|
||||
pagination.current = pag.current;
|
||||
pagination.pageSize = pag.pageSize;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 打开添加模态框
|
||||
const openAdd = () => {
|
||||
isEdit.value = false;
|
||||
resetForm();
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑模态框
|
||||
const openEdit = (record) => {
|
||||
isEdit.value = true;
|
||||
Object.assign(formState, record);
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
await formRef.value.validate();
|
||||
confirmLoading.value = true;
|
||||
|
||||
if (isEdit.value) {
|
||||
await updateBook(formState.id, formState);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addBook(formState);
|
||||
message.success('添加成功');
|
||||
}
|
||||
|
||||
visible.value = false;
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
console.error('提交失败:', error);
|
||||
message.error('操作失败');
|
||||
} finally {
|
||||
confirmLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 删除处理
|
||||
const handleDelete = async (id) => {
|
||||
try {
|
||||
await deleteBook(id);
|
||||
message.success('删除成功');
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
message.error('删除失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
formRef.value?.resetFields();
|
||||
Object.assign(formState, {
|
||||
id: undefined,
|
||||
name: '',
|
||||
author: '',
|
||||
publishDate: null,
|
||||
description: '',
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.book-management {
|
||||
padding: 1em;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.ant-form-item {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
@ -20,7 +20,17 @@ const routes = [
|
||||
path: '/auth',
|
||||
name: 'AuthView',
|
||||
component: () => import('../views/AuthView.vue'),
|
||||
}
|
||||
},
|
||||
{
|
||||
name:'BackView',
|
||||
path:'/back',
|
||||
component:()=>import('../views/BackView.vue'),
|
||||
redirect:'/back/index',
|
||||
children:[
|
||||
{name:'BackIndex',path:'/back/index',component:()=>import('../pages/back/BackIndex.vue')},
|
||||
{name:'BackUser',path:'user',component:()=>import('../pages/back/BackUser.vue')},
|
||||
{name:'BackBookAdmin',path:'/back/admin/book',component:()=>import('../pages/back/BookVueAdmin.vue')},
|
||||
]},
|
||||
];
|
||||
|
||||
// 创建路由实例
|
||||
|
@ -1,6 +1,17 @@
|
||||
import service from '@/apis/axios';
|
||||
import axios from 'axios';
|
||||
import {auth_logout} from "@/apis/apis_auth.js";
|
||||
// 清除会话的辅助函数
|
||||
const clearSession = (state, commit) => {
|
||||
state.info = null;
|
||||
state.lastLogin = null;
|
||||
localStorage.removeItem('userInfo');
|
||||
if (state.refreshTimer) {
|
||||
clearTimeout(state.refreshTimer);
|
||||
state.refreshTimer = null;
|
||||
}
|
||||
commit('CLEAR_SESSION');
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
@ -18,13 +29,14 @@ export default {
|
||||
state.lastLogin = new Date().toISOString();
|
||||
},
|
||||
CLEAR_SESSION(state) {
|
||||
state.info = null;
|
||||
state.lastLogin = null;
|
||||
localStorage.removeItem('userInfo');
|
||||
if (state.refreshTimer) {
|
||||
clearTimeout(state.refreshTimer);
|
||||
state.refreshTimer = null;
|
||||
}
|
||||
// state.info = null;
|
||||
// state.lastLogin = null;
|
||||
// localStorage.removeItem('userInfo');
|
||||
// if (state.refreshTimer) {
|
||||
// clearTimeout(state.refreshTimer);
|
||||
// state.refreshTimer = null;
|
||||
// }
|
||||
clearSession(state, () => {});
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
@ -44,8 +56,9 @@ export default {
|
||||
}
|
||||
},
|
||||
CLEAR_SESSION({ commit }) {
|
||||
commit('CLEAR_SESSION');
|
||||
localStorage.removeItem('userInfo');
|
||||
// commit('CLEAR_SESSION');
|
||||
// localStorage.removeItem('userInfo');
|
||||
clearSession(this.state, commit);
|
||||
},
|
||||
async logout({commit}) {
|
||||
//向后端发起退出登录的请求
|
||||
|
@ -1,11 +1,49 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<a-layout>
|
||||
<a-layout-header class="layout-header"><header-vue/></a-layout-header>
|
||||
<a-layout>
|
||||
<a-layout-sider class="layout-sider"><aside-vue/></a-layout-sider>
|
||||
<a-layout-content class="layout-content"><router-view></router-view></a-layout-content>
|
||||
</a-layout>
|
||||
<a-layout-footer class="layout-footer"></a-layout-footer>
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<script setup>
|
||||
|
||||
import HeaderVue from "@/components/back/layout/HeaderVue.vue";
|
||||
import AsideVue from "@/components/back/layout/AsideVue.vue";
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.layout-header {
|
||||
text-align: left;
|
||||
color: #fff;
|
||||
height: 64px;
|
||||
padding-inline: 50px;
|
||||
line-height: 64px;
|
||||
background-color: #87b9ff;
|
||||
}
|
||||
|
||||
.layout-content {
|
||||
text-align: center;
|
||||
min-height: 120px;
|
||||
line-height: 120px;
|
||||
color: #fff;
|
||||
background-color: rgb(243, 255, 249);
|
||||
}
|
||||
|
||||
.layout-sider {
|
||||
text-align: center;
|
||||
width: 256px;
|
||||
line-height: 120px;
|
||||
color: #fff;
|
||||
background-color: rgba(95, 183, 255, 0.54);
|
||||
}
|
||||
|
||||
.layout-footer {
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background-color: #87b9ff;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
x
Reference in New Issue
Block a user