basic.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <script lang="ts" setup>
  2. import type { NotificationItem } from '@vben/layouts';
  3. import { computed, ref, watch } from 'vue';
  4. import { AuthenticationLoginExpiredModal } from '@vben/common-ui';
  5. import { VBEN_DOC_URL, VBEN_GITHUB_URL } from '@vben/constants';
  6. import { useWatermark } from '@vben/hooks';
  7. import { BookOpenText, CircleHelp, MdiGithub } from '@vben/icons';
  8. import {
  9. BasicLayout,
  10. LockScreen,
  11. Notification,
  12. UserDropdown,
  13. } from '@vben/layouts';
  14. import { preferences } from '@vben/preferences';
  15. import { useAccessStore, useTabbarStore, useUserStore } from '@vben/stores';
  16. import { openWindow } from '@vben/utils';
  17. import { $t } from '#/locales';
  18. import { useAuthStore } from '#/store';
  19. import LoginForm from '#/views/_core/authentication/login.vue';
  20. const { setMenuList } = useTabbarStore();
  21. setMenuList([
  22. 'close',
  23. 'affix',
  24. 'maximize',
  25. 'reload',
  26. 'open-in-new-window',
  27. 'close-left',
  28. 'close-right',
  29. 'close-other',
  30. 'close-all',
  31. ]);
  32. const notifications = ref<NotificationItem[]>([
  33. {
  34. avatar: 'https://avatar.vercel.sh/vercel.svg?text=VB',
  35. date: '3小时前',
  36. isRead: true,
  37. message: '描述信息描述信息描述信息',
  38. title: '收到了 14 份新周报',
  39. },
  40. {
  41. avatar: 'https://avatar.vercel.sh/1',
  42. date: '刚刚',
  43. isRead: false,
  44. message: '描述信息描述信息描述信息',
  45. title: '朱偏右 回复了你',
  46. },
  47. {
  48. avatar: 'https://avatar.vercel.sh/1',
  49. date: '2024-01-01',
  50. isRead: false,
  51. message: '描述信息描述信息描述信息',
  52. title: '曲丽丽 评论了你',
  53. },
  54. {
  55. avatar: 'https://avatar.vercel.sh/satori',
  56. date: '1天前',
  57. isRead: false,
  58. message: '描述信息描述信息描述信息',
  59. title: '代办提醒',
  60. },
  61. ]);
  62. const userStore = useUserStore();
  63. const authStore = useAuthStore();
  64. const accessStore = useAccessStore();
  65. const { destroyWatermark, updateWatermark } = useWatermark();
  66. const showDot = computed(() =>
  67. notifications.value.some((item) => !item.isRead),
  68. );
  69. const menus = computed(() => [
  70. {
  71. handler: () => {
  72. openWindow(VBEN_DOC_URL, {
  73. target: '_blank',
  74. });
  75. },
  76. icon: BookOpenText,
  77. text: $t('ui.widgets.document'),
  78. },
  79. {
  80. handler: () => {
  81. openWindow(VBEN_GITHUB_URL, {
  82. target: '_blank',
  83. });
  84. },
  85. icon: MdiGithub,
  86. text: 'GitHub',
  87. },
  88. {
  89. handler: () => {
  90. openWindow(`${VBEN_GITHUB_URL}/issues`, {
  91. target: '_blank',
  92. });
  93. },
  94. icon: CircleHelp,
  95. text: $t('ui.widgets.qa'),
  96. },
  97. ]);
  98. const avatar = computed(() => {
  99. return userStore.userInfo?.avatar ?? preferences.app.defaultAvatar;
  100. });
  101. async function handleLogout() {
  102. await authStore.logout(false);
  103. }
  104. function handleNoticeClear() {
  105. notifications.value = [];
  106. }
  107. function handleMakeAll() {
  108. notifications.value.forEach((item) => (item.isRead = true));
  109. }
  110. function handleClickLogo() {}
  111. watch(
  112. () => preferences.app.watermark,
  113. async (enable) => {
  114. if (enable) {
  115. await updateWatermark({
  116. content: `${userStore.userInfo?.username}`,
  117. });
  118. } else {
  119. destroyWatermark();
  120. }
  121. },
  122. {
  123. immediate: true,
  124. },
  125. );
  126. </script>
  127. <template>
  128. <BasicLayout
  129. @clear-preferences-and-logout="handleLogout"
  130. @click-logo="handleClickLogo"
  131. >
  132. <template #user-dropdown>
  133. <UserDropdown
  134. :avatar
  135. :menus
  136. :text="userStore.userInfo?.realName"
  137. description="ann.vben@gmail.com"
  138. tag-text="Pro"
  139. trigger="both"
  140. @logout="handleLogout"
  141. />
  142. </template>
  143. <template #notification>
  144. <Notification
  145. :dot="showDot"
  146. :notifications="notifications"
  147. @clear="handleNoticeClear"
  148. @make-all="handleMakeAll"
  149. />
  150. </template>
  151. <template #extra>
  152. <AuthenticationLoginExpiredModal
  153. v-model:open="accessStore.loginExpired"
  154. :avatar
  155. >
  156. <LoginForm />
  157. </AuthenticationLoginExpiredModal>
  158. </template>
  159. <template #lock-screen>
  160. <LockScreen :avatar @to-login="handleLogout" />
  161. </template>
  162. </BasicLayout>
  163. </template>