mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-22 05:02:57 +00:00
1、后端优化多环境动态管理:python3 main.py run --env=dev(dev、test、prod,可以不加--env,默认dev)
2、前端加入切换主题功能(布局页面头部背景未生效,待优化)
This commit is contained in:
+27
-2
@@ -2,8 +2,9 @@
|
||||
<ConfigProvider
|
||||
:locale="zhCN"
|
||||
:theme="{
|
||||
algorithm: theme.defaultAlgorithm,
|
||||
}">
|
||||
algorithm: isDarkMode ? theme.darkAlgorithm : theme.defaultAlgorithm,
|
||||
}"
|
||||
>
|
||||
<div id="app">
|
||||
<router-view />
|
||||
</div>
|
||||
@@ -15,10 +16,34 @@ import { ConfigProvider, theme } from 'ant-design-vue'
|
||||
import zhCN from 'ant-design-vue/es/locale/zh_CN'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/zh-cn'
|
||||
import { ref, provide } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
dayjs.locale('zh-cn')
|
||||
|
||||
// 主题状态
|
||||
const isDarkMode = ref(localStorage.getItem('theme') === 'dark')
|
||||
|
||||
// 提供主题状态和切换方法给所有子组件
|
||||
provide('isDarkMode', isDarkMode)
|
||||
|
||||
// 全局切换主题方法
|
||||
const toggleTheme = (darkMode: boolean) => {
|
||||
isDarkMode.value = darkMode
|
||||
if (darkMode) {
|
||||
document.documentElement.classList.add('dark')
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark')
|
||||
}
|
||||
}
|
||||
|
||||
provide('toggleTheme', toggleTheme)
|
||||
|
||||
// 初始化主题
|
||||
if (isDarkMode.value) {
|
||||
document.documentElement.classList.add('dark')
|
||||
}
|
||||
|
||||
// 禁用Promise reject输出控制台
|
||||
window.addEventListener('unhandledrejection', function browserRejectionHandler(event) {
|
||||
event && event.preventDefault()
|
||||
|
||||
@@ -1,90 +1,98 @@
|
||||
<template>
|
||||
<a-layout class="basic-layout">
|
||||
<!-- 顶部导航栏 -->
|
||||
<a-layout-header class="header">
|
||||
<div class="header-content">
|
||||
<!-- 左侧 Logo -->
|
||||
<div class="header-left">
|
||||
<a-button type="link" class="logo-btn">
|
||||
<a-image src="/logo.png" :preview="false" :width="28" :height="28" />
|
||||
<h1 class="logo-title">fastapi-vue-admin</h1>
|
||||
</a-button>
|
||||
<a-button
|
||||
type="link"
|
||||
class="collapse-btn"
|
||||
@click="toggleCollapsed"
|
||||
>
|
||||
<MenuFoldOutlined v-if="menuState.collapsed" />
|
||||
<MenuUnfoldOutlined v-else />
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<!-- 右侧工具栏 -->
|
||||
<div class="header-right">
|
||||
<!-- 文档按钮 -->
|
||||
<a-tooltip title="说明文档" placement="bottom">
|
||||
<a-button type="link" @click="openDocumentation" class="tool-btn">
|
||||
<QuestionCircleOutlined />
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
|
||||
<!-- 通知按钮 -->
|
||||
<a-badge :count="unreadCount" :dot="unreadCount > 99">
|
||||
<a-button type="link" @click="openNotification" class="tool-btn">
|
||||
<BellOutlined />
|
||||
</a-button>
|
||||
</a-badge>
|
||||
|
||||
<!-- 用户信息下拉菜单 -->
|
||||
<a-dropdown>
|
||||
<div class="user-dropdown">
|
||||
<a-avatar :src="userAvatar" :size="32" />
|
||||
<span class="username">{{ username }}</span>
|
||||
<DownOutlined />
|
||||
</div>
|
||||
<template #overlay>
|
||||
<a-menu @click="handleUserMenuClick">
|
||||
<a-menu-item key="profile">
|
||||
<template #icon><UserOutlined /></template>
|
||||
个人中心
|
||||
</a-menu-item>
|
||||
<a-menu-divider />
|
||||
<a-menu-item key="logout">
|
||||
<template #icon><LogoutOutlined /></template>
|
||||
退出登录
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
<!-- 左侧导航 -->
|
||||
<a-layout-sider class="layout-sider"
|
||||
:collapsed="menuState.collapsed"
|
||||
theme="light"
|
||||
:trigger="null"
|
||||
collapsible
|
||||
:width="240"
|
||||
:collapsedWidth="80"
|
||||
>
|
||||
<!-- Logo 区域 -->
|
||||
<div class="logo-container">
|
||||
<a-image src="/logo.png" :preview="false" :width="28" :height="28" />
|
||||
<h1 class="logo-title" v-show="!menuState.collapsed">fastapi-vue-admin</h1>
|
||||
</div>
|
||||
</a-layout-header>
|
||||
|
||||
<a-layout class="main-container">
|
||||
<!-- 侧边栏 -->
|
||||
<a-layout-sider
|
||||
class="sider"
|
||||
:collapsed="menuState.collapsed"
|
||||
:trigger="null"
|
||||
collapsible
|
||||
:width="240"
|
||||
:collapsedWidth="80"
|
||||
>
|
||||
<a-menu
|
||||
class="side-menu"
|
||||
mode="inline"
|
||||
theme="light"
|
||||
v-model:openKeys="menuState.openKeys"
|
||||
v-model:selectedKeys="menuState.selectedKeys"
|
||||
:items="menuState.menus"
|
||||
@click="handleMenuClick"
|
||||
/>
|
||||
</a-layout-sider>
|
||||
|
||||
<a-menu
|
||||
class="side-menu"
|
||||
mode="inline"
|
||||
theme="light"
|
||||
v-model:openKeys="menuState.openKeys"
|
||||
v-model:selectedKeys="menuState.selectedKeys"
|
||||
:items="menuState.menus"
|
||||
@click="handleMenuClick"
|
||||
/>
|
||||
</a-layout-sider>
|
||||
|
||||
<!-- 右侧布局 -->
|
||||
<a-layout class="layout-main" :class="{ collapsed: menuState.collapsed }">
|
||||
<!-- 顶部导航栏 -->
|
||||
<a-layout-header class="layout-header" >
|
||||
|
||||
<div class="header-left" >
|
||||
<!-- 左侧折叠按钮 -->
|
||||
<a-button
|
||||
type="link"
|
||||
class="collapse-btn"
|
||||
@click="toggleCollapsed"
|
||||
>
|
||||
<MenuFoldOutlined v-if="menuState.collapsed" />
|
||||
<MenuUnfoldOutlined v-else />
|
||||
</a-button>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 右侧工具栏 -->
|
||||
<div class="header-right">
|
||||
<!-- 主题切换按钮 -->
|
||||
<a-tooltip :title="isDarkMode ? '切换亮色主题' : '切换暗色主题'" placement="bottom">
|
||||
<a-button type="link" @click="handleThemeChange" class="tool-btn">
|
||||
<component :is="isDarkMode ? BulbFilled : BulbOutlined" />
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
|
||||
<!-- 文档按钮 -->
|
||||
<a-tooltip title="说明文档" placement="bottom">
|
||||
<a-button type="link" @click="openDocumentation" class="tool-btn">
|
||||
<QuestionCircleOutlined />
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
|
||||
<!-- 通知按钮 -->
|
||||
<a-badge :count="unreadCount" :dot="unreadCount > 99">
|
||||
<a-button type="link" @click="openNotification" class="tool-btn">
|
||||
<BellOutlined />
|
||||
</a-button>
|
||||
</a-badge>
|
||||
|
||||
<!-- 用户信息下拉菜单 -->
|
||||
<a-dropdown>
|
||||
<div class="user-dropdown">
|
||||
<a-avatar :src="userAvatar" :size="32" />
|
||||
<span class="username">{{ username }}</span>
|
||||
<DownOutlined />
|
||||
</div>
|
||||
<template #overlay>
|
||||
<a-menu @click="handleUserMenuClick">
|
||||
<a-menu-item key="profile">
|
||||
<template #icon><UserOutlined /></template>
|
||||
个人中心
|
||||
</a-menu-item>
|
||||
<a-menu-divider />
|
||||
<a-menu-item key="logout">
|
||||
<template #icon><LogoutOutlined /></template>
|
||||
退出登录
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
</a-layout-header>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<a-layout-content class="content"
|
||||
:class="{ collapsed: menuState.collapsed }"
|
||||
>
|
||||
<a-layout-content class="layout-content">
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<transition name="fade" mode="out-in">
|
||||
<div :key="route.path">
|
||||
@@ -101,7 +109,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, computed, watch, onMounted } from "vue";
|
||||
import { reactive, computed, watch, onMounted, inject, type Ref } from "vue";
|
||||
import type { MenuProps, ItemType } from "ant-design-vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import storage from 'store';
|
||||
@@ -117,7 +125,9 @@ import {
|
||||
LogoutOutlined,
|
||||
DownOutlined,
|
||||
MenuFoldOutlined,
|
||||
MenuUnfoldOutlined
|
||||
MenuUnfoldOutlined,
|
||||
BulbOutlined,
|
||||
BulbFilled
|
||||
} from '@ant-design/icons-vue';
|
||||
|
||||
// 路由相关
|
||||
@@ -249,6 +259,16 @@ const openNotification = () => {
|
||||
console.log('打开通知面板');
|
||||
};
|
||||
|
||||
// 主题相关
|
||||
const isDarkMode = inject('isDarkMode') as Ref<boolean>
|
||||
const toggleTheme = inject('toggleTheme') as (darkMode: boolean) => void
|
||||
|
||||
// 切换主题
|
||||
const handleThemeChange = () => {
|
||||
toggleTheme(!isDarkMode.value)
|
||||
localStorage.setItem('theme', isDarkMode.value ? 'dark' : 'light')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initMenu();
|
||||
});
|
||||
@@ -257,41 +277,86 @@ onMounted(() => {
|
||||
<style lang="scss" scoped>
|
||||
.basic-layout {
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
|
||||
:deep(.ant-layout-header) {
|
||||
background: #fff;
|
||||
padding: 0;
|
||||
height: var(--header-height);
|
||||
line-height: var(--header-height);
|
||||
}
|
||||
display: flex;
|
||||
|
||||
.header {
|
||||
|
||||
.header-content {
|
||||
height: 60px;
|
||||
.layout-sider {
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 99;
|
||||
|
||||
.logo-container {
|
||||
height: 64px;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
|
||||
.logo-title {
|
||||
margin: 0 0 0 12px;
|
||||
color: var(--text-color);
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.side-menu {
|
||||
height: calc(100vh - 64px);
|
||||
border-right: 0;
|
||||
padding: 16px 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
:deep(.ant-menu-item) {
|
||||
margin: 4px 8px;
|
||||
padding: 0 16px;
|
||||
border-radius: 4px;
|
||||
|
||||
&.ant-menu-item-selected {
|
||||
background: rgba(24, 144, 255, 0.1);
|
||||
color: var(--primary-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layout-main {
|
||||
margin-left: 240px;
|
||||
transition: all 0.3s;
|
||||
width: calc(100% - 240px);
|
||||
|
||||
&.collapsed {
|
||||
margin-left: 80px;
|
||||
width: calc(100% - 80px);
|
||||
}
|
||||
|
||||
.layout-header {
|
||||
background: var(--component-background);
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.logo-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
|
||||
.collapse-btn {
|
||||
padding: 0 6px;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
|
||||
.logo-title {
|
||||
margin: 0 0 0 12px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
white-space: nowrap;
|
||||
&:hover {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -315,77 +380,19 @@ onMounted(() => {
|
||||
|
||||
.username {
|
||||
margin: 0 8px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
color: var(--text-color);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main-container {
|
||||
margin-top: var(--header-height);
|
||||
// height: calc(100vh - var(--header-height));
|
||||
height: 90px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.sider {
|
||||
box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
|
||||
background: #fff;
|
||||
|
||||
.side-menu {
|
||||
height: 100%;
|
||||
border-right: 0;
|
||||
padding: 16px 0;
|
||||
|
||||
:deep(.ant-menu-item) {
|
||||
margin: 4px 8px;
|
||||
padding: 0 16px;
|
||||
border-radius: 4px;
|
||||
|
||||
&.ant-menu-item-selected {
|
||||
background: rgba(24, 144, 255, 0.1);
|
||||
color: var(--primary-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout-header {
|
||||
padding-inline: 0;
|
||||
}
|
||||
|
||||
.ant-layout-header {
|
||||
padding-inline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout-sider-children .ant-menu-light {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
|
||||
.ant-layout-sider-children .ant-menu-light {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
background: var(--background-color);
|
||||
overflow-y: auto; /* 确保垂直滚动条在需要时出现 */
|
||||
.layout-content {
|
||||
padding: 24px;
|
||||
min-height: calc(100vh - var(--header-height));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 过渡动画
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
+1
-184
@@ -17,7 +17,7 @@
|
||||
--text-color-secondary: rgba(0, 0, 0, 0.45);
|
||||
--border-color: #f0f0f0;
|
||||
--background-color: #f0f2f5;
|
||||
--component-background: #fff;
|
||||
--component-background: #ffffff;
|
||||
--box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
--box-shadow-light: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
@@ -71,186 +71,3 @@ button {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
/* 布局相关的全局样式 */
|
||||
.basic-layout {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
height: var(--header-height);
|
||||
background: #fff;
|
||||
box-shadow: var(--box-shadow-light);
|
||||
}
|
||||
|
||||
.header-content {
|
||||
height: 100%;
|
||||
padding: 0 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.logo-btn {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
padding: 0 8px !important;
|
||||
color: var(--text-color) !important;
|
||||
}
|
||||
|
||||
.logo-title {
|
||||
margin: 0 0 0 12px !important;
|
||||
color: var(--text-color) !important;
|
||||
font-weight: 600 !important;
|
||||
font-size: 18px !important;
|
||||
line-height: 1.5 !important;
|
||||
}
|
||||
|
||||
.collapse-btn {
|
||||
padding: 0 12px !important;
|
||||
font-size: 16px !important;
|
||||
color: var(--text-color) !important;
|
||||
}
|
||||
|
||||
.collapse-btn:hover {
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.tool-btn {
|
||||
padding: 0 12px !important;
|
||||
font-size: 16px !important;
|
||||
color: var(--text-color) !important;
|
||||
}
|
||||
|
||||
.tool-btn:hover {
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.username {
|
||||
margin: 0 8px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
color: var(--text-color-secondary);
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: var(--card-padding);
|
||||
background-color: var(--color-background-card);
|
||||
border-radius: var(--card-border-radius);
|
||||
box-shadow: var(--card-shadow);
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: var(--app-max-width);
|
||||
margin: 0 auto;
|
||||
padding: var(--app-padding);
|
||||
text-align: var(--app-text-align);
|
||||
}
|
||||
|
||||
/* Ant Design Layout 样式覆盖 */
|
||||
.ant-layout-header {
|
||||
background: #fff !important;
|
||||
padding: 0 !important;
|
||||
height: var(--header-height) !important;
|
||||
line-height: var(--header-height) !important;
|
||||
}
|
||||
|
||||
/* Ant Design 按钮样式覆盖 */
|
||||
.ant-btn-link {
|
||||
color: var(--text-color) !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.ant-btn-link:hover {
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
|
||||
/* Ant Design 下拉菜单样式 */
|
||||
.ant-dropdown-menu {
|
||||
padding: 4px 0 !important;
|
||||
}
|
||||
|
||||
.ant-dropdown-menu-item {
|
||||
padding: 8px 16px !important;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
color: #213547;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.4em;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 1.5em;
|
||||
}
|
||||
|
||||
.left-header {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.right-header {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.logo-btn {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.doc-button {
|
||||
padding: 8px 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
@@ -477,7 +477,6 @@ onMounted(() => {
|
||||
<style lang="scss" scoped>
|
||||
.profile-container {
|
||||
min-height: 90vh;
|
||||
background-color: #e5e9ee;
|
||||
|
||||
.profile-content {
|
||||
padding: 24px;
|
||||
@@ -515,7 +514,6 @@ onMounted(() => {
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
opacity: 0;
|
||||
transition: opacity var(--transition-duration);
|
||||
}
|
||||
@@ -573,7 +571,6 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.user-role {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
@@ -585,7 +582,6 @@ onMounted(() => {
|
||||
.detail-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
white-space: nowrap;
|
||||
|
||||
.anticon {
|
||||
@@ -596,7 +592,6 @@ onMounted(() => {
|
||||
|
||||
.ant-descriptions-item-content {
|
||||
display: inline-block;
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
}
|
||||
|
||||
.ant-descriptions-item-colon {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<a-card :bodyStyle="{ padding: '20px 24px 8px' }">
|
||||
<a-skeleton :loading="loading">
|
||||
<div>
|
||||
<span style="color: rgba(0, 0, 0, 0.65)">总销售额</span>
|
||||
<span>总销售额</span>
|
||||
<div style="float: right;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
<InfoCircleOutlined />
|
||||
@@ -48,7 +48,7 @@
|
||||
<a-card :bodyStyle="{ padding: '20px 24px 8px' }">
|
||||
<a-skeleton :loading="loading">
|
||||
<div>
|
||||
<span style="color: rgba(0, 0, 0, 0.65)">访问量</span>
|
||||
<span>访问量</span>
|
||||
<div style="float: right;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
<InfoCircleOutlined />
|
||||
@@ -74,7 +74,7 @@
|
||||
<a-card :bodyStyle="{ padding: '20px 24px 8px' }">
|
||||
<a-skeleton :loading="loading">
|
||||
<div>
|
||||
<span style="color: rgba(0, 0, 0, 0.65)">支付笔数</span>
|
||||
<span>支付笔数</span>
|
||||
<div style="float: right;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
<InfoCircleOutlined />
|
||||
@@ -100,7 +100,7 @@
|
||||
<a-card :bodyStyle="{ padding: '20px 24px 8px' }">
|
||||
<a-skeleton :loading="loading">
|
||||
<div>
|
||||
<span style="color: rgba(0, 0, 0, 0.65)">运营活动效果</span>
|
||||
<span>运营活动效果</span>
|
||||
<div style="float: right;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
<InfoCircleOutlined />
|
||||
@@ -210,7 +210,7 @@
|
||||
|
||||
<a-row :gutter="68">
|
||||
<a-col :sm="12" :xs="24">
|
||||
<div style="color: rgba(0, 0, 0, 0.65);">
|
||||
<div>
|
||||
<span>搜索用户数</span>
|
||||
<span style="margin-left: 8px;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
@@ -223,7 +223,7 @@
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :sm="12" :xs="24">
|
||||
<div style="color: rgba(0, 0, 0, 0.65);">
|
||||
<div>
|
||||
<span>人均搜索次数</span>
|
||||
<span style="margin-left: 8px;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
@@ -595,7 +595,6 @@ setTimeout(() => {
|
||||
.value {
|
||||
height: 38px;
|
||||
padding-top: 4px;
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
font-size: 30px;
|
||||
line-height: 38px;
|
||||
word-break: break-all;
|
||||
@@ -616,7 +615,6 @@ setTimeout(() => {
|
||||
|
||||
a {
|
||||
margin-right: 25px;
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
@@ -628,7 +626,6 @@ setTimeout(() => {
|
||||
padding: 0 32px 32px 72px;
|
||||
|
||||
h4 {
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
@@ -639,7 +636,7 @@ setTimeout(() => {
|
||||
|
||||
ul li span {
|
||||
&:first-child {
|
||||
background-color: #f5f5f5;
|
||||
background-color: var(--background-color);
|
||||
border-radius: 20px;
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
@@ -649,6 +646,7 @@ setTimeout(() => {
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
color: var( --text-color);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
@@ -656,8 +654,8 @@ setTimeout(() => {
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #314659;
|
||||
color: #fff;
|
||||
background-color: var(--background-color);
|
||||
color: var(--text-colorr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
</a-col>
|
||||
<a-col class="content" style="margin-left: 20px;">
|
||||
<div class="content-title"
|
||||
style="font-size: 20px; font-weight: 500; color: rgba(0, 0, 0, 0.88); margin-bottom: 12px;">
|
||||
style="font-size: 20px; font-weight: 500; margin-bottom: 12px;">
|
||||
{{ timefix }},{{ userInfo.name }}<span class="welcome-text">,{{ welcome }}</span>
|
||||
</div>
|
||||
<div style="color: rgba(0, 0, 0, 0.65);">{{userInfo.positions[0].name}} | {{userInfo.dept_name}}</div>
|
||||
<div>{{userInfo.positions[0].name}} | {{userInfo.dept_name}}</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="extra-content" justify="space-around">
|
||||
@@ -38,14 +38,14 @@
|
||||
<a-card-meta>
|
||||
<template #title>
|
||||
<a-avatar :size="30" :src="item.avatar" />
|
||||
<a class="a-hover" style="margin-left: 10px; color: rgba(0, 0, 0, 0.88);">{{ item.title }}</a>
|
||||
<a class="a-hover" style="margin-left: 10px; ">{{ item.title }}</a>
|
||||
</template>
|
||||
<template #description>
|
||||
<div style="min-height: 45px;">{{ item.description }}</div>
|
||||
</template>
|
||||
</a-card-meta>
|
||||
<div class="project-item">
|
||||
<a class="a-hover" style="color: rgba(0, 0, 0, 0.65)">{{ item.author }}</a>
|
||||
<a class="a-hover" >{{ item.author }}</a>
|
||||
<span class="item-datetime">{{ item.datetime }}</span>
|
||||
</div>
|
||||
</a-skeleton>
|
||||
@@ -252,7 +252,6 @@ setTimeout(() => {
|
||||
right: 0;
|
||||
width: 1px;
|
||||
height: 45px;
|
||||
background-color: rgba(5, 5, 5, 0.06);
|
||||
content: '';
|
||||
}
|
||||
|
||||
@@ -269,7 +268,6 @@ setTimeout(() => {
|
||||
|
||||
.item-datetime {
|
||||
float: right;
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.a-hover:hover {
|
||||
@@ -278,7 +276,6 @@ setTimeout(() => {
|
||||
|
||||
:deep(.ant-list-item-meta-content) {
|
||||
h4 {
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
@@ -298,7 +295,6 @@ setTimeout(() => {
|
||||
|
||||
.member {
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
line-height: 24px;
|
||||
max-width: 100px;
|
||||
vertical-align: top;
|
||||
|
||||
@@ -68,18 +68,13 @@
|
||||
:style="{ minHeight: '500px' }"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'name'">
|
||||
<span :style="{ color: !record.available ? 'rgb(255, 77, 79)' : 'rgba(0, 0, 0, .88)' }">
|
||||
{{ record.name }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template v-else-if="column.dataIndex === 'available'">
|
||||
<template v-if="column.dataIndex === 'available'">
|
||||
<a-badge :status="record.available ? 'success' : 'error'" />
|
||||
{{ record.available ? '启用' : '停用' }}
|
||||
</template>
|
||||
|
||||
<template v-else-if="column.dataIndex === 'action'">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-space size="middle">
|
||||
<a @click="modalHandle('view', record)">查看</a>
|
||||
<a @click="modalHandle('update', record)">修改</a>
|
||||
|
||||
@@ -67,11 +67,6 @@
|
||||
:style="{ minHeight: '500px' }"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'name'">
|
||||
<span :style="{ color: !record.available ? 'rgb(255, 77, 79)' : 'rgba(0, 0, 0, .88)' }">
|
||||
{{ record.name }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'type'">
|
||||
<a-tag :color="record.type === 1 ? 'blue' : (record.type === 2 ? 'green' : 'orange')">
|
||||
{{ record.type === 1 ? '目录' : (record.type === 2 ? '功能' : '权限') }}
|
||||
|
||||
@@ -68,11 +68,6 @@
|
||||
<template v-if="column.dataIndex === 'index'">
|
||||
<span>{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'notice_title'">
|
||||
<span :style="{ color: !record.available ? 'rgb(255, 77, 79)' : 'rgba(0, 0, 0, .88)' }">
|
||||
{{ record.notice_title }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'notice_type'">
|
||||
<span :style="{ color: record.notice_type === 1 ? '#108ee9' : '#f8e231' }">
|
||||
{{ record.notice_type === 1 ? '通知' : '公告' }}
|
||||
|
||||
@@ -78,11 +78,6 @@
|
||||
<template v-if="column.dataIndex === 'index'">
|
||||
<span>{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'name'">
|
||||
<span :style="{ color: !record.available ? 'rgb(255, 77, 79)' : 'rgba(0, 0, 0, .88)' }">
|
||||
{{ record.name }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'available'">
|
||||
<span><a-badge :color="record.available ? 'green' : 'red'" /> {{ record.available ? '启用' : '禁用' }}
|
||||
</span>
|
||||
|
||||
@@ -76,11 +76,6 @@
|
||||
<template v-if="column.dataIndex === 'index'">
|
||||
<span>{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'name'">
|
||||
<span :style="{ color: !record.available ? 'rgb(255, 77, 79)' : 'rgba(0, 0, 0, .88)' }">
|
||||
{{ record.name }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'available'">
|
||||
<span><a-badge :color="record.available ? 'green' : 'red'" /> {{ record.available ? '启用' : '禁用' }}
|
||||
</span>
|
||||
|
||||
@@ -74,11 +74,6 @@
|
||||
<template v-if="column.dataIndex === 'index'">
|
||||
<span>{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'name'">
|
||||
<span :style="{ color: !record.available ? 'rgb(255, 77, 79)' : 'rgba(0, 0, 0, .88)' }">
|
||||
{{ record.name }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'dept'">
|
||||
<span>{{ record.dept_name }}</span>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user