Navbar.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <script setup lang="ts">
  2. import { storeToRefs } from "pinia";
  3. import { useRoute, useRouter } from "vue-router";
  4. import { useAppStore } from "@/store/modules/app";
  5. import { useTagsViewStore } from "@/store/modules/tagsView";
  6. import { useUserStore } from "@/store/modules/user";
  7. import { SchoolList } from "@/api/school/types";
  8. import { getSchoolSelect } from "@/api/school";
  9. import { watch } from "vue";
  10. import SvgIcon from "@/components/SvgIcon/index.vue";
  11. import { CaretBottom } from "@element-plus/icons-vue";
  12. const appStore = useAppStore();
  13. const tagsViewStore = useTagsViewStore();
  14. const userStore = useUserStore();
  15. const route = useRoute();
  16. const router = useRouter();
  17. const { device } = storeToRefs(appStore); // 设备类型:desktop-宽屏设备 || mobile-窄屏设备
  18. /**
  19. * 左侧菜单栏显示/隐藏
  20. */
  21. function toggleSideBar() {
  22. appStore.toggleSidebar(true);
  23. }
  24. /**
  25. * vueUse 全屏
  26. */
  27. const { isFullscreen, toggle } = useFullscreen();
  28. /**
  29. * 注销
  30. */
  31. function logout() {
  32. ElMessageBox.confirm("确定退出系统吗?", "提示", {
  33. confirmButtonText: "确定",
  34. cancelButtonText: "取消",
  35. type: "warning",
  36. }).then(() => {
  37. userStore
  38. .logout()
  39. .then(() => {
  40. tagsViewStore.delAllViews();
  41. })
  42. .then(() => {
  43. router.push(`/login?redirect=${route.fullPath}`);
  44. });
  45. });
  46. }
  47. /**
  48. * 学校数据
  49. */
  50. const schoolData = ref<SchoolList[]>();
  51. const schoolId = ref(0);
  52. const schoolNum = ref("");
  53. async function getSchoolData() {
  54. getSchoolSelect()
  55. .then(({ data }) => {
  56. schoolData.value = data;
  57. if (schoolId.value == 0) {
  58. schoolId.value = data[0].school_id;
  59. schoolNum.value = data[0].num;
  60. userStore.changeSchool(schoolId.value, schoolNum.value);
  61. }
  62. })
  63. .catch((error) => {
  64. console.log(error);
  65. });
  66. }
  67. onMounted(() => {
  68. getSchoolData();
  69. });
  70. watch(
  71. () => schoolId.value,
  72. (newValue, oldValue) => {
  73. let num: string = "";
  74. schoolData.value?.some((school) => {
  75. if (newValue == school.school_id) {
  76. num = school.num;
  77. return true;
  78. }
  79. });
  80. //console.log("school", newValue, num);
  81. userStore.changeSchool(newValue, num);
  82. }
  83. );
  84. </script>
  85. <template>
  86. <!-- 顶部导航栏 -->
  87. <div class="navbar">
  88. <!-- 左侧面包屑 -->
  89. <div class="flex">
  90. <Hamburger
  91. :is-active="appStore.sidebar.opened"
  92. @toggle-click="toggleSideBar"
  93. />
  94. <Breadcrumb />
  95. </div>
  96. <!-- 右侧导航设置 -->
  97. <div class="flex">
  98. <!-- 导航栏设置(窄屏隐藏)-->
  99. <div v-if="device !== 'mobile'" class="setting-container">
  100. <!--全屏 -->
  101. <div class="setting-item" @click="toggle">
  102. <svg-icon
  103. :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
  104. size="16px"
  105. />
  106. </div>
  107. </div>
  108. <!-- 学校选择下拉框 -->
  109. <div class="nav-select">
  110. <el-select
  111. v-model="schoolId"
  112. size="large"
  113. placeholder="请选择学校"
  114. :suffix-icon="CaretBottom"
  115. >
  116. <el-option
  117. v-for="item in schoolData"
  118. :key="item.school_id"
  119. :label="item.name"
  120. :value="item.school_id"
  121. />
  122. </el-select>
  123. </div>
  124. <!-- 用户头像 -->
  125. <div class="avatar-container">
  126. <span>学校编码:{{ userStore.schoolNum }}</span>
  127. <span class="spl">|</span>
  128. <img src="../../assets/login/avatar.png" alt="头像" />
  129. <span class="">{{ userStore.nickname + " " + userStore.phone }}</span>
  130. <span @click="logout"
  131. ><svg-icon icon-class="exit" color="#006eff" size="20px"
  132. /></span>
  133. </div>
  134. </div>
  135. </div>
  136. </template>
  137. <style lang="scss" scoped>
  138. .navbar {
  139. display: flex;
  140. align-items: center;
  141. justify-content: space-between;
  142. height: 70px;
  143. background-color: #fff;
  144. box-shadow: 0 0 1px #0003;
  145. .setting-container {
  146. display: flex;
  147. align-items: center;
  148. .setting-item {
  149. display: inline-block;
  150. width: 30px;
  151. height: 70px;
  152. line-height: 70px;
  153. color: #5a5e66;
  154. text-align: center;
  155. cursor: pointer;
  156. &:hover {
  157. background: rgb(249 250 251 / 100%);
  158. }
  159. }
  160. }
  161. .avatar-container {
  162. display: flex;
  163. align-items: center;
  164. justify-items: center;
  165. margin: 0 20px 0 0;
  166. cursor: pointer;
  167. img {
  168. width: 40px;
  169. height: 40px;
  170. line-height: 40px;
  171. text-align: center;
  172. border-radius: 20px;
  173. background: #494949;
  174. }
  175. span {
  176. margin-left: 12px;
  177. font-size: 16px;
  178. color: #494949;
  179. &.spl {
  180. margin: 0 12px 0 12px;
  181. color: #d7d8d8;
  182. }
  183. }
  184. }
  185. .svg-icon {
  186. margin-bottom: -2px;
  187. }
  188. .el-select {
  189. padding: 15px 0;
  190. width: 280px;
  191. margin-left: 12px;
  192. }
  193. }
  194. /* 自定义 el-select 样式 */
  195. :deep(.el-input__wrapper) {
  196. background: #efefef;
  197. border-radius: 12px;
  198. }
  199. /* el-select 各种边框线隐藏**/
  200. :deep(.el-select) {
  201. --el-select-input-focus-border-color: none !important;
  202. }
  203. :deep(.el-input__wrapper) {
  204. box-shadow: none !important;
  205. }
  206. :deep(.el-select .el-input.is-focus .el-input__wrapper) {
  207. box-shadow: none !important;
  208. }
  209. :deep(.el-select .el-input__wrapper.is-focus) {
  210. box-shadow: none !important;
  211. }
  212. :deep(.el-select:hover:not(.el-select--disabled) .el-input__wrapper) {
  213. box-shadow: none !important;
  214. }
  215. //移动端兼容
  216. .mobile {
  217. .navbar {
  218. .nav-select {
  219. position: absolute;
  220. left: 0;
  221. top: 80px;
  222. z-index: 1;
  223. width: 100%;
  224. box-sizing: border-box;
  225. padding: 0 24px;
  226. .el-select {
  227. width: 100%;
  228. padding: 0;
  229. margin: 0;
  230. }
  231. :deep(.el-input__wrapper) {
  232. background: #ffffff;
  233. }
  234. }
  235. }
  236. }
  237. </style>