You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
5.4 KiB

9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
8 months ago
9 months ago
9 months ago
9 months ago
8 months ago
9 months ago
9 months ago
8 months ago
8 months ago
8 months ago
9 months ago
8 months ago
9 months ago
9 months ago
8 months ago
9 months ago
8 months ago
9 months ago
8 months ago
9 months ago
9 months ago
9 months ago
8 months ago
9 months ago
9 months ago
8 months ago
9 months ago
9 months ago
8 months ago
9 months ago
9 months ago
8 months ago
9 months ago
9 months ago
8 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
  1. <template>
  2. <Simplebar>
  3. <div id="container">
  4. <div class="leftSidebar" :style="{ width: state.menuWidth }">
  5. <a-flex justify="center" align="center" style="height: 48px;">
  6. <component :is=iconComponents.TitleOutLined :class="collapsed ? 'small' : 'large'" />
  7. <span v-if="!collapsed">{{ state.name }}</span>
  8. </a-flex>
  9. <a-menu v-model:selectedKeys="state.selectedKeys" mode="inline" theme="light"
  10. :inline-collapsed="state.collapsed" :items="items" style="border-inline-end: none;" @click="menuItemclick">
  11. </a-menu>
  12. </div>
  13. <div class="contentArea">
  14. <div>
  15. <a-flex>
  16. <a-space>
  17. <a-button @click="toggleCollapsed">
  18. <MenuUnfoldOutlined v-if="state.collapsed" />
  19. <MenuFoldOutlined v-else />
  20. </a-button>
  21. <a-button type="text" @click="jumpdashboard">首页</a-button>
  22. </a-space>
  23. </a-flex>
  24. <a-flex align="center" gap="middle">
  25. <span>{{ username }}</span>
  26. <div>
  27. <a-button type="primary" @click="showModal" danger>
  28. <LogoutOutlined />
  29. </a-button>
  30. <a-modal v-model:open="open" title="提示" @ok="handleOk" @cancel="handleCancel" ok-text="确认"
  31. cancel-text="取消">
  32. <p>确定要注销吗</p>
  33. </a-modal>
  34. </div>
  35. </a-flex>
  36. </div>
  37. <RouterView />
  38. </div>
  39. </div>
  40. </Simplebar>
  41. </template>
  42. <script setup lang='ts'>
  43. import { computed, ref, onMounted, h, reactive, watch } from 'vue';
  44. import iconComponents from "@/assets/index"
  45. import { RouterView, useRouter, useRoute } from 'vue-router'
  46. import { MenuFoldOutlined, MenuUnfoldOutlined, LogoutOutlined, DashboardOutlined } from '@ant-design/icons-vue';
  47. import { get } from "@/tools/request"
  48. import { message } from 'ant-design-vue';
  49. import { useAuthStore } from '@/stores/index'
  50. const router = useRouter()
  51. const state = reactive({
  52. collapsed: false,
  53. selectedKeys: ['1'],
  54. name: '博客后台系统',
  55. menuWidth: '10%'
  56. });
  57. const items = reactive([
  58. {
  59. key: 'dashboard',
  60. icon: () => h(DashboardOutlined),
  61. label: "仪表盘",
  62. title: '仪表盘',
  63. },
  64. {
  65. key: 'blogmanage',
  66. icon: () => h(iconComponents.BlogOutLined),
  67. label: '博客管理',
  68. title: '博客管理',
  69. children: [
  70. {
  71. key: 'blogmanage',
  72. label: '博客管理',
  73. title: '博客管理',
  74. },
  75. {
  76. key: 'blogtype',
  77. label: '博客分类',
  78. title: '博客分类',
  79. },
  80. {
  81. key: 'bloglabel',
  82. icon: () => h(iconComponents.TypeOutLined),
  83. label: '博客标签',
  84. title: '博客标签',
  85. }
  86. ],
  87. },
  88. {
  89. key: 'diarymanage',
  90. icon: () => h(iconComponents.DiaryOutLined),
  91. label: '日记管理',
  92. title: '日记管理',
  93. children: [
  94. {
  95. key: 'diarymanage',
  96. label: '日记管理',
  97. title: '日记管理',
  98. },
  99. {
  100. key: 'diarytype',
  101. label: '日记分类',
  102. title: '日记分类',
  103. }
  104. ],
  105. },
  106. {
  107. key: 'classticmanage',
  108. icon: () => h(iconComponents.DiaryOutLined),
  109. label: '语录管理',
  110. title: '语录管理',
  111. },
  112. {
  113. key: 'commonlinkmanage',
  114. icon: () => h(iconComponents.DiaryOutLined),
  115. label: '链接管理',
  116. title: '链接管理',
  117. },
  118. {
  119. key: 'commentmanage',
  120. icon: () => h(iconComponents.CommentOutLined),
  121. label: '评论管理',
  122. title: '评论管理',
  123. },
  124. {
  125. key: 'imagemanage',
  126. icon: () => h(iconComponents.PhotoOutLined),
  127. label: '相册管理',
  128. title: '相册管理',
  129. },
  130. {
  131. key: 'filemanage',
  132. icon: () => h(iconComponents.FileOutLined),
  133. label: '文件管理',
  134. title: '文件管理',
  135. },
  136. {
  137. key: 'systemmanage',
  138. icon: () => h(iconComponents.SystemOutLined),
  139. label: '系统设置',
  140. title: '系统设置',
  141. },
  142. ]);
  143. const menuItemclick = ({ key }: { key: any }) => {
  144. router.push(key)
  145. }
  146. const collapsed = computed(() => state.collapsed);
  147. const authStore = useAuthStore()
  148. const username = ref("")
  149. const toggleCollapsed = () => {
  150. state.collapsed = !state.collapsed;
  151. state.menuWidth = state.collapsed ? 'auto' : '10%'
  152. };
  153. const jumpdashboard = function () {
  154. state.selectedKeys = ['1']
  155. router.push('/admin/dashboard')
  156. }
  157. onMounted(async () => {
  158. const userinfo = await get(
  159. '/users/me',
  160. {
  161. 'Accept': 'application/json',
  162. 'Content-Type': 'application/x-www-form-urlencoded'
  163. }
  164. )
  165. username.value = userinfo.data.username
  166. });
  167. const open = ref<boolean>(false);
  168. const showModal = () => {
  169. open.value = true;
  170. };
  171. const handleOk = (e: MouseEvent) => {
  172. console.log(e);
  173. authStore.removeToken()
  174. message.loading("注销成功")
  175. setTimeout(() => {
  176. router.push('/login')
  177. }, 2000);
  178. open.value = false;
  179. };
  180. const handleCancel = (e: MouseEvent) => {
  181. message.warn('取消注销');
  182. }
  183. </script>
  184. <style scoped>
  185. #container {
  186. display: flex;
  187. }
  188. .leftSidebar {
  189. border-right: 1px solid rgba(5, 5, 5, 0.06);
  190. font-size: 20px;
  191. }
  192. .leftSidebar>* {
  193. margin: 12px 0;
  194. }
  195. .leftSidebar>:first-child {
  196. font-size: 20px;
  197. }
  198. .contentArea {
  199. flex: 1;
  200. }
  201. .contentArea>:first-child {
  202. margin: 24px;
  203. display: flex;
  204. flex-direction: row;
  205. justify-content: space-between;
  206. align-items: center;
  207. }
  208. .small {
  209. font-size: 30px;
  210. margin: 0 5px 0 5px;
  211. }
  212. .large {
  213. font-size: 50px;
  214. margin: 0 10px 0 10px;
  215. }
  216. </style>