sidebarL.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. <template>
  2. <div class="left">
  3. <div class="logo2">
  4. <img :src="fromL.basics.logo" alt="">
  5. </div>
  6. <div class="ulT">
  7. <!-- 默认首页 -->
  8. <div @click.stop="goto(0)" :style="{background :activeL === 0 ?'#E6F0FF':'',zIndex : 10000 }">
  9. <div class="menu_left">
  10. <img class="logo" :src="activeL === 0 ? require('../assets/img/sy1.svg') : require('../assets/img/sy.svg')" alt="">
  11. <span :style="{color : activeL === 0 ? '#0051D7' :''}">首页</span>
  12. </div>
  13. </div>
  14. <!-- 权限 -->
  15. <div v-for="(item,index) in appSignL(fromL.admin.sidebar.list)"
  16. @click.stop="goto(index,item)"
  17. :style="{background :activeL === (index +1) ?'#E6F0FF':'',zIndex : 10000 }"
  18. :key="index+1">
  19. <!-- 渲染菜单类型 -->
  20. <div class="menu_left" v-if="item.menuName">
  21. <img class="logo" :src="activeL === (index +1) ? item.menuActiveIcon : item.menuIcon" alt="">
  22. <span :style="{color : activeL === (index +1) ? '#0051D7' :''}">{{ item.menuName }}</span>
  23. </div>
  24. <!-- 渲染应用类型, status判断是否被删除 isAdmin是否为管理员可见 -->
  25. <div v-else>
  26. <div>
  27. <div v-for="(p,pin) in AppCon(item.url)" :key="pin+'p'">
  28. <div class="menu_left" >
  29. <div>
  30. <img class="logo3"
  31. :src="activeL === (index +1) ? p.icon : p.activeIcon"
  32. alt="">
  33. </div>
  34. <span :style="{color : activeL === (index +1) ? '#0051D7' :''}">
  35. {{ p.name }}
  36. </span>
  37. </div>
  38. </div>
  39. </div>
  40. </div>
  41. </div>
  42. </div>
  43. <div class="userInfo">
  44. <img style="width: 40px;height: 40px;object-fit: cover;border-radius: 50%;margin-bottom: 4px;" :src="userinfo.headportrait ? userinfo.headportrait : require('../assets/img/toux.png')" alt="">
  45. <div style="margin-bottom: 8px;">{{ userinfo.username }}</div>
  46. <span style="cursor: pointer;padding: 5px;background-color: #e7e7e7;box-sizing: border-box;border-radius: 5px;" @click="handleLogout">退出登录</span>
  47. </div>
  48. <!-- 二级导航 -->
  49. <div class="ulTCopy" v-if="isShow && barCopy.length != 0" >
  50. <div class="ulTCopyTit">
  51. <span>教学中心</span>
  52. <span @click="closeCopy" class="cha" style="color: #6B7280;font-size: 23px;cursor: pointer;">⨯</span>
  53. </div>
  54. <div style="padding: 16px;box-sizing: border-box;">
  55. <div class="ulTCopyTxt" v-for="(i,ind) in appSignL(barCopy)" @click="levTwo(i)" :key="ind+'a'">
  56. <div>
  57. <div style="display: flex;justify-content: space-between;align-items: center;" v-for="(p,pin) in AppCon(i.url)" :key="pin+'p'">
  58. <div>
  59. <img style="width: 30px;object-fit: contain;margin-right: 5px;"
  60. :src="p.icon"
  61. alt="">
  62. </div>
  63. <span>{{ p.name }}</span>
  64. </div>
  65. </div>
  66. </div>
  67. </div>
  68. </div>
  69. <div v-if="isShow" @click="closeCopy" style="width: 100vw;height: 100vh;position: absolute;left: 0;top: 0;z-index: 1;"></div>
  70. </div>
  71. </template>
  72. <script>
  73. import { mapGetters, mapActions } from 'vuex';
  74. import { loginOut } from '@/api/user';
  75. import store from '../store'
  76. export default {
  77. computed: {
  78. ...mapGetters(['userinfo','fromL','appSign']),
  79. // 如果hk,com没有图标,默认使用cn的
  80. AppCon(){
  81. return function(c) {
  82. let k = JSON.parse(JSON.stringify(c))
  83. let data = k.filter(e=>{
  84. return e.region == this.userinfo.schoolArea || e.region == this.userinfo.orgArea
  85. })
  86. let data2 = k.filter(e=>{
  87. return e.region == 'cn'
  88. })
  89. // 如果hk,com没有图标,默认使用cn的
  90. if (!data[0].icon){
  91. data[0].icon = data2[0].icon
  92. data[0].activeIcon = data2[0].activeIcon
  93. }
  94. return data
  95. };
  96. },
  97. // 筛选是否为管理员可见,是否被删除
  98. appSignL(){
  99. return function(val){
  100. console.log(val);
  101. let data = []
  102. if (this.userinfo.type == 1 && this.userinfo.role == 1) {
  103. val.forEach( e =>{
  104. if (e.menuName || e.status == 0) {
  105. data.push(e)
  106. }
  107. })
  108. } else {
  109. val.forEach( e =>{
  110. if (e.menuName || (e.isAdmin == '0' && e.status == 0)) {
  111. data.push(e)
  112. }
  113. })
  114. }
  115. return data
  116. }
  117. }
  118. },
  119. data() {
  120. return {
  121. // 二级弹框是否显示
  122. isShow:false,
  123. // 一级选中第几个
  124. activeL:0,
  125. // 二级分类
  126. barCopy:[],
  127. }
  128. },
  129. methods: {
  130. ...mapActions({
  131. logout: 'user/logout'
  132. }),
  133. async handleLogout() {
  134. this.$confirm('确定退出吗', '提示', {
  135. confirmButtonText: '确定',
  136. cancelButtonText: '取消',
  137. type: 'warning'
  138. }).then(async () => {
  139. loginOut()
  140. .then(async () => {
  141. this.$message({
  142. message: '退出成功',
  143. type: 'success'
  144. });
  145. await this.logout();
  146. this.$router.push('/login');
  147. })
  148. .catch(err => {
  149. console.error(err);
  150. });
  151. }).catch(() => {
  152. // 取消操作
  153. });
  154. },
  155. // 关闭二级导航遮罩层
  156. closeCopy(){
  157. this.isShow = false
  158. },
  159. // 点击一级导航
  160. async goto(index,val = null){
  161. console.log('goto',val);
  162. // val = null 就是点击了首页
  163. if (val) {
  164. this.activeL = index + 1
  165. }else{
  166. // 点击首页清空内容,并把标识去除
  167. await store.commit('user/SET_AppSIGN', '')
  168. document.querySelector('#pageCon').innerHTML = '';
  169. this.$emit('getPer')
  170. this.isShow = false
  171. this.activeL = index
  172. return
  173. }
  174. // 有二级导航的显示二级导航.无二级则进行判断
  175. if (val.children) {
  176. this.barCopy = JSON.parse(JSON.stringify(val.children))
  177. this.isShow = true
  178. // this.appSign = ''
  179. // document.querySelector('#pageCon').innerHTML = '';
  180. }else{
  181. this.isShow = false
  182. // 点击相同应用不刷新
  183. if (this.appSign == val.toolId) return
  184. // 更新标识
  185. await store.commit('user/SET_AppSIGN', val.toolId)
  186. let url = ''
  187. // 查出对应账号的应用区域地址
  188. val.url.forEach(e => {
  189. if (e.region == this.userinfo.schoolArea || e.region == this.userinfo.orgArea) {
  190. url = e.url
  191. }
  192. });
  193. let dom = document.querySelector('#pageCon')
  194. document.querySelector('#pageCon').innerHTML = '';
  195. console.log('val',val);
  196. window.topU.U.MD.D.I.openApplicationWai(val.toolId, url, dom,val.argumentList)
  197. // 应用标识,url,存储dom
  198. }
  199. },
  200. // 点击二级导航
  201. async levTwo(val){
  202. // 点击相同应用不刷新
  203. if (this.appSign == val.toolId) return
  204. // 更新标识
  205. await store.commit('user/SET_AppSIGN', val.toolId)
  206. let url = ''
  207. val.url.forEach(e => {
  208. if (e.region == this.userinfo.schoolArea || e.region == this.userinfo.orgArea) {
  209. url = e.url
  210. }
  211. });
  212. let dom = document.querySelector('#pageCon')
  213. document.querySelector('#pageCon').innerHTML = '';
  214. window.topU.U.MD.D.I.openApplicationWai(val.toolId, url, dom)
  215. }
  216. },
  217. }
  218. </script>
  219. <style scoped>
  220. .logo{
  221. width: 80px;
  222. height: 68px;
  223. }
  224. .logo3{
  225. height: 25px;object-fit: contain;transform: scale(1.5);
  226. }
  227. .logo2{
  228. padding: 16px;
  229. box-sizing: border-box;
  230. height: 68px;
  231. border-bottom: .5px #e5e7eb solid;
  232. }
  233. .logo2 img{
  234. width: 37px;
  235. }
  236. .userInfo{
  237. width: 80px;
  238. color: #374151;
  239. font-size: 12px;
  240. display: flex;
  241. flex-direction: column;
  242. align-items: center;
  243. padding: 8px;
  244. box-sizing: border-box;
  245. padding-bottom: 20px;
  246. }
  247. .left {
  248. font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important;
  249. width: 80px;
  250. height: 100%;
  251. background-color: #ffffff;
  252. display: flex;
  253. flex-direction: column;
  254. align-items: center;
  255. justify-content: space-between;
  256. position: relative;
  257. box-shadow: 5px 0 8px rgba(0, 0, 0, 0.1);
  258. z-index: 999;
  259. }
  260. .left .ulT {
  261. width: 100%;
  262. height: 100%;
  263. padding: 8px;
  264. box-sizing: border-box;
  265. display: flex;
  266. gap: 10px;
  267. overflow: auto;
  268. flex-direction: column;
  269. background-color: #ffffff;
  270. }
  271. .left .ulT div{
  272. border-radius: 10px;
  273. }
  274. .ulTCopy{
  275. position: absolute;
  276. right: 0;
  277. top: 0;
  278. transform: translate(256px,0);
  279. height: 100%;
  280. width: 256px;
  281. z-index: 999999999;
  282. background-color: #ffffff;
  283. overflow: visible;
  284. transition: width 2s ease; /* 定义过渡效果 */
  285. box-shadow: inset 2px 0 8px rgba(0, 0, 0, 0.1),5px 3px 5px 0px rgba(0, 0, 0, 0.1);
  286. }
  287. .ulTCopyTit{
  288. height: 72px;padding: 16px;box-sizing: border-box;color: #000;font-size: 18px;font-weight: 600;
  289. display: flex;
  290. align-items: center;
  291. justify-content: space-between;
  292. border-bottom: .5px #e5e7eb solid;
  293. }
  294. .ulTCopyTxt{
  295. height: 48px;padding: 12px;box-sizing: border-box;display: flex;align-items: center;
  296. color: #374151;
  297. border-radius: 10px;
  298. cursor: pointer;
  299. }
  300. .ulTCopyTxt:hover{
  301. background-color: #f3f4f6;
  302. }
  303. .cha:hover{
  304. color: #000 !important;
  305. }
  306. .menu_left {
  307. width: 64px;
  308. height: 70px;
  309. font-size: 10px;
  310. margin-top: 3px;
  311. white-space: nowrap;
  312. color: #64748b;
  313. align-items: center;
  314. justify-content: center;
  315. display: flex;
  316. flex-wrap: wrap;
  317. padding: 12px;
  318. box-sizing: border-box;
  319. border-radius: 10px;
  320. border: none;
  321. z-index: 1000000;
  322. text-decoration: none; /* 移除下划线 */
  323. cursor: pointer;
  324. border-radius: 10px;
  325. margin-top: 12px;
  326. }
  327. .ulT div:nth-child(1){
  328. margin-top: 0;
  329. }
  330. .menu_left:hover{
  331. background-color: #f3f4f6 !important;
  332. }
  333. .menu_left img{
  334. width: 22px;
  335. height: 20px;
  336. }
  337. </style>