LayoutHeader.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <template>
  2. <div class="layout-header">
  3. <div class="logo"></div>
  4. <div class="menu">
  5. <el-menu :default-active="currentPath" ref="menuRef" class="el-menu-demo" mode="horizontal">
  6. <el-menu-item :index="item.path" v-for="item in menuStore.routeList" :key="item.name"
  7. :class="{ 'external-link-item': isExternalLink(item.path) }" @click="handleMenuClick(item.path)">{{ item.title
  8. }}</el-menu-item>
  9. </el-menu>
  10. </div>
  11. <!-- 机构切换下拉 -->
  12. <div style="align-self: center; margin-right: 16px;">
  13. <el-select v-model="currentOrg" placeholder="请选择机构" style="width: 160px" @change="changeOrg">
  14. <el-option v-for="org in orgList" :key="org.id" :label="org.organ_name" :value="org.id" />
  15. </el-select>
  16. </div>
  17. <!-- 用户下拉 -->
  18. <div style="align-self: center;">
  19. <el-dropdown style="margin-top:10px">
  20. <div style="font-size:medium;font-weight: bold; color:#000">{{ user.full_name }}</div>
  21. <template #dropdown>
  22. <el-dropdown-menu>
  23. <el-dropdown-item>用户资料</el-dropdown-item>
  24. <el-dropdown-item @click="editPassShow = true">修改密码</el-dropdown-item>
  25. <el-dropdown-item @click="handleLogout">登出</el-dropdown-item>
  26. </el-dropdown-menu>
  27. </template>
  28. </el-dropdown>
  29. </div>
  30. </div>
  31. <EditPasswordDialog v-model="editPassShow" />
  32. </template>
  33. <script setup>
  34. import { ref, computed, onMounted, onBeforeUnmount, getCurrentInstance } from 'vue'
  35. import { useMenuStore } from "@/stores/menu.js"
  36. import { useRoute, useRouter } from "vue-router";
  37. import { getSessionVar, clearSessionVar, saveSessionVar } from '@/utils/session'
  38. import EditPasswordDialog from "@/components/EditPasswordDialog.vue"
  39. import { knowledgeGraphAddr } from "@/utils/config"
  40. import { isNotLogin } from "@/utils/app"
  41. const { proxy } = getCurrentInstance()
  42. const route = useRoute()
  43. const router = useRouter()
  44. let timer
  45. let editPassShow = ref(false)
  46. const menuRef = ref()
  47. // const { routeList, updateRouteList } = useMenuStore()
  48. const menuStore = useMenuStore()
  49. // console.log(operationPermissions)
  50. const user = ref({
  51. id: "0",
  52. full_name: 'John Doe',
  53. username: 'johndoe',
  54. })
  55. user.value = {
  56. id: getSessionVar('user_id') || "0",
  57. full_name: getSessionVar('full_name') || 'John Doe',
  58. username: getSessionVar('username') || 'johndoe',
  59. }
  60. // 机构相关
  61. const orgList = ref([])
  62. const currentOrg = ref(getSessionVar('org_id') || '') // 当前机构id
  63. // 获取机构列表
  64. const fetchOrgList = async () => {
  65. // 假设接口返回 { records: [{id, name}, ...] }
  66. const { records } = await proxy.$http.get('/open-platform/sys/loadSURO')
  67. orgList.value = records
  68. // 默认选中第一个
  69. const res = await proxy.$http.get('/open-platform/sys/currSURO')
  70. // console.log('当前机构11:', res)
  71. currentOrg.value = res
  72. saveSessionVar('org_id', res)
  73. // console.log('机构列表:', orgList.value)
  74. // console.log('当前机构:', currentOrg.value)
  75. }
  76. // 切换机构
  77. const changeOrg = async (orgId) => {
  78. // 可调用后端切换机构接口
  79. const res = await proxy.$http.post(`/open-platform/sys/changeSURO/${orgId}`)
  80. // console.log('切换机构结果:', res)
  81. saveSessionVar('org_id', orgId)
  82. saveSessionVar("knowledageSystem", '');
  83. saveSessionVar('routeList', '')
  84. // 可选:刷新页面或重新拉取权限/菜单等
  85. menuStore.updateRouteList([]);
  86. let knowledageSystem = '';
  87. let routeList = [{
  88. path: '/kmplatform/home',
  89. name: 'kmplatform-home',
  90. title: "主页",
  91. children: []
  92. }]
  93. res.records[0].menu_permissions.sort((a, b) => {
  94. return a.id - b.id;
  95. });
  96. res.records[0].menu_permissions.forEach((item) => {
  97. if (item.menu_name == "知识更新管理") {
  98. knowledageSystem = 'true';
  99. routeList.push({
  100. path: knowledgeGraphAddr,
  101. name: '',
  102. title: item.name,
  103. children: item.children,
  104. });
  105. } else if (item.menu_route) {
  106. routeList.push({
  107. path: item.menu_route,
  108. name: item.menu_route.split("/")[2],
  109. title: item.name,
  110. children: item.children,
  111. });
  112. }
  113. });
  114. // console.log("knowledageSystem", knowledageSystem);
  115. saveSessionVar("knowledageSystem", knowledageSystem);
  116. saveSessionVar('routeList', JSON.stringify(routeList))
  117. menuStore.updateRouteList(routeList);
  118. // 刷新页面
  119. // window.location.href = '/kmplatform/home';
  120. router.push({ path: menuStore.routeList[0].path })
  121. }
  122. const currentPath = computed(() => {
  123. // console.log('当前路由:', route)
  124. let temp = ""
  125. for (let i = 0; i < menuStore.routeList.length; i++) {
  126. for (let j = 0; j < route.matched.length; j++) {
  127. if (menuStore.routeList[i].path === route.matched[j].path) {
  128. temp = route.matched[j].path
  129. break
  130. }
  131. }
  132. if (temp) break;
  133. }
  134. return temp
  135. })
  136. const handleLogout = () => {
  137. router.push({ path: '/login' });
  138. clearSessionVar()
  139. }
  140. const isExternalLink = (path) => {
  141. return /^https?/g.test(path);
  142. };
  143. function handleMenuClick(path) {
  144. if (/^https?/g.test(path)) {
  145. const newWindow = window.open(path, '_blank');
  146. timer = setInterval(() => {
  147. newWindow?.postMessage({ type: 'login', username: getSessionVar("full_name"), userId: getSessionVar("user_id") }, "*")
  148. }, 1000)
  149. menuRef.value.updateActiveIndex(currentPath.value)
  150. } else {
  151. if (route.path.includes(path)) return
  152. router.push({ path: path })
  153. }
  154. }
  155. function handleLogin(event) {
  156. const { type, status } = event.data
  157. if (type === 'login' && status === 'ok') {
  158. clearInterval(timer)
  159. }
  160. }
  161. onMounted(() => {
  162. window.addEventListener('message', handleLogin);
  163. (!isNotLogin()) && fetchOrgList()
  164. if (route.name === 'kmplatform') {
  165. router.push({ path: menuStore.routeList[0].path })
  166. }
  167. })
  168. onBeforeUnmount(() => {
  169. window.removeEventListener('message', handleLogin);
  170. clearInterval(timer)
  171. })
  172. </script>
  173. <style lang="less" scoped>
  174. .layout-header {
  175. display: flex;
  176. border-bottom: 1px solid #C4C2C2;
  177. // padding-bottom: 10px;
  178. .logo {
  179. width: 200px;
  180. // height: 60px;
  181. // border: 1px solid skyblue;
  182. flex: 0 0 auto;
  183. margin-right: 50px;
  184. background: url('../assets/images/logo.jpg') no-repeat center;
  185. background-size: 100% 100%;
  186. }
  187. .menu {
  188. flex: 1 1 auto;
  189. // .el-menu--horizontal>.el-menu-item.is-active {
  190. // border: none;
  191. // }
  192. .el-menu--horizontal.el-menu {
  193. border: none;
  194. }
  195. :deep(.el-menu) {
  196. .el-menu-item {
  197. font-size: 20px;
  198. }
  199. }
  200. .external-link-item {
  201. // 覆盖激活效果
  202. &.is-active {
  203. background-color: transparent !important;
  204. color: inherit !important;
  205. }
  206. // 覆盖点击效果
  207. &:focus {
  208. background-color: transparent !important;
  209. color: inherit !important;
  210. }
  211. }
  212. }
  213. }
  214. </style>