sidebarL.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. <template>
  2. <div class="left">
  3. <!-- <div > -->
  4. <div class="logo2" @click="gotoKanban">
  5. <img :src="fromL.basics.logo ? fromL.basics.logo : require('../assets/img/moren.png')" alt="">
  6. </div>
  7. <!-- <div class="ulT"> -->
  8. <!-- 默认首页 -->
  9. <div class="ulTOne" @click.stop="goto(0)">
  10. <div class="menu_left">
  11. <img class="logo" :src="activeL === 0 ? require('../assets/img/sy.svg') : require('../assets/img/sy1.svg')" alt="">
  12. <span class="barT" :style="{color : activeL === 0 ? '#0051D7' :''}">首页</span>
  13. </div>
  14. </div>
  15. <!-- 权限 -->
  16. <div style="width: 100%;" v-for="(item,index) in appSignL(fromL.admin.sidebar.list)"
  17. :key="index+1">
  18. <!-- 渲染菜单类型 -->
  19. <div class="ulTOne" v-if="item.menuName">
  20. <!-- 二级导航 -->
  21. <div class="ulTCopy">
  22. <div class="ulTCopyTit">
  23. <span>{{ item.menuName }}</span>
  24. </div>
  25. <div class="ulTCopyHei">
  26. <div class="ulTCopyTxt"
  27. v-for="(i,ind) in appSignL(item.children)"
  28. @click="levTwo(i,ind,index)" :key="ind+'a'">
  29. <div class="ulTCopyTxt"
  30. :style="{background : (activeLTwo === index+1 +'+' + ind)? '#0663FE' : '',color: (activeLTwo === index+1 +'+' + ind)? '#fff' :''}"
  31. v-for="(p,pin) in AppCon(i.url)" :key="pin+'p'">
  32. <div class="ulTCopyConT">{{ p.name }}</div>
  33. </div>
  34. </div>
  35. </div>
  36. </div>
  37. <div class="menu_left">
  38. <img :src="activeL === (index +1) ? item.menuActiveIcon : item.menuIcon" class="logo" alt="">
  39. <span class="barT" :style="{color : activeL === (index +1) ? '#0051D7' :''}">{{ item.menuName }}</span>
  40. </div>
  41. </div>
  42. <!-- 渲染平台工具类型 -->
  43. <div style="width: 100%;" @click.stop="goto(index,item)"
  44. v-else>
  45. <div class="ulTOne"
  46. v-for="(p,pin) in AppCon(item.url)" :key="pin+'p'">
  47. <div class="menu_left" @mouseenter="mouGet(item.toolId)" >
  48. <img class="logo"
  49. :src="activeL === (index +1) ? p.activeIcon : p.defaultIcon"
  50. alt="">
  51. <span class="barT" :style="{color : activeL === (index +1) ? '#0051D7' :''}">
  52. {{ p.name }}
  53. </span>
  54. </div>
  55. <!-- 二级导航 -->
  56. <div class="ulTCopy" v-if="item.toolId == 'appStore' && cocoFlowList[0] && cocoFlowList[1] && cocoFlowList[0].length && cocoFlowList[1].length">
  57. <div class="ulTCopyTit">
  58. <span>CocoFlow</span>
  59. </div>
  60. <div class="ulTCopyHei" >
  61. <span v-if="cocoFlowList[0] && cocoFlowList[0].length" style="color: #00000066;">最近使用</span>
  62. <div class="ulTCopyTxt"
  63. v-for="(i,ind) in cocoFlowList[0]"
  64. @click="openNewWindow(i.url)" :key="ind+'ab'">
  65. <div class="ulTCopyConT">{{ i.name }}</div>
  66. </div>
  67. <span v-if="cocoFlowList[0] && cocoFlowList[1].length" style="color: #00000066;">我的收藏</span>
  68. <div class="ulTCopyTxt"
  69. v-for="(i,ind) in cocoFlowList[1]" @click="openNewWindow(i.url)" :key="ind+'a'">
  70. <div class="ulTCopyConT">{{ i.name }}</div>
  71. </div>
  72. </div>
  73. </div>
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. </template>
  79. <script>
  80. import { mapGetters, mapActions } from 'vuex';
  81. import store from '../store'
  82. import { API_CONFIG } from "@/common/apiConfig";
  83. export default {
  84. props:['urlAddress'],
  85. computed: {
  86. ...mapGetters(['userinfo','userinfo2','fromL','appSign']),
  87. // 如果hk,com没有图标,默认使用cn的
  88. AppCon(){
  89. return function(c) {
  90. let k = JSON.parse(JSON.stringify(c))
  91. let data = k.filter(e=>{
  92. return e.region == this.roleUser.schoolArea || e.region == this.roleUser.orgArea
  93. })
  94. let data2 = k.filter(e=>{
  95. return e.region == 'cn'
  96. })
  97. // 如果hk,com没有图标,默认使用cn的
  98. if (!data[0].icon){
  99. data[0].icon = data2[0].icon
  100. data[0].activeIcon = data2[0].activeIcon
  101. }
  102. return data
  103. };
  104. },
  105. // 筛选是否为管理员可见,是否被删除
  106. appSignL(){
  107. return function(val){
  108. let data = []
  109. if (this.roleUser.type == 1 && this.roleUser.role == 1) {
  110. val.forEach( e =>{
  111. if (e.menuName || e.status == 0) {
  112. data.push(e)
  113. }
  114. })
  115. } else {
  116. val.forEach( e =>{
  117. if (e.menuName || (e.isAdmin == '0' && e.status == 0)) {
  118. data.push(e)
  119. }
  120. })
  121. }
  122. return data
  123. }
  124. },
  125. roleUser(){
  126. return Object.keys(this.userinfo2).length != 0 ? this.userinfo2 : this.userinfo
  127. }
  128. },
  129. data() {
  130. return {
  131. // 一级选中第几个
  132. activeL:0,
  133. visible:true,
  134. // 二级选中第几个
  135. activeLTwo: null,
  136. cocoFlowList:[],
  137. }
  138. },
  139. methods: {
  140. ...mapActions({
  141. logout: 'user/logout'
  142. }),
  143. // 跳转到看板
  144. gotoKanban(){
  145. let num = this.userinfo.type == 1 && this.userinfo.role == 1 && this.userinfo.rrole == 1 ? 1 : 2
  146. this.$router.push({
  147. path: '/KanBan',
  148. query: {
  149. index: num,
  150. }
  151. });
  152. },
  153. mouGet(val){
  154. if(val != 'appStore') return
  155. console.log('666')
  156. this.getData()
  157. },
  158. // 点击一级导航
  159. async goto(index,val = null){
  160. // console.log('goto',val);
  161. // val = null 就是点击了首页
  162. if (val) {
  163. this.activeL = index + 1
  164. }else{
  165. // 点击首页清空内容,并把标识去除
  166. await store.commit('user/SET_AppSIGN', '')
  167. this.$emit('update:urlAddress','')
  168. this.$emit('getPer')
  169. // 清空选中状态
  170. this.activeLTwo = ''
  171. this.activeL = index
  172. return
  173. }
  174. this.activeLTwo = ''
  175. // 点击相同应用不刷新
  176. if (this.appSign == val.toolId) return
  177. // 更新标识
  178. await store.commit('user/SET_AppSIGN', val.toolId)
  179. let url = ''
  180. // 查出对应账号的应用区域地址
  181. val.url.forEach(e => {
  182. // if (e.region == this.roleUser.schoolArea || e.region == this.roleUser.orgArea) {
  183. if (e.region == this.$region) {
  184. url = e.url
  185. }
  186. });
  187. let _userinfo = this.roleUser, //登录用户信息
  188. { userid: _userid, organizeid: _oid, type: _type, org: _org, role: _role, classid: _classId } = _userinfo; // 解构赋值获取用户信息
  189. const _TscreenType = 1, _SscreenType = 3; // 常量定义
  190. let queryString = ''
  191. if(val.argumentList && val.argumentList.length){
  192. const paramsMap = {
  193. userid: _userid,
  194. org: _org,
  195. oid: _oid,
  196. tType: _type,
  197. role: _role,
  198. classId: _classId,
  199. TscreenType: _TscreenType,
  200. SscreenType: _SscreenType
  201. };
  202. const canshu = val.argumentList
  203. .filter(param => paramsMap[param] !== undefined || param === 'type')
  204. .map(param => param === 'type' ? `tType=${paramsMap['tType']}` : `${param}=${paramsMap[param]}`);
  205. queryString = canshu.length ? (url.includes('?') ? '&' : '?') + canshu.join('&') : ''; // 生成查询字符串
  206. }
  207. let _url = url + queryString
  208. console.log('_url',_url);
  209. let kpl = ` <iframe
  210. allow= "camera *; microphone *;display-capture;midi;encrypted-media;"
  211. frameborder="no"
  212. border="0"
  213. style="border:0;width:100%;height:100%;"
  214. src="${_url}"
  215. ref="pageCon"
  216. >
  217. </iframe>`
  218. let pl = {json:kpl ,stateL :true,toolId :val.toolId}
  219. // 添加打开应用
  220. this.$emit('AddAppJson',pl)
  221. },
  222. // 获取cocoFlow收藏与历史使用记录
  223. getData(){
  224. let params = [
  225. {
  226. functionName: API_CONFIG.ajax_appStoreSave.functionName,
  227. uid: this.roleUser.userid,
  228. },
  229. ];
  230. this.$ajax
  231. .post(API_CONFIG.baseUrl, params)
  232. .then((res) => {
  233. this.cocoFlowList = []
  234. this.cocoFlowList.push(res.data[0])
  235. this.cocoFlowList.push(res.data[1])
  236. })
  237. .catch((err) => {
  238. console.log(err);
  239. this.$message.error("获取cocoFlow收藏与历史失败");
  240. });
  241. },
  242. // 点击二级导航
  243. async levTwo(val,index,aInd){
  244. this.activeL = ''
  245. this.activeL = aInd +1
  246. this.activeLTwo = `${aInd + 1}+${index}`
  247. // 点击相同应用不刷新
  248. if (this.appSign == val.toolId) return
  249. // 更新标识
  250. await store.commit('user/SET_AppSIGN', val.toolId)
  251. let url = ''
  252. val.url.forEach(e => {
  253. // if (e.region == this.roleUser.schoolArea || e.region == this.roleUser.orgArea) {
  254. if (e.region == this.$region) {
  255. url = e.url
  256. }
  257. });
  258. let _userinfo = this.roleUser, //登录用户信息
  259. { userid: _userid, organizeid: _oid, type: _type, org: _org, role: _role, classid: _classId } = _userinfo; // 解构赋值获取用户信息
  260. const _TscreenType = 1, _SscreenType = 3; // 常量定义
  261. let queryString = ''
  262. if(val.argumentList && val.argumentList.length){
  263. const paramsMap = {
  264. userid: _userid,
  265. org: _org,
  266. oid: _oid,
  267. tType: _type,
  268. role: _role,
  269. classId: _classId,
  270. TscreenType: _TscreenType,
  271. SscreenType: _SscreenType
  272. };
  273. const canshu = val.argumentList
  274. .filter(param => paramsMap[param] !== undefined || param === 'type')
  275. .map(param => param === 'type' ? `tType=${paramsMap['tType']}` : `${param}=${paramsMap[param]}`);
  276. queryString = canshu.length ? (url.includes('?') ? '&' : '?') + canshu.join('&') : ''; // 生成查询字符串
  277. }
  278. let _url = url + queryString
  279. console.log('_url',_url);
  280. let kpl = ` <iframe
  281. allow= "camera *; microphone *;display-capture;midi;encrypted-media;"
  282. frameborder="no"
  283. border="0"
  284. style="border:0;width:100%;height:100%;"
  285. src="${_url}"
  286. ref="pageCon"
  287. >
  288. </iframe>`
  289. let pl = {json:kpl ,stateL :true,toolId :val.toolId}
  290. this.$emit('AddAppJson',pl)
  291. },
  292. openNewWindow(val) {
  293. console.log(val);
  294. // // 基本用法:打开指定 URL
  295. window.open(val, "_blank");
  296. },
  297. },
  298. }
  299. </script>
  300. <style scoped>
  301. .ulTCopy{
  302. height: 90%;
  303. width: 154px;
  304. overflow: hidden;
  305. background-color: rgb(255 255 255 / 98%);
  306. border-radius: 12px;
  307. position: fixed;
  308. left: -75px;
  309. top: 70px;
  310. z-index: -100;
  311. transition: transform .5s ease;
  312. }
  313. .ulTOne:hover .ulTCopy{
  314. display: block !important;
  315. transform: translateX(164px) !important; /* 初始位置在视图之外 */
  316. z-index: -100;
  317. box-shadow: 0px 6px 30px 5px #0000000D;
  318. }
  319. .logo{
  320. margin: auto;
  321. width: 24px;
  322. height: 24px;
  323. }
  324. .iconW{
  325. width: 30px;
  326. height: 30px;
  327. display: flex;
  328. align-content: center;
  329. justify-content: center;
  330. padding: 1px;
  331. box-sizing: border-box;
  332. }
  333. .logo2 {
  334. cursor: pointer;
  335. box-sizing: border-box;
  336. width: 100%;
  337. background-color: #fff;
  338. text-align: center;
  339. }
  340. .logo2 img{
  341. width: 60px;
  342. height: 60px;
  343. }
  344. .userInfo{
  345. width: 80px;
  346. color: #374151;
  347. font-size: 12px;
  348. display: flex;
  349. flex-direction: column;
  350. align-items: center;
  351. padding: 8px;
  352. box-sizing: border-box;
  353. background-color: #fff;
  354. padding-bottom: 20px;
  355. }
  356. .left {
  357. font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important;
  358. width: 80px;
  359. height: 100%;
  360. padding:23px 6px;
  361. box-sizing: border-box;
  362. background-color: #ffffff;
  363. display: flex;
  364. flex-direction: column;
  365. align-items: center;
  366. gap: 24px;
  367. overflow: auto;
  368. border-right: 1px #D5D5D5 solid;
  369. }
  370. .ulTOne{
  371. width: 100%;
  372. border-radius: 10px;
  373. display: flex;
  374. height: 48px;
  375. flex-wrap:nowrap;
  376. align-content: center;
  377. justify-content: center;
  378. position: relative;
  379. }
  380. .barT{
  381. font-size:10px;
  382. overflow: hidden;
  383. white-space: nowrap;
  384. text-overflow: ellipsis;
  385. }
  386. .menu_left {
  387. width: 32px;
  388. height: 42px;
  389. font-size: 10px;
  390. color: #64748b;
  391. box-sizing: border-box;
  392. cursor: pointer;
  393. margin: auto;
  394. display: flex;
  395. flex-direction: column;
  396. align-items: center;
  397. gap: 2px;
  398. }
  399. .ulTCopyTit{
  400. font-family: PingFang SC;
  401. font-weight: 600;
  402. font-size: 12px;
  403. letter-spacing: 0px;
  404. color: #000;
  405. height: 40px;
  406. padding: 12px 16px;
  407. box-sizing: border-box;
  408. border-bottom: .5px #e5e7eb solid;
  409. background: #fff !important;
  410. }
  411. .ulTCopyHei{
  412. display: flex;flex-direction: column;
  413. gap: 10px;
  414. overflow: auto;
  415. padding: 10px;
  416. overflow-x: hidden;
  417. height: calc(100% - 72px);
  418. }
  419. .ulTCopyTxt{
  420. box-sizing: border-box;display: flex;
  421. align-items: center;
  422. color: #374151;
  423. width: 100%;
  424. border-radius: 10px;
  425. font-size: 16px;
  426. margin: 0;
  427. }
  428. .ulTCopyTxtBlock{
  429. width: 100%;
  430. }
  431. .ulTCopyConT {
  432. width: 100%;
  433. font-size: 12px;
  434. cursor: pointer;
  435. border-radius: 8px;
  436. padding: 8px;
  437. box-sizing: border-box;
  438. white-space: nowrap;
  439. overflow: hidden;
  440. text-overflow: ellipsis;
  441. }
  442. .ulTCopyConT:hover{
  443. background: #e7e7e7;
  444. color: #000;
  445. }
  446. .ulTCopyTxtCon{
  447. display: flex;align-items: center;width: 100%;
  448. }
  449. /* .ulTCopyTxt:hover{
  450. background-color: #f3f4f6 !important;
  451. } */
  452. .cha:hover{
  453. color: #000 !important;
  454. }
  455. .ovlH{
  456. overflow: hidden;
  457. white-space: nowrap;
  458. text-overflow: ellipsis;
  459. }
  460. </style>