From acd6bbae394c997523b5051d019e584db1845c4c Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期三, 17 六月 2026 14:29:04 +0800
Subject: [PATCH] 样式修改
---
src/layout/components/Navbar.vue | 844 +++++++++++++++++++++++++++++++++----------------------
1 files changed, 503 insertions(+), 341 deletions(-)
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index aae5330..15de4e1 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -1,81 +1,101 @@
<template>
<div class="navbar">
- <div class="left-zone">
- <hamburger
- id="hamburger-container"
- :is-active="appStore.sidebar.opened"
- class="hamburger-container"
- @toggleClick="toggleSideBar"
- />
- <breadcrumb
- v-if="!settingsStore.topNav"
- id="breadcrumb-container"
- class="breadcrumb-container"
- />
+ <div class="left-menu">
+ <hamburger id="hamburger-container"
+ :is-active="appStore.sidebar.opened"
+ class="hamburger-container"
+ @toggleClick="toggleSideBar" />
+ <breadcrumb v-if="!settingsStore.topNav"
+ id="breadcrumb-container"
+ class="breadcrumb-container" />
</div>
-
- <div class="center-zone">
- <el-icon class="search-icon" @click="openHeaderSearch"><Search /></el-icon>
- <el-input
- v-model="topSearchKeyword"
- placeholder="鎼滅储鑿滃崟 / 鍔熻兘 / 鏁版嵁"
- clearable
- @keyup.enter="openHeaderSearch"
- />
- <header-search
- ref="headerSearchRef"
- :keyword="topSearchKeyword"
- class="search-popup-trigger"
- />
- </div>
-
<div class="right-menu">
- <el-popover
- v-model:visible="notificationVisible"
- :width="500"
- placement="bottom-end"
- trigger="click"
- :popper-options="{ modifiers: [{ name: 'offset', options: { offset: [0, 10] } }] }"
- popper-class="notification-popover"
- >
- <template #reference>
- <div class="notification-container right-menu-item hover-effect">
- <el-badge :value="unreadCount" :hidden="unreadCount === 0" class="notification-badge">
- <el-icon :size="18">
- <Bell />
- </el-icon>
- </el-badge>
- </div>
- </template>
- <NotificationCenter @unreadCountChange="handleUnreadCountChange" ref="notificationCenterRef" />
- </el-popover>
-
- <div class="right-menu-item hover-effect screenfull-container">
- <screenfull />
+ <div class="search-wrapper">
+ <el-icon class="search-icon"
+ @click="openHeaderSearch">
+ <Search />
+ </el-icon>
+ <el-input v-model="topSearchKeyword"
+ placeholder="蹇�熸悳绱�..."
+ clearable
+ @keyup.enter="openHeaderSearch" />
+ <header-search ref="headerSearchRef"
+ :keyword="topSearchKeyword"
+ class="search-popup-trigger" />
</div>
-
- <div class="avatar-container">
- <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
- <div class="avatar-wrapper">
- <div class="user-summary">
- <div class="user-name">{{ userStore.nickName || userStore.name || "绠$悊鍛�" }}</div>
- <div class="user-role">{{ userStore.roleName || "绯荤粺鐢ㄦ埛" }}</div>
+ <div class="action-icons">
+ <el-popover v-model:visible="notificationVisible"
+ :width="500"
+ placement="bottom-end"
+ trigger="click"
+ :popper-options="{ modifiers: [{ name: 'offset', options: { offset: [0, 10] } }] }"
+ popper-class="notification-popover">
+ <template #reference>
+ <div class="notification-container right-menu-item hover-effect">
+ <el-badge :value="unreadCount"
+ :hidden="unreadCount === 0"
+ class="notification-badge">
+ <el-icon :size="18">
+ <Bell />
+ </el-icon>
+ </el-badge>
</div>
- <img :src="userStore.avatar" class="user-avatar" />
- <el-icon><caret-bottom /></el-icon>
+ </template>
+ <NotificationCenter @unreadCountChange="handleUnreadCountChange"
+ ref="notificationCenterRef" />
+ </el-popover>
+ <div class="right-menu-item hover-effect screenfull-container">
+ <screenfull />
+ </div>
+ </div>
+ <div class="user-profile">
+ <el-dropdown @command="handleCommand"
+ class="profile-dropdown"
+ trigger="click">
+ <div class="profile-trigger">
+ <div class="avatar-inner">
+ <img :src="userStore.avatar"
+ class="user-avatar" />
+ <div class="user-status-dot"></div>
+ </div>
+ <div class="profile-trigger-text">
+ <div class="user-name">{{ userStore.nickName || userStore.name || "绠$悊鍛�" }}</div>
+ </div>
+ <el-icon class="caret-icon"><caret-bottom /></el-icon>
</div>
<template #dropdown>
- <el-dropdown-menu>
- <router-link to="/user/profile">
- <el-dropdown-item>涓汉涓績</el-dropdown-item>
- </router-link>
- <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
- <span>甯冨眬璁剧疆</span>
- </el-dropdown-item>
- <el-dropdown-item divided command="logout">
- <span>閫�鍑虹櫥褰�</span>
- </el-dropdown-item>
- </el-dropdown-menu>
+ <div class="user-profile-dropdown-panel">
+ <div class="user-profile-dropdown-head">
+ <img :src="userStore.avatar"
+ class="user-profile-dropdown-avatar" />
+ <div class="user-profile-dropdown-meta">
+ <div class="user-profile-dropdown-name">{{ userStore.nickName || userStore.name || "绠$悊鍛�" }}</div>
+ <div class="user-profile-dropdown-role">{{ userStore.roleName || "绯荤粺鐢ㄦ埛" }}</div>
+ </div>
+ </div>
+ <el-dropdown-menu class="user-profile-dropdown">
+ <router-link to="/user/profile">
+ <el-dropdown-item>
+ <el-icon>
+ <User />
+ </el-icon>涓汉涓績
+ </el-dropdown-item>
+ </router-link>
+ <el-dropdown-item command="setLayout"
+ v-if="settingsStore.showSettings">
+ <el-icon>
+ <Setting />
+ </el-icon>甯冨眬璁剧疆
+ </el-dropdown-item>
+ <el-dropdown-item divided
+ command="logout"
+ class="logout-item">
+ <el-icon>
+ <SwitchButton />
+ </el-icon>閫�鍑虹櫥褰�
+ </el-dropdown-item>
+ </el-dropdown-menu>
+ </div>
</template>
</el-dropdown>
</div>
@@ -84,299 +104,441 @@
</template>
<script setup>
-import { ElMessageBox } from "element-plus";
-import { Bell, Search } from "@element-plus/icons-vue";
-import Breadcrumb from "@/components/Breadcrumb";
-import Hamburger from "@/components/Hamburger";
-import Screenfull from "@/components/Screenfull";
-import HeaderSearch from "@/components/HeaderSearch";
-import NotificationCenter from "./NotificationCenter/index.vue";
-import useAppStore from "@/store/modules/app";
-import useUserStore from "@/store/modules/user";
-import useSettingsStore from "@/store/modules/settings";
+ import { ElMessageBox } from "element-plus";
+ import { Bell, Search } from "@element-plus/icons-vue";
+ import Breadcrumb from "@/components/Breadcrumb";
+ import Hamburger from "@/components/Hamburger";
+ import Screenfull from "@/components/Screenfull";
+ import HeaderSearch from "@/components/HeaderSearch";
+ import NotificationCenter from "./NotificationCenter/index.vue";
+ import useAppStore from "@/store/modules/app";
+ import useUserStore from "@/store/modules/user";
+ import useSettingsStore from "@/store/modules/settings";
-const appStore = useAppStore();
-const userStore = useUserStore();
-const settingsStore = useSettingsStore();
+ const appStore = useAppStore();
+ const userStore = useUserStore();
+ const settingsStore = useSettingsStore();
-const topSearchKeyword = ref("");
-const headerSearchRef = ref(null);
-const notificationVisible = ref(false);
-const notificationCenterRef = ref(null);
-const unreadCount = ref(0);
+ const topSearchKeyword = ref("");
+ const headerSearchRef = ref(null);
+ const notificationVisible = ref(false);
+ const notificationCenterRef = ref(null);
+ const unreadCount = ref(0);
-function toggleSideBar() {
- appStore.toggleSideBar();
-}
-
-function openHeaderSearch() {
- headerSearchRef.value?.open(topSearchKeyword.value);
-}
-
-function handleCommand(command) {
- switch (command) {
- case "setLayout":
- setLayout();
- break;
- case "logout":
- logout();
- break;
- default:
- break;
+ function toggleSideBar() {
+ appStore.toggleSideBar();
}
-}
-function logout() {
- ElMessageBox.confirm("纭畾娉ㄩ攢骞堕��鍑虹郴缁熷悧锛�", "鎻愮ず", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- userStore.logOut().then(() => {
- location.href = "/index";
- });
+ function openHeaderSearch() {
+ headerSearchRef.value?.open(topSearchKeyword.value);
+ }
+
+ function handleCommand(command) {
+ switch (command) {
+ case "setLayout":
+ setLayout();
+ break;
+ case "logout":
+ logout();
+ break;
+ default:
+ break;
+ }
+ }
+
+ function logout() {
+ ElMessageBox.confirm("纭畾娉ㄩ攢骞堕��鍑虹郴缁熷悧锛�", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
})
- .catch(() => {});
-}
+ .then(() => {
+ userStore.logOut().then(() => {
+ location.href = "/index";
+ });
+ })
+ .catch(() => {});
+ }
-const emits = defineEmits(["setLayout"]);
-function setLayout() {
- emits("setLayout");
-}
+ const emits = defineEmits(["setLayout"]);
+ function setLayout() {
+ emits("setLayout");
+ }
-function handleUnreadCountChange(count) {
- unreadCount.value = count;
-}
+ function handleUnreadCountChange(count) {
+ unreadCount.value = count;
+ }
-let unreadCountTimer = null;
-onMounted(() => {
- nextTick(() => {
- if (notificationCenterRef.value) {
- notificationCenterRef.value.loadUnreadCount();
+ let unreadCountTimer = null;
+ onMounted(() => {
+ nextTick(() => {
+ if (notificationCenterRef.value) {
+ notificationCenterRef.value.loadUnreadCount();
+ }
+ });
+
+ unreadCountTimer = setInterval(() => {
+ if (notificationCenterRef.value) {
+ notificationCenterRef.value.loadUnreadCount();
+ }
+ }, 30000);
+ });
+
+ watch(notificationVisible, val => {
+ if (val && notificationCenterRef.value) {
+ nextTick(() => {
+ notificationCenterRef.value.loadMessages();
+ });
}
});
- unreadCountTimer = setInterval(() => {
- if (notificationCenterRef.value) {
- notificationCenterRef.value.loadUnreadCount();
+ onUnmounted(() => {
+ if (unreadCountTimer) {
+ clearInterval(unreadCountTimer);
}
- }, 30000);
-});
-
-watch(notificationVisible, (val) => {
- if (val && notificationCenterRef.value) {
- nextTick(() => {
- notificationCenterRef.value.loadMessages();
- });
- }
-});
-
-onUnmounted(() => {
- if (unreadCountTimer) {
- clearInterval(unreadCountTimer);
- }
-});
+ });
</script>
<style lang="scss" scoped>
-.navbar {
- height: var(--topbar-height);
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 14px;
- background: rgba(255, 255, 255, 0.86);
- border: 1px solid rgba(148, 163, 184, 0.18);
- border-radius: var(--content-radius);
- backdrop-filter: blur(16px);
- box-shadow: 0 8px 20px rgba(15, 23, 42, 0.05);
- padding: 0 18px;
-}
-
-.left-zone {
- flex: 0 1 420px;
- min-width: 0;
- display: flex;
- align-items: center;
- gap: 10px;
-}
-
-.hamburger-container {
- line-height: 36px;
- height: 36px;
- width: 36px;
- border-radius: 10px;
- display: flex;
- align-items: center;
- justify-content: center;
- color: var(--navbar-text);
-
- &:hover {
- background: var(--navbar-hover);
- }
-}
-
-.breadcrumb-container {
- min-width: 0;
-}
-
-.center-zone {
- width: clamp(360px, 34vw, 560px);
- min-width: 320px;
- height: 38px;
- border-radius: 999px;
- border: 1px solid rgba(148, 163, 184, 0.24);
- background: rgba(248, 251, 255, 0.92);
- display: flex;
- align-items: center;
- padding: 0 12px;
- gap: 8px;
-}
-
-.search-icon {
- color: #5b86c9;
- cursor: pointer;
-}
-
-.center-zone :deep(.el-input__wrapper) {
- border: 0;
- box-shadow: none !important;
- background: transparent;
- padding: 0;
-}
-
-.center-zone :deep(.el-input__inner) {
- color: #334155;
- font-size: 13px;
-}
-
-.search-popup-trigger :deep(.search-icon) {
- color: #5b86c9;
- font-size: 16px;
- cursor: pointer;
-}
-
-.right-menu {
- height: 100%;
- align-items: center;
- display: flex;
- gap: 14px;
-}
-
-.right-menu-item {
- display: flex;
- align-items: center;
- justify-content: center;
- color: var(--navbar-text);
- border-radius: 8px;
-}
-
-.hover-effect {
- cursor: pointer;
- transition: background 0.2s;
-
- &:hover {
- background: var(--navbar-hover);
- }
-}
-
-.notification-container,
-.screenfull-container {
- width: 36px;
- height: 36px;
-}
-
-.notification-badge :deep(.el-badge__content) {
- border: none;
-}
-
-.screenfull-container :deep(.svg-icon) {
- width: 16px;
- height: 16px;
- color: var(--navbar-text);
-}
-
-.avatar-container {
- height: 100%;
- display: flex;
- align-items: center;
-}
-
-.avatar-container :deep(.el-dropdown) {
- height: 100%;
- display: flex;
- align-items: center;
-}
-
-.avatar-wrapper {
- display: flex;
- align-items: center;
- gap: 10px;
- padding: 4px 10px 4px 8px;
- height: 44px;
- border-radius: 22px;
- background: rgba(255, 255, 255, 0.9);
- border: 1px solid rgba(148, 163, 184, 0.22);
-}
-
-.user-summary {
- display: flex;
- flex-direction: column;
- align-items: flex-end;
- gap: 2px;
-}
-
-.user-name {
- color: var(--text-primary);
- font-size: 13px;
- line-height: 1;
-}
-
-.user-role {
- color: var(--text-tertiary);
- font-size: 11px;
- line-height: 1;
-}
-
-.user-avatar {
- cursor: pointer;
- width: 36px;
- height: 36px;
- border-radius: 50%;
- border: 1px solid rgba(148, 163, 184, 0.3);
-}
-
-@media (max-width: 1200px) {
- .center-zone {
- display: none;
+ .navbar {
+ height: var(--topbar-height);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 24px;
+ background: var(--navbar-bg);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
+ backdrop-filter: blur(12px);
+ z-index: var(--layout-header-z);
}
- .user-summary {
- display: none;
+ .left-menu {
+ display: flex;
+ align-items: center;
+ gap: 12px;
}
-}
+
+ .hamburger-container {
+ height: 32px;
+ width: 32px;
+ border-radius: var(--radius-sm);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--navbar-text);
+ cursor: pointer;
+ transition: all 0.2s ease;
+
+ &:hover {
+ background: var(--navbar-hover);
+ color: #fff;
+ }
+ }
+
+ .breadcrumb-container {
+ min-width: 0;
+
+ :deep(.el-breadcrumb__inner) {
+ color: var(--navbar-text) !important;
+ opacity: 0.85;
+
+ &:hover {
+ color: #fff !important;
+ opacity: 1;
+ }
+
+ a {
+ color: inherit !important;
+ font-weight: 500 !important;
+ }
+ }
+
+ :deep(.no-redirect) {
+ color: #fff !important;
+ font-weight: 600 !important;
+ opacity: 1;
+ }
+
+ :deep(.el-breadcrumb__separator) {
+ color: var(--navbar-text);
+ opacity: 0.5;
+ }
+ }
+
+ .right-menu {
+ display: flex;
+ align-items: center;
+ gap: 20px; // 澧炲姞澶х粍涔嬮棿鐨勯棿璺�
+
+ .search-wrapper {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ height: 34px;
+ padding: 0 12px;
+ background: var(--navbar-hover);
+ border: 1px solid var(--surface-border);
+ border-radius: 17px;
+ width: 240px; // 鎼滅储妗嗘洿鍔犵簿鑷村皬宸�
+ transition: all 0.3s ease;
+
+ &:focus-within {
+ width: 300px;
+ background: rgba(255, 255, 255, 0.1);
+ border-color: var(--accent-primary);
+ box-shadow: 0 0 0 2px rgba(var(--el-color-primary-rgb), 0.2);
+ }
+
+ .search-icon {
+ color: var(--sidebar-text);
+ font-size: 16px;
+ cursor: pointer;
+ }
+
+ :deep(.el-input__wrapper) {
+ background: transparent;
+ box-shadow: none !important;
+ padding: 0;
+ }
+
+ :deep(.el-input__inner) {
+ color: var(--navbar-text);
+ font-size: 13px;
+ height: 32px;
+
+ &::placeholder {
+ color: var(--sidebar-text);
+ }
+ }
+ }
+
+ .action-icons {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ padding-right: 16px;
+ border-right: 1px solid var(--surface-border); // 澧炲姞鍨傜洿鍒嗗壊绾�
+
+ .right-menu-item {
+ padding: 0 8px;
+ height: 34px;
+ display: flex;
+ align-items: center;
+ color: var(--navbar-text);
+ border-radius: var(--radius-sm);
+ transition: all 0.2s ease;
+ cursor: pointer;
+
+ &:hover {
+ background: var(--navbar-hover);
+ color: var(--menu-active-text);
+ }
+ }
+ }
+
+ .user-profile {
+ .profile-dropdown {
+ cursor: pointer;
+ }
+
+ .profile-trigger {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ height: 38px;
+ padding: 4px 10px 4px 6px;
+ border-radius: 999px;
+ border: 1px solid rgba(var(--el-color-primary-rgb), 0.32);
+ background: rgba(0, 0, 0, 0.16);
+ transition: 0.2s ease;
+
+ &:hover {
+ background: rgba(0, 0, 0, 0.24);
+ border-color: rgba(var(--el-color-primary-rgb), 0.58);
+ box-shadow: 0 0 0 2px rgba(var(--el-color-primary-rgb), 0.18);
+ }
+ }
+
+ .profile-trigger-text {
+ display: flex;
+ align-items: center;
+ max-width: 120px;
+ min-width: 0;
+ }
+
+ .user-name {
+ font-size: 13px;
+ font-weight: 700;
+ color: var(--navbar-text);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ line-height: 1;
+ }
+
+ .avatar-inner {
+ position: relative;
+ flex-shrink: 0;
+ display: flex;
+ }
+
+ .user-avatar {
+ width: 30px;
+ height: 30px;
+ border-radius: 999px;
+ border: 2px solid rgba(var(--el-color-primary-rgb), 0.28);
+ box-shadow: 0 8px 18px rgba(0, 0, 0, 0.18);
+ object-fit: cover;
+ transition: 0.2s ease;
+ }
+
+ .profile-trigger:hover .user-avatar {
+ transform: translateY(-1px);
+ }
+
+ .user-status-dot {
+ position: absolute;
+ bottom: -1px;
+ right: -1px;
+ width: 9px;
+ height: 9px;
+ background: #10b981;
+ border: 2px solid var(--navbar-bg);
+ border-radius: 999px;
+ }
+
+ .caret-icon {
+ color: var(--navbar-text);
+ opacity: 0.76;
+ font-size: 12px;
+ transition: 0.2s ease;
+ margin-left: 2px;
+ }
+
+ .profile-trigger:hover .caret-icon {
+ transform: translateY(1px);
+ opacity: 1;
+ }
+ }
+ }
+
+ :deep(.user-profile-dropdown-panel) {
+ min-width: 240px;
+ color: var(--sidebar-text);
+ }
+
+ :deep(.user-profile-dropdown-head) {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 12px 12px 10px;
+ margin: 0 6px 6px;
+ border-radius: var(--radius-lg);
+ // background: rgba(0, 0, 0, 0.18);
+ // border: 1px solid rgba(var(--el-color-primary-rgb), 0.22);
+ }
+
+ :deep(.user-profile-dropdown-avatar) {
+ width: 38px;
+ height: 38px;
+ border-radius: 999px;
+ border: 2px solid rgba(var(--el-color-primary-rgb), 0.26);
+ object-fit: cover;
+ flex-shrink: 0;
+ }
+
+ :deep(.user-profile-dropdown-meta) {
+ min-width: 0;
+ }
+
+ :deep(.user-profile-dropdown-name) {
+ font-size: 13px;
+ font-weight: 800;
+ color: #000;
+ line-height: 1.2;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ :deep(.user-profile-dropdown-role) {
+ margin-top: 2px;
+ font-size: 12px;
+ // color: var(--sidebar-muted, rgba(255, 255, 255, 0.62));
+ color: #64748b;
+ line-height: 1.2;
+ }
+
+ :deep(.user-profile-dropdown) {
+ background: var(--sidebar-bg) !important;
+ border: 1px solid var(--surface-border) !important;
+ border-radius: var(--radius-lg) !important;
+ box-shadow: var(--shadow-menu) !important;
+ padding: 6px !important;
+ backdrop-filter: blur(16px);
+
+ .el-dropdown-menu__item {
+ color: var(--sidebar-text) !important;
+ border-radius: var(--radius-md) !important;
+ margin: 2px 0 !important;
+ padding: 8px 16px !important;
+ font-size: 13px !important;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+
+ .el-icon {
+ font-size: 16px;
+ margin-right: 0;
+ }
+
+ &:hover {
+ background: var(--menu-hover) !important;
+ color: var(--menu-active-text) !important;
+ }
+
+ &.el-dropdown-menu__item--divided {
+ border-top-color: var(--surface-border) !important;
+ margin-top: 6px !important;
+ padding-top: 10px !important;
+
+ &::before {
+ display: none;
+ }
+ }
+
+ &.logout-item {
+ color: #f87171 !important;
+
+ &:hover {
+ background: rgba(239, 68, 68, 0.1) !important;
+ color: #ef4444 !important;
+ }
+ }
+ }
+ }
</style>
<style lang="scss">
-.notification-popover {
- padding: 0 !important;
- border-radius: 16px !important;
- border: 1px solid rgba(148, 163, 184, 0.22) !important;
- box-shadow: 0 18px 40px rgba(15, 23, 42, 0.12) !important;
- background: rgba(255, 255, 255, 0.94) !important;
- backdrop-filter: blur(16px);
-
- .el-popover__title {
- display: none;
- }
-
- .el-popover__body {
+ .notification-popover {
padding: 0 !important;
- }
-}
+ border-radius: var(--radius-lg) !important;
+ border: 1px solid rgba(15, 23, 42, 0.1) !important;
+ box-shadow: var(--shadow-menu) !important;
+ background: rgba(255, 255, 255, 0.96) !important;
+ backdrop-filter: blur(16px);
+ color: rgba(15, 23, 42, 0.92);
-.el-badge__content.is-fixed {
- top: 8px;
-}
+ .el-popover__title {
+ display: none;
+ }
+
+ .el-popover__body {
+ padding: 0 !important;
+ }
+ }
+
+ .el-badge__content.is-fixed {
+ top: 8px;
+ }
</style>
--
Gitblit v1.9.3