indexCommon.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119
  1. <template>
  2. <div class="common-layout">
  3. <el-container>
  4. <el-header class="nav" style="position: sticky; top: 0; left: 0; width: 100%; z-index: 999">
  5. <div class="nav-top">
  6. <div>
  7. <img class="logoImg" src="@/assets/images/logos.png" /><span>聚合智慧文档管理系统</span>
  8. </div>
  9. <div class="search">
  10. <el-input v-model="searchText" maxlength="32" class="w-50 m-2" size="small"
  11. placeholder="搜索文件" clearable @keyup.enter="toSearch">
  12. </el-input>
  13. <el-icon style="position: absolute;top: 15px;left: calc(100% - 40px);z-index: 1;color: white;" @click="toSearch">
  14. <Search />
  15. </el-icon>
  16. </div>
  17. <div>
  18. <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
  19. <div class="avatar-wrapper">
  20. <img :src="userStore.avatar
  21. ? userStore.avatar
  22. : '@/assets/images/profile.png'
  23. " class="head-img" /><span style="cursor: pointer;margin-right: 6px;">{{ userStore.name }}</span>
  24. <el-icon>
  25. <ArrowDown />
  26. </el-icon>
  27. </div>
  28. <template #dropdown>
  29. <el-dropdown-menu>
  30. <router-link to="/user/profile">
  31. <el-dropdown-item>个人中心</el-dropdown-item>
  32. </router-link>
  33. <el-dropdown-item divided command="logout">
  34. <span>退出登录</span>
  35. </el-dropdown-item>
  36. </el-dropdown-menu>
  37. </template>
  38. </el-dropdown>
  39. </div>
  40. </div>
  41. </el-header>
  42. <el-container>
  43. <el-aside width="92px" class="asides">
  44. <div class="aside-con">
  45. <router-link :to="item.path" v-for="(item, index) in menuList.data" :key="index"
  46. @click="clickPath(index, item)">
  47. <div style="position: relative" :class="$route.path == item.path
  48. ? 'acitve-img-style img-style'
  49. : 'img-style'
  50. ">
  51. <img :src="$route.path == item.path ? item.beimgs : item.imgs" />
  52. <div class="text-style" v-if="$route.path != item.path">
  53. {{ item.label }}
  54. </div>
  55. <span class="yuandian" v-if="hasNewMessage &&
  56. item.path == '/index' &&
  57. ($route.path != item.path || isSwitchFileIframe)
  58. "></span>
  59. </div>
  60. </router-link><br />
  61. </div>
  62. </el-aside>
  63. <el-main class="main">
  64. <div class="tab_box">
  65. <!-- <el-tabs
  66. v-model="editableTabsValue"
  67. @tab-change="clickTab"
  68. @tab-add="addTab"
  69. type="card"
  70. class="common-tabs"
  71. > -->
  72. <el-tabs v-model="editableTabsValue" @tab-add="addTab" type="card" class="common-tabs">
  73. <!-- <el-tab-pane label="首页" @click="clickTab('/index')"> </el-tab-pane> -->
  74. <el-tab-pane v-for="(item, index) in toRaw(editableTabs)" :key="item.path" :label="item.label"
  75. :name="item.path" :data-item="JSON.stringify(item)">
  76. <template #label>
  77. <div class="tab_pane" @click="paneClick(item)">
  78. <div class="tab_text">{{ item.label }}</div>
  79. <img v-if="item.label != '首页'" src="@/assets/images/close.png" @click="closeTab(item, index, $event)"
  80. alt="" />
  81. </div>
  82. <!-- <router-link
  83. :key="item"
  84. :data-path="item.path"
  85. :to="{
  86. path: item.path,
  87. query: { row: item.clickRowId },
  88. }"
  89. @click="paneClick(item)"
  90. class="tags-view-item"
  91. >
  92. {{ item.label }}
  93. </router-link> -->
  94. </template>
  95. </el-tab-pane>
  96. <!-- 文件的iframe -->
  97. <div v-for="item in iFrameData" :key="item.id">
  98. <el-tab-pane :label="item.name" :name="item.id" v-if="item.src">
  99. <template #label>
  100. <div class="tab_pane" @click="filePaneClick(item)">
  101. <div class="tab_text">{{ item.name }}</div>
  102. <img src="@/assets/images/close.png" @click="closeFileTab(item, index, $event)" alt="" />
  103. </div>
  104. </template>
  105. </el-tab-pane>
  106. </div>
  107. </el-tabs>
  108. </div>
  109. <div v-show="isAlive">
  110. <router-view v-slot="{ Component }" :key="$router.currentRoute.value.fullPath">
  111. <KeepAlive :exclude="['identifyFont', 'allback', 'search']">
  112. <component :is="Component" />
  113. </KeepAlive>
  114. </router-view>
  115. </div>
  116. <div v-show="!isAlive" style="width: 100%">
  117. <div v-for="item in iFrameData" :id="item.src" :key="item.src">
  118. <div style="width: 100%" v-show="item.show">
  119. <iframe :src="item.src" frameborder="0" :id="`iframe${item.id}`" :name="`iframe${item.id}`" width="100%"
  120. height="800px" class="iframeBox" ></iframe>
  121. </div>
  122. </div>
  123. </div>
  124. </el-main>
  125. </el-container>
  126. </el-container>
  127. </div>
  128. </template>
  129. <script setup>
  130. import { nextTick, onMounted, provide, ref, watchEffect, watch } from "vue";
  131. import { ElMessageBox, ElMessage } from "element-plus";
  132. import useAppStore from "@/store/modules/app";
  133. import useUserStore from "@/store/modules/user";
  134. import useSettingsStore from "@/store/modules/settings";
  135. import Cookies from "js-cookie";
  136. import chat from "@/assets/images/chat.png";
  137. import bechat from "@/assets/images/bechat.png";
  138. import zuijin from "@/assets/images/zuijin.png";
  139. import bezuijin from "@/assets/images/bezuijin.png";
  140. import colloect from "@/assets/images/colloect.png";
  141. import becolloect from "@/assets/images/becolloect.png";
  142. import system from "@/assets/images/system.png";
  143. import issystem from "@/assets/images/issystem.png";
  144. import my from "@/assets/images/my.png";
  145. import bemy from "@/assets/images/bemy.png";
  146. import bumen from "@/assets/images/bumen.png";
  147. import bebumen from "@/assets/images/bebumen.png";
  148. import common from "@/assets/images/common.png";
  149. import becommon from "@/assets/images/becommon.png";
  150. import chuanshu from "@/assets/images/chuanshu.png";
  151. import bechuanshu from "@/assets/images/bechuanshu.png";
  152. import highsearch from "@/assets/images/highsearch.png";
  153. import behighsearch from "@/assets/images/behighsearch.png";
  154. import manyBody from "@/assets/images/manyBody.png";
  155. import manyBodyFalse from "@/assets/images/manyBodyFalse.png";
  156. import { AppMain, Navbar, Settings, TagsView } from "./components";
  157. import { flieSearch } from "@/api/search/search.js";
  158. import { useRouter, useRoute } from "vue-router";
  159. import useWebsoctStore from "@/store/modules/websocket";
  160. import { toRaw } from "@vue/reactivity";
  161. import iFrame from "@/components/iFrame/index.vue";
  162. const websoctStore = useWebsoctStore();
  163. const router = useRouter(); //注册路由
  164. const route = useRoute();
  165. const appStore = useAppStore();
  166. const userStore = useUserStore();
  167. const settingsStore = useSettingsStore();
  168. const searchText = ref(""); //搜索ipt的值
  169. const selectValue = ref(1); //文档空间类型
  170. const wangzhi = import.meta.env.VITE_APP_BASE_API;
  171. const isAlive = ref(true);
  172. const toFileData = ref();
  173. const uid = useUserStore().uid;
  174. let hasNewMessage = ref(false)
  175. let isSwitchFileIframe = ref(false); //是否切换到文件预览标签
  176. const iFrameData = ref(JSON.parse(sessionStorage.getItem('fileTabData')) || [
  177. {
  178. id: 1,
  179. // src: `${window.location.origin}/fileEdit?clickRowId=113`,
  180. show: false,
  181. name: "file1",
  182. docId: ''
  183. },
  184. {
  185. id: 2,
  186. src: ``,
  187. // src: `http://192.168.1.9:81/fileEdit?clickRowId=1198`,
  188. show: false,
  189. name: "file2",
  190. docId: ''
  191. },
  192. {
  193. id: 3,
  194. src: ``,
  195. show: false,
  196. name: "",
  197. docId: ''
  198. },
  199. {
  200. id: 4,
  201. src: ``,
  202. show: false,
  203. name: "",
  204. docId: ''
  205. },
  206. {
  207. id: 5,
  208. src: ``,
  209. show: false,
  210. name: "",
  211. docId: ''
  212. },
  213. {
  214. id: 6,
  215. src: ``,
  216. show: false,
  217. name: "",
  218. docId: ''
  219. },
  220. {
  221. id: 7,
  222. src: ``,
  223. show: false,
  224. name: "",
  225. docId: ''
  226. },
  227. {
  228. id: 8,
  229. src: ``,
  230. show: false,
  231. name: "",
  232. docId: ''
  233. },
  234. {
  235. id: 9,
  236. src: ``,
  237. show: false,
  238. name: "",
  239. docId: ''
  240. },
  241. {
  242. id: 10,
  243. src: ``,
  244. show: false,
  245. name: "",
  246. docId: ''
  247. },
  248. ]);
  249. //--------tabs-----------------
  250. let tabIndex = 2;
  251. const editableTabsValue = ref(JSON.parse(sessionStorage.getItem('editableTabsValue')) || "/index");
  252. // const editableTabsValue = ref("/index");
  253. const editableTabs = ref(JSON.parse(sessionStorage.getItem('tabData')) || [{ label: '首页', path: '/reindex' }]);
  254. // const removeTab = (targetName) => {
  255. // const tabs = editableTabs.value;
  256. // let activeName = editableTabsValue.value;
  257. // if (activeName === targetName) {
  258. // tabs.forEach((tab, index) => {
  259. // if (tab.name === targetName) {
  260. // const nextTab = tabs[index + 1] || tabs[index - 1];
  261. // if (nextTab) {
  262. // activeName = nextTab.name;
  263. // }
  264. // }
  265. // });
  266. // }
  267. // editableTabsValue.value = activeName;
  268. // editableTabs.value = tabs.filter((tab) => tab.name !== targetName);
  269. // };
  270. //-------------------------
  271. function reload() {
  272. isAlive.value = false;
  273. nextTick(() => {
  274. isAlive.value = true;
  275. });
  276. }
  277. provide("reload", reload);
  278. function toggleSideBar() {
  279. appStore.toggleSideBar();
  280. }
  281. const logingName = ref("");
  282. let lisetenMessageTime = null;
  283. onMounted(() => {
  284. logingName.value = Cookies.get("username");
  285. clearInterval(lisetenMessageTime)
  286. lisetenMessageTime = setInterval(() => {
  287. //if(router.currentRoute.value.path=='/index') return;
  288. //console.log("===============window.noReadList:", localStorage.getItem("noreadlist"),'===========',isSwitchFileIframe.value)
  289. let tmplist = localStorage.getItem("noreadlist")
  290. if (tmplist == null || tmplist == '') {
  291. hasNewMessage.value = false
  292. return
  293. }
  294. tmplist = JSON.parse(tmplist);
  295. if (tmplist != null) hasNewMessage.value = true
  296. else hasNewMessage.value = false
  297. }, 1000);
  298. // console.log('onMt',editableTabsValue.value);
  299. // console.log('type',typeof editableTabsValue.value);
  300. nextTick(() => { // 要放在对响应式数据修改之后
  301. if (typeof editableTabsValue.value == 'number') {
  302. setTimeout(() => {
  303. iframeSize(editableTabsValue.value)
  304. }, 1000);
  305. }
  306. })
  307. // console.log('router',router)
  308. });
  309. watchEffect(async () => {
  310. if (router.currentRoute.value.path == '/index') return;
  311. if (websoctStore.noReadList != null) hasNewMessage.value = true
  312. else hasNewMessage.value = false
  313. // console.log("===============websoctStore.noReadList:",websoctStore.noReadList,'===========',hasNewMessage.value)
  314. });
  315. function handleCommand(command) {
  316. switch (command) {
  317. case "setLayout":
  318. setLayout();
  319. break;
  320. case "logout":
  321. logout();
  322. break;
  323. default:
  324. break;
  325. }
  326. }
  327. function logout() {
  328. ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
  329. confirmButtonText: "确定",
  330. cancelButtonText: "取消",
  331. type: "warning",
  332. })
  333. .then(() => {
  334. sessionStorage.clear()
  335. userStore.logOut().then(() => {
  336. location.href = "/index";
  337. });
  338. })
  339. .catch(() => { });
  340. }
  341. // 跳转到全文搜索
  342. const toSearch = async () => {
  343. if (!searchText.value) return;
  344. // console.log('searchText = ',searchText.value);
  345. const query = {
  346. keyword: searchText.value,
  347. isAsc: "asc",
  348. orderByColumn: "createTime",
  349. pageSize: 10,
  350. pageNum: 1,
  351. };
  352. const res = await flieSearch(query);
  353. console.log("res", res);
  354. if (res) {
  355. const itemData = {
  356. name: '全局搜索',
  357. path: 'search',
  358. clickRowId: {
  359. searchData: res,
  360. searchText: searchText.value,
  361. }
  362. }
  363. addFolderAdd(itemData)
  364. // console.log("res", res);
  365. // console.log("router", route.path);
  366. // if (route.path != "/search") {
  367. // let listArr = JSON.stringify(res);
  368. // router.push({
  369. // name: 'search',
  370. // params: {
  371. // listArr: listArr,
  372. // searchText: searchText.value
  373. // }
  374. // });
  375. // } else {
  376. // router.replace({
  377. // path: "/allback",
  378. // query: {
  379. // searchData: JSON.stringify(res),
  380. // searchText: searchText.value,
  381. // },
  382. // });
  383. // }
  384. }
  385. };
  386. const emits = defineEmits(["setLayout"]);
  387. function setLayout() {
  388. emits("setLayout");
  389. }
  390. const clickId = ref("");
  391. const menuList = reactive({
  392. data: [
  393. {
  394. label: "会话消息",
  395. path: "/index",
  396. imgs: chat,
  397. beimgs: bechat,
  398. },
  399. // {
  400. // label: "接口",
  401. // path: "/swagger",
  402. // imgs: chat,
  403. // beimgs: bechat,
  404. // disabled:true
  405. // },
  406. {
  407. label: "最近文件",
  408. path: "/recent",
  409. imgs: zuijin,
  410. beimgs: bezuijin,
  411. },
  412. {
  413. label: "收藏文件",
  414. path: "/collect",
  415. imgs: colloect,
  416. beimgs: becolloect,
  417. },
  418. {
  419. label: "我的文件",
  420. path: "/myfile",
  421. imgs: my,
  422. beimgs: bemy,
  423. },
  424. {
  425. label: "部门文件",
  426. path: "/department",
  427. imgs: bumen,
  428. beimgs: bebumen,
  429. },
  430. {
  431. label: "公共文件",
  432. path: "/publicment",
  433. imgs: common,
  434. beimgs: becommon,
  435. },
  436. {
  437. label: "高级搜索",
  438. path: "/highsearch",
  439. imgs: highsearch,
  440. beimgs: behighsearch,
  441. },
  442. // {
  443. // label: "传输列表",
  444. // path: "/transFile",
  445. // imgs: chuanshu,
  446. // beimgs: bechuanshu,
  447. // },
  448. // {
  449. // label: "系统管理",
  450. // path: "/admin",
  451. // imgs: system,
  452. // beimgs: issystem,
  453. // },
  454. {
  455. label: "我的协作",
  456. path: "/myjoin",
  457. imgs: manyBody,
  458. beimgs: manyBodyFalse,
  459. },
  460. ],
  461. });
  462. const roles = useUserStore().roles;
  463. const permissionRoles = ['admin', 'dept', 'system', 'audit']
  464. const super_admin = "admin";
  465. const hasRole = roles.some(role => {
  466. return super_admin === role || permissionRoles.includes(role)
  467. })
  468. if (hasRole) {
  469. menuList.data.push(
  470. {
  471. label: "系统管理",
  472. path: "/admin",
  473. imgs: system,
  474. beimgs: issystem,
  475. }
  476. );
  477. }
  478. const clickPath = (index, items) => {
  479. items = toRaw(items);
  480. localStorage.setItem("inChat", items.path == "/index" ? 1 : 0)
  481. // toFileData.value = null
  482. console.log("clickPathitems", items);
  483. // editableTabs.value = arr;
  484. isSwitchFileIframe.value = false
  485. const arr = toRaw(editableTabs.value);
  486. if (!arr.some((item) => item.label == items.label)) {
  487. editableTabs.value.push({
  488. label: items.label,
  489. path: items.path,
  490. });
  491. //需要jSON去转 否则页面无变化 离谱得很
  492. editableTabs.value = JSON.parse(JSON.stringify(editableTabs.value));
  493. } else {
  494. toFileData.value = null;
  495. clickTab(items.path);
  496. }
  497. editableTabsValue.value = items.path;
  498. isAlive.value = true;
  499. // console.log("editableTabs", editableTabs.value);
  500. };
  501. const clickTab = (item) => {
  502. let url = toRaw(item)
  503. setTimeout(() => {
  504. console.log("toFileData.value", toFileData.value);
  505. if (toFileData.value) {
  506. localStorage.setItem("inChat", 0)
  507. // 去全文搜索单独判断
  508. if (toFileData.value.name == "全局搜索" || toFileData.value.label == "全局搜索") {
  509. // console.log("clickRowId.value", JSON.stringify(toRaw(toFileData.value).clickRowId));
  510. editableTabsValue.value = toFileData.value.path
  511. isAlive.value = true
  512. console.log('route', route.path);
  513. // 如果当前已经在search就跳到中转页面
  514. if (route.path == "/search") {
  515. router.push({
  516. path: '/allback',
  517. query: {
  518. // row: JSON.stringify(toRaw(toFileData.value.clickRowId)),
  519. clickRowId: JSON.stringify(toRaw(toFileData.value).clickRowId),
  520. },
  521. });
  522. } else {
  523. // 否则去search
  524. router.push({
  525. name: toFileData.value.path,
  526. state: {
  527. // row: JSON.stringify(toRaw(toFileData.value.clickRowId)),
  528. clickRowId: JSON.stringify(toRaw(toFileData.value).clickRowId),
  529. },
  530. });
  531. }
  532. return
  533. }
  534. // 去文字识别单独判断
  535. if (toFileData.value.name == "文字识别" || toFileData.value.label == "文字识别") {
  536. // console.log("clickRowId.value", JSON.stringify(toRaw(toFileData.value).clickRowId));
  537. editableTabsValue.value = toFileData.value.path
  538. isAlive.value = true
  539. console.log('route', route.path);
  540. router.push({
  541. name: toFileData.value.path,
  542. state: {
  543. // row: JSON.stringify(toRaw(toFileData.value.clickRowId)),
  544. clickRowId: JSON.stringify(toRaw(toFileData.value).clickRowId),
  545. },
  546. });
  547. return
  548. }
  549. editableTabsValue.value = toFileData.value.path
  550. router.push({
  551. path: toFileData.value.path,
  552. query: {
  553. // row: JSON.stringify(toRaw(toFileData.value.clickRowId)),
  554. clickRowId: toRaw(toFileData.value.clickRowId).dirId,
  555. },
  556. });
  557. return;
  558. }
  559. localStorage.setItem("inChat", url == "/index" ? 1 : 0)
  560. let regExp = new RegExp(/^\//);
  561. if (!regExp.test(url)) {
  562. const data = JSON.parse(url);
  563. console.log("data", data);
  564. router.push({
  565. // path: "/fileEdit" + data.docId,
  566. path: "/fileEdit",
  567. query: {
  568. clickRowId: data.docId,
  569. // row:JSON.stringify(toFileData.value)
  570. // copyRow: JSON.stringify(data),
  571. },
  572. });
  573. } else {
  574. editableTabsValue.value = url
  575. router.push({
  576. path: item + '?dirId=' + item,
  577. });
  578. }
  579. }, 0);
  580. };
  581. const paneClick = (item) => {
  582. // 可以拿到当前的标签对象
  583. console.log(item, 'pane');
  584. isAlive.value = true;
  585. isSwitchFileIframe.value = false
  586. // console.log("paneItem", item);
  587. if (item.clickRowId) {
  588. // 判断是菜单还是目录
  589. toFileData.value = item;
  590. } else {
  591. toFileData.value = null;
  592. }
  593. clickTab(item.path);
  594. };
  595. // 点击文件标签
  596. const filePaneClick = (item) => {
  597. localStorage.setItem("inChat", 0)
  598. console.log("filePaneClickitem", item);
  599. isSwitchFileIframe.value = true
  600. const row = toRaw(item);
  601. const arr = iFrameData.value.map((par) => {
  602. if (par.id === row.id) {
  603. // editableTabsValue.value = row.id
  604. par.show = true;
  605. // document.getElementById('iframe'+par.id).window.document.iframe[0]
  606. const outIframe = document.getElementById("iframe" + par.id);
  607. const inIframe =
  608. outIframe.contentDocument.getElementsByTagName("iframe")[0];
  609. setTimeout(() => {
  610. // console.log('outIframe',outIframe.parentElement);
  611. console.error(outIframe.parentElement);
  612. inIframe.style.height = outIframe.style.height =
  613. outIframe.parentElement.offsetHeight + "px";
  614. inIframe.style.width = outIframe.style.width =
  615. outIframe.parentElement.offsetWidth + "px";
  616. // console.log('dom',outIframe.parentElement.offsetWidth);
  617. // console.log('inIframe',inIframe);
  618. }, 500);
  619. } else {
  620. par.show = false;
  621. }
  622. return toRaw(par);
  623. });
  624. iFrameData.value = arr;
  625. // console.log("Clicknewfilearr", iFrameData.value);
  626. isAlive.value = false;
  627. // console.log("editableTabsValue", editableTabsValue.value);
  628. };
  629. // 创建文件的标签
  630. const addFileTab = (data, bool,copy,history,fileId) => {
  631. // console.log("addFileTab", data);
  632. history = history?history:0
  633. const thisData = JSON.parse(JSON.stringify(toRaw(data)));
  634. const oldIFrameData = iFrameData.value;
  635. const canAdd = oldIFrameData.some((par) => par.src == ""); //是否达到上限
  636. if (!canAdd) return ElMessage.error("已到最大数量,请先关闭其他文件!");
  637. const hasThis = oldIFrameData.find((par) => par.docId == data.docId);//是否已存在
  638. if (hasThis) {
  639. // 已存在打开当前的并且改变编辑状态
  640. const thisPane = toRaw(hasThis)
  641. // 如果编辑状态改变了 先删除旧的 再新建
  642. if(thisPane.src != `${window.location.origin}/fileEdit?clickRowId=${thisData.docId}&canEdit=${bool}&canCopy=${copy}&history=${history}&fileId=${fileId}` ){
  643. // console.log('buyiyang',`${window.location.origin}/fileEdit?clickRowId=${thisData.docId}&canEdit=${bool}`);
  644. const arr = oldIFrameData.map((par) => {
  645. if (par.id === thisPane.id) {
  646. par.src = "";
  647. par.show = false;
  648. par.name = "";
  649. par.docId = ''
  650. }
  651. return toRaw(par);
  652. });
  653. iFrameData.value = arr.map((par) => {
  654. if (!par.src) {
  655. if (thisData.docId) {
  656. // par.src = `${window.location.origin}/fileEdit?clickRowId=${thisData.docId}`;
  657. par.src = `${window.location.origin}/fileEdit?clickRowId=${thisData.docId}&canEdit=${bool}&canCopy=${copy}&history=${history}&fileId=${fileId}`;
  658. par.name = data.fileName;
  659. par.docId = data.docId
  660. par.show = true
  661. thisData.docId = "";
  662. editableTabsValue.value = par.id// 新建时标签跳转
  663. setTimeout(() => {
  664. iframeSize(par.id,history)
  665. }, 1000);
  666. }
  667. } else {
  668. par.show = false
  669. }
  670. return toRaw(par);
  671. });
  672. isAlive.value = false;
  673. return
  674. }
  675. // console.log('hasThis',thisPane);
  676. const arr = oldIFrameData.map((par) => {
  677. if (par.id == thisPane.id) {
  678. `${window.location.origin}/fileEdit?clickRowId=${thisData.docId}&canEdit=${bool}&canCopy=${copy}&history=${history}&fileId=${fileId}`
  679. par.show = true
  680. editableTabsValue.value = par.id// 标签跳转
  681. setTimeout(() => {
  682. iframeSize(par.id,history)
  683. }, 1000);
  684. } else {
  685. par.show = false
  686. }
  687. return toRaw(par);
  688. });
  689. iFrameData.value = arr;
  690. isAlive.value = false;
  691. return
  692. }
  693. // 新增标签
  694. const arr = oldIFrameData.map((par) => {
  695. if (!par.src) {
  696. if (thisData.docId) {
  697. // par.src = `${window.location.origin}/fileEdit?clickRowId=${thisData.docId}`;
  698. par.src = `${window.location.origin}/fileEdit?clickRowId=${thisData.docId}&canEdit=${bool}&canCopy=${copy}&history=${history}&fileId=${fileId}`;
  699. par.name = data.fileName;
  700. par.docId = data.docId
  701. par.show = true
  702. thisData.docId = "";
  703. editableTabsValue.value = par.id// 新建时标签跳转
  704. setTimeout(() => {
  705. iframeSize(par,history)
  706. }, 1000);
  707. // console.log('open======');
  708. // window.open(`http://192.168.1.8:81/dev-api/api/history/655b0d360f078a3dc7fd19e4`)
  709. // window.open(`${window.location.origin}/fileEdit?clickRowId=${thisData.docId}&canEdit=${bool}&canCopy=${copy}&history=${history}&fileId=${fileId}`)
  710. }
  711. } else {
  712. par.show = false
  713. }
  714. return toRaw(par);
  715. });
  716. iFrameData.value = arr;
  717. isAlive.value = false;
  718. // console.log("addFileTab", arr);
  719. };
  720. //创建tab标签事件
  721. const addTab = (data) => {
  722. // console.log("addTab", data);
  723. const arr = toRaw(editableTabs.value);
  724. if (!arr.some((item) => item.label == data.fileName)) {
  725. // editableTabs.value.push({
  726. // label: data.fileName,
  727. // path: JSON.stringify(data),
  728. // });
  729. editableTabs.value.push({
  730. label: data.fileName,
  731. path: JSON.stringify(data),
  732. });
  733. //需要jSON去转 否则页面无变化 离谱得很
  734. editableTabs.value = JSON.parse(JSON.stringify(editableTabs.value));
  735. // editableTabsValue.value = data.path;
  736. }
  737. };
  738. const addFolderAdd = (data) => {
  739. const arr = toRaw(editableTabs.value);
  740. if (!arr.some((item) => item.label == data.clickRowId.dirName || item.label == data.name)) {
  741. editableTabs.value.push({
  742. label: data.name,
  743. path: data.path,
  744. clickRowId: data.clickRowId,
  745. });
  746. //需要jSON去转 否则页面无变化 离谱得很
  747. editableTabs.value = JSON.parse(JSON.stringify(editableTabs.value));
  748. }
  749. editableTabsValue.value = data.path
  750. toFileData.value = data
  751. clickTab(data)
  752. // console.log("editableTabs", toRaw(editableTabs.value));
  753. };
  754. provide("addTab", addTab);
  755. provide("addFolderAdd", addFolderAdd);
  756. provide("addFileTab", addFileTab);
  757. // TODO 删除tab事件
  758. const closeTab = (item, index, e) => {
  759. e.preventDefault();
  760. e.stopPropagation();
  761. editableTabs.value.splice(index, 1);
  762. editableTabs.value = JSON.parse(JSON.stringify(editableTabs.value));
  763. const nextTab = editableTabs.value[index - 1];
  764. // console.log('nextTab',toRaw(nextTab));
  765. // console.log('item',item);
  766. // console.log('editableTabsValue',editableTabsValue.value);
  767. if (editableTabsValue.value == item.path) {
  768. paneClick(toRaw(nextTab));
  769. }
  770. // console.log("item", item);
  771. // console.log("index", index);
  772. // console.log("e", e);
  773. };
  774. // TODO 删除tab事件
  775. const closeFileTab = (item, index, e) => {
  776. e.preventDefault();
  777. e.stopPropagation();
  778. const data = toRaw(item);
  779. let arr = iFrameData.value.map((par) => {
  780. if (par.id === data.id) {
  781. par.src = "";
  782. par.show = false;
  783. par.name = "";
  784. par.docId = ''
  785. }
  786. return toRaw(par);
  787. });
  788. if (data.id == editableTabsValue.value) {
  789. let isLeft = true
  790. //如果不是第一个就左移
  791. for (let thisId = data.id; thisId > 0; thisId--) {
  792. // console.log(arr[thisId - 1].id, arr[thisId - 1].src);
  793. if (arr[thisId - 1].src) {
  794. arr[thisId - 1].show = true
  795. isLeft = false
  796. editableTabsValue.value = arr[thisId - 1].id
  797. return
  798. }
  799. }
  800. // 如果是第一个就跳到文件夹标签右一
  801. if (isLeft) {
  802. const num = toRaw(editableTabs.value).length - 1
  803. const nextTab = editableTabs.value[num]
  804. paneClick(toRaw(nextTab));
  805. // console.log('left', nextTab);
  806. }
  807. // isAlive.value = true;
  808. }
  809. iFrameData.value = arr;
  810. // console.log("index", index);
  811. // console.log("iFrameData", iFrameData.value);
  812. };
  813. // 控制iframe大小
  814. const iframeSize = (par,history) => {
  815. const outIframe = document.getElementById("iframe" + par.id);
  816. const inIframe =
  817. outIframe.contentDocument.getElementsByTagName("iframe")[0];
  818. // console.log('outIframe', outIframe.parentElement);
  819. // console.error(outIframe.parentElement);
  820. inIframe.style.height = outIframe.style.height =
  821. outIframe.parentElement.offsetHeight + "px";
  822. inIframe.style.width = outIframe.style.width =
  823. outIframe.parentElement.offsetWidth + "px";
  824. // if(history){
  825. // var widgetIFrameParent = inIframe.parentNode;
  826. // outIframe.remove();
  827. // // widgetIFrameParent.append("<iframe id=\"widgetIFrame\" style=\"width: 100%;height: 600px\" src=\"\"></iframe>");
  828. // widgetIFrameParent.append("<iframe :src=\"item.src\" frameborder=\"0\" :id=\"`iframe${item.id}`\" :name=\"`iframe${item.id}`\" width=\"100%\" height=\"800px\" class=\"iframeBox\" ></iframe>");
  829. // var widgetIFrameNew = document.getElementById("iframe" + par.id);
  830. // // widgetIFrameNew.attr('src',encodeURI(par.src));
  831. // // widgetIFrameNew.css('width',"100%")
  832. // }
  833. // console.log('dom',outIframe.parentElement.offsetWidth);
  834. // console.log('inIframe',inIframe);
  835. }
  836. // 监听和保存标签信息
  837. const setTabLocal = (data) => {
  838. // console.log('setTabLocal',data);
  839. sessionStorage.setItem('tabData', JSON.stringify(data))
  840. }
  841. const setFileTabLocal = (data) => {
  842. console.log('setFileTabLocal', data);
  843. isSwitchFileIframe.value = true
  844. // console.log('setFileTabLocal',data);
  845. sessionStorage.setItem('fileTabData', JSON.stringify(data))
  846. }
  847. const setEditableTabsValue = (data) => {
  848. // console.log('setEditableTabsValue',data);
  849. sessionStorage.setItem('editableTabsValue', JSON.stringify(data))
  850. }
  851. watch(() => iFrameData.value, (newValue, oldValue) => {
  852. // console.log('iFrameData 发生改变了', newValue, oldValue);
  853. setFileTabLocal(toRaw(toRaw(newValue)))
  854. }, {
  855. immediate: true,
  856. deep: true
  857. });
  858. watch(() => editableTabs.value, (newValue, oldValue) => {
  859. // console.log('editableTabs 发生改变了', newValue, oldValue);
  860. setTabLocal(toRaw(newValue))
  861. }, {
  862. immediate: true,
  863. deep: true
  864. });
  865. watch(() => editableTabsValue.value, (newValue, oldValue) => {
  866. // console.log('editableTabsValue 发生改变了', newValue, oldValue);
  867. setEditableTabsValue(toRaw(newValue))
  868. let regExp = new RegExp(/^\//);
  869. if (!regExp.test(editableTabsValue.value)) {
  870. isAlive.value = false;
  871. }
  872. }, {
  873. immediate: true,
  874. deep: true
  875. });
  876. </script>
  877. <style lang="scss" scoped>
  878. @import "@/assets/styles/mixin.scss";
  879. @import "@/assets/styles/variables.module.scss";
  880. //整体布局css
  881. .common-layout,
  882. .el-container {
  883. height: 94vh;
  884. }
  885. :deep .el-main {
  886. --el-main-padding: 8px !important;
  887. }
  888. .nav {
  889. background: #06286c;
  890. height: 48px;
  891. .nav-top {
  892. width: 98%;
  893. display: flex;
  894. justify-content: space-between;
  895. &>div:first-child {
  896. font-family: "Inter-SemiBold";
  897. }
  898. &>div:first-child,
  899. &>div:last-child {
  900. display: flex;
  901. align-items: center;
  902. color: #fff;
  903. &>img {
  904. width: 48px;
  905. height: 48px;
  906. }
  907. }
  908. .logoImg {
  909. width: 150px !important;
  910. height: 100%;
  911. margin-right: 10px;
  912. }
  913. }
  914. .head-img {
  915. border-radius: 12px;
  916. width: 24px;
  917. height: 24px;
  918. margin-right: 10px;
  919. }
  920. .avatar-wrapper {
  921. color: #fff;
  922. display: flex;
  923. align-items: center;
  924. }
  925. .search {
  926. position: relative;
  927. .w-50,
  928. :deep .el-input {
  929. width: 400px;
  930. height: 32px;
  931. border-radius: 4px;
  932. margin-top: 8px;
  933. background: #6f85b5 !important;
  934. --el-input-border-color: #6f85b5;
  935. }
  936. ::v-deep .el-input__inner {
  937. color: #fff !important;
  938. }
  939. }
  940. :deep .el-input__wrapper {
  941. background: #1f3f7e !important;
  942. }
  943. }
  944. .asides {
  945. padding: 8px 10px !important;
  946. font-size: 14px;
  947. color: #000;
  948. background: #fff;
  949. }
  950. .main {
  951. background: #c7cbd8;
  952. }
  953. // tabs标签
  954. .tab_box {
  955. width: 100%;
  956. height: 32px;
  957. border-radius: 4px 4px 4px 4px;
  958. background-color: #fff;
  959. margin-bottom: 8px;
  960. .common-tabs {
  961. height: 32px;
  962. // display: flex;
  963. // align-items: center;
  964. }
  965. .tab_pane {
  966. display: flex;
  967. align-items: center;
  968. justify-content: space-between;
  969. img {
  970. margin-left: 8px;
  971. width: 10px;
  972. height: 10px;
  973. }
  974. }
  975. }
  976. :deep(.common-tabs .el-tabs__item) {
  977. height: 24px !important;
  978. padding: 0px 8px !important;
  979. margin-top: 4px !important;
  980. margin-left: 4px !important;
  981. border: 1px solid #c1cce3 !important;
  982. color: #505870 !important;
  983. font-size: 12px !important;
  984. line-height: 24px;
  985. font-weight: 400 !important;
  986. }
  987. // tag选中颜色
  988. :deep(.common-tabs .el-tabs__item.is-active) {
  989. color: #fff !important;
  990. font-weight: normal;
  991. background-color: #6f85b5;
  992. }
  993. //侧边栏css
  994. .acitve-img-style {
  995. background-color: #f5f7f9;
  996. border-radius: 4px;
  997. }
  998. .img-style {
  999. width: 72px;
  1000. height: 72px;
  1001. display: flex;
  1002. margin-bottom: 8px;
  1003. flex-direction: column;
  1004. align-items: center;
  1005. justify-content: center;
  1006. &>img {
  1007. width: 40px;
  1008. height: 40px;
  1009. }
  1010. }
  1011. .text-style {
  1012. text-align: center;
  1013. color: #000;
  1014. }
  1015. </style>
  1016. <style lang="scss" scoped>
  1017. .el-popper.is-light.type_popper {
  1018. background-color: #1f3f7e !important;
  1019. border-radius: 4px 4px 4px 4px !important;
  1020. border: none !important;
  1021. // padding: 0 16px !important;
  1022. // box-sizing: border-box !important;
  1023. }
  1024. .el-popper__arrow::before {
  1025. content: none;
  1026. }
  1027. //鼠标移动上去的选中色
  1028. .type_popper {
  1029. .el-select-dropdown__item.hover,
  1030. .el-select-dropdown__item:hover {
  1031. background: #6f85b5 !important;
  1032. }
  1033. //下拉框的文本颜色
  1034. .el-select-dropdown__item {
  1035. color: #a4b0d8 !important;
  1036. }
  1037. //选中之后的颜色
  1038. .el-select-dropdown__item.selected {
  1039. background: #6f85b5 !important;
  1040. color: #fff !important;
  1041. }
  1042. }
  1043. .yuandian {
  1044. width: 8px;
  1045. height: 8px;
  1046. position: absolute;
  1047. right: 8px;
  1048. top: 6px;
  1049. background: #fa5151;
  1050. border-radius: 4px;
  1051. }
  1052. ::v-deep .qualityManual-container-office {
  1053. width: 1000px !important;
  1054. height: 1000px !important;
  1055. iframe {
  1056. width: 1000px !important;
  1057. height: 1000px !important;
  1058. }
  1059. }
  1060. :deep(.el-tabs--card>.el-tabs__header) {
  1061. border-bottom: none !important;
  1062. }
  1063. </style>