TopMenu.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. <template>
  2. <div class="TopMenu">
  3. <div class="logo" @click="toIndex">
  4. <img :src="LOGO" alt="" />
  5. <span class="name">{{ TITLE }}</span>
  6. </div>
  7. <div class="menu">
  8. <div class="menuList">
  9. <div class="oneMenu finger" @click="openTab('我的文件', '/myfile')">
  10. <img src="@/assets/images/newIndex/users.png" alt="" />
  11. <span>我的文件</span>
  12. </div>
  13. <div class="oneMenu finger" @click="openTab('收藏文件', '/collect')">
  14. <img src="@/assets/images/newIndex/collect.png" alt="" />
  15. <span>收藏文件</span>
  16. </div>
  17. <div class="oneMenu finger" @click="showMoreMenu">
  18. <img src="@/assets/images/newIndex/more.png" alt="" />
  19. <span>更多</span>
  20. </div>
  21. </div>
  22. <div v-if="showMore" class="moreMenu">
  23. <div
  24. v-for="item in menuList"
  25. class="oneBox"
  26. :key="item.name"
  27. @click="openTab(item.name, item.path)"
  28. >
  29. <img :src="item.imgs" alt="" />
  30. <span>{{ item.name }}</span>
  31. </div>
  32. </div>
  33. </div>
  34. <div class="user">
  35. <div
  36. class="AIBot hand"
  37. v-if="showAi"
  38. @click="openTab('智聚AI', '/aipage')"
  39. >
  40. <img src="@/assets/images/newIndex/bot.png" alt="" />
  41. <span>智聚AI</span>
  42. </div>
  43. <!-- <img
  44. src="@/assets/images/newIndex/p2w.png"
  45. @click="openTab('Pdf转Word', '/camera')"
  46. class="hand"
  47. alt=""
  48. /> -->
  49. <img
  50. src="@/assets/images/newIndex/p2w.png"
  51. @click="openTab('Pdf转Word', '/pdf2word')"
  52. class="hand"
  53. alt=""
  54. />
  55. <img
  56. src="@/assets/images/newIndex/OCR.png"
  57. @click="openTab('文字识别', '/identifyFont')"
  58. class="hand"
  59. alt=""
  60. />
  61. <div class="clockBox">
  62. <img
  63. src="@/assets/images/newIndex/clock.png"
  64. @click="openTab('会话消息', '/chat')"
  65. class="hand"
  66. alt=""
  67. />
  68. <span class="yuandian" v-if="hasNewMessage"></span>
  69. </div>
  70. <img
  71. v-if="hasRole"
  72. src="@/assets/images/newIndex/setting.png"
  73. @click="openTab('系统管理', systemPath.path)"
  74. class="hand"
  75. alt=""
  76. />
  77. <div class="userInfo" @click="changeShowMenu">
  78. <span>{{ userStore.name }}</span>
  79. <img v-if="!showMenu" src="@/assets/images/newIndex/arrow.png" alt="" />
  80. <img
  81. v-else
  82. class="upArrow"
  83. src="@/assets/images/newIndex/arrow.png"
  84. alt=""
  85. />
  86. </div>
  87. <div class="menu" v-if="showMenu">
  88. <div class="oneBox hand" @click="openTab('个人中心', '/user/profile')">
  89. <img src="@/assets/images/newIndex/userInfo.png" alt="" />
  90. <span>个人中心</span>
  91. </div>
  92. <div class="oneBox hand" @click="logout">
  93. <img src="@/assets/images/newIndex/edit.png" alt="" />
  94. <span>退出登录</span>
  95. </div>
  96. </div>
  97. </div>
  98. </div>
  99. <!-- 扫描文档 -->
  100. <ScanFile
  101. v-if="openScan"
  102. :openScan="openScan"
  103. :scannerFiles="scannerFiles"
  104. @saveScanFile="saveScanFile"
  105. @closeOpen="closeOpen"
  106. ></ScanFile>
  107. <!-- 可用扫描仪信息 -->
  108. <div>
  109. <el-dialog v-model="checkScanner" title="扫描仪" width="30%">
  110. <div v-if="scannerList.length==0">请联系管理员先添加扫描仪设备</div>
  111. <div v-if="scannerList.length>0" style="margin-bottom: 10px;">请选择扫描仪设备</div>
  112. <div v-if="scannerList.length>0"
  113. v-for="item in scannerList"
  114. :key="item.scannerId"
  115. @click="checkScanFn(item)"
  116. id="Onescan"
  117. :class="checkScanId==item.scannerId?'hand Onescan checkScan':'hand Onescan'"
  118. >
  119. <img src="@/assets/images/scanImg.png" alt="" />
  120. {{ item.scannerName }}
  121. </div>
  122. <template #footer>
  123. <span class="dialog-footer">
  124. <el-button @click="closeCheckScanner">取消</el-button>
  125. <el-button v-if="scannerList.length>0" type="primary" @click="sureScaner">确认</el-button>
  126. </span>
  127. </template>
  128. </el-dialog>
  129. </div>
  130. <!-- 扫描文件移动到 -->
  131. <MoveTo
  132. v-if="openScanMove"
  133. :spaceType="3"
  134. :scanFileArr="scanFileArr"
  135. :thisFolder="thisFolder"
  136. :openScanMove="openScanMove"
  137. :spaceId="spaceId"
  138. @closeOpenScanMove="closeOpenScanMove"
  139. ></MoveTo>
  140. </template>
  141. <script setup>
  142. import {
  143. nextTick,
  144. onMounted,
  145. onBeforeMount,
  146. provide,
  147. ref,
  148. watchEffect,
  149. watch,
  150. } from "vue";
  151. import { canChat } from "@/api/chatglm/chatglm.js";
  152. import bebumen from "@/assets/images/bebumen.png";
  153. import common from "@/assets/images/becommon.png";
  154. import manyBody from "@/assets/images/manyBodyFalse.png";
  155. import useUserStore from "@/store/modules/user";
  156. import { ElMessage, ElLoading, ElMessageBox } from "element-plus";
  157. import ImgPreview from "@/components/ImgPreview/ImgPreview.vue";
  158. import { getConfigKey } from "@/api/system/config.js";
  159. import ScanFile from "@/components/ScanFile/ScanFile.vue";
  160. import MoveTo from "@/components/MoveTo/MoveTo.vue";
  161. import myfile from "@/api/myfile/myfile";
  162. import useWebsoctStore from "@/store/modules/websocket";
  163. import { listInfo, selectInfo, getFileByScanerId } from "@/api/scanner/info.js";
  164. const websoctStore = useWebsoctStore();
  165. const LOGO = import.meta.env.VITE_APP_LOGO;
  166. const TITLE = import.meta.env.VITE_APP_TITLE;
  167. const activeScannerClass=ref('hand Onescan')
  168. const menuList = ref([
  169. {
  170. name: "部门文件",
  171. icon: "@/assets/images/newIndex/users.png",
  172. path: "/department",
  173. imgs: bebumen,
  174. },
  175. {
  176. name: "公共文件",
  177. icon: "@/assets/images/newIndex/collect.png",
  178. path: "/publicment",
  179. imgs: common,
  180. },
  181. {
  182. name: "协作",
  183. icon: "@/assets/images/newIndex/more.png",
  184. path: "/myjoin",
  185. imgs: manyBody,
  186. },
  187. ]);
  188. const props = defineProps({
  189. systemPath: {
  190. type: Object,
  191. default: () => {},
  192. },
  193. hasRole: {
  194. type: Boolean,
  195. default: false,
  196. },
  197. });
  198. const userStore = useUserStore();
  199. const showMore = ref(false); // 是否显示更多菜单
  200. const showMenu = ref(false); // 是否显示用户菜单
  201. const scannerList = ref(); // 扫描仪数据
  202. const checkScanId = ref(); // 选中的scan的id
  203. const checkScanner = ref(false); //显示扫描仪选择框
  204. const scannerFiles = ref([]); //选择的扫描仪的文件
  205. const openScanMove = ref(false);
  206. const openScan = ref(false); //控制扫描文档显示
  207. const scanFileArr = ref([]); //认领的扫描文件数组
  208. const hasNewMessage = ref(false);
  209. const showAi = ref(false);
  210. const emit = defineEmits(["openMaxmin", "goIndex"]);
  211. // 鼠标移入 显示更多菜单
  212. const showMoreMenu = () => {
  213. if (!showMore.value) {
  214. setTimeout(() => {
  215. showMore.value = true;
  216. }, 200);
  217. }
  218. };
  219. const hideMoreMenu = () => {
  220. if (showMore.value) {
  221. setTimeout(() => {
  222. showMore.value = false;
  223. }, 0);
  224. }
  225. };
  226. //
  227. const changeShowMenu = () => {
  228. showMenu.value = true;
  229. };
  230. const hideShowMenu = () => {
  231. if (showMenu.value) {
  232. setTimeout(() => {
  233. showMenu.value = false;
  234. }, 0);
  235. }
  236. };
  237. //打开/新建标签
  238. const openTab = (title, path) => {
  239. emit("openMaxmin", title, path);
  240. };
  241. //logo点击事件 回到首页
  242. const toIndex = () => {
  243. emit("goIndex");
  244. };
  245. // 判断是否可以使用ai
  246. const canChatFn = async () => {
  247. const res = await canChat();
  248. showAi.value = res;
  249. };
  250. //退出
  251. function logout() {
  252. setTimeout(() => {
  253. var el = document.querySelector(".is-message-box");
  254. el.style.zIndex = 9999999;
  255. }, 200);
  256. ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
  257. confirmButtonText: "确定",
  258. cancelButtonText: "取消",
  259. type: "warning",
  260. customStyle: { zIndex: 9999999 },
  261. })
  262. .then(() => {
  263. sessionStorage.clear();
  264. localStorage.setItem("passArr", "");
  265. userStore.logOut().then(() => {
  266. location.href = "/index";
  267. });
  268. })
  269. .catch(() => {});
  270. }
  271. //获取扫描仪列表
  272. const scannerFile = async () => {
  273. const res = await selectInfo();
  274. scannerList.value = res.rows;
  275. checkScanner.value = true;
  276. checkScanId.value = scannerList.value.length>0 ? scannerList.value[0].scannerId : null;
  277. // console.log('scanner',res);
  278. };
  279. // 选择扫描仪
  280. const checkScanFn = (item) => {
  281. checkScanId.value = item.scannerId;
  282. };
  283. // 确认选择扫描仪 获取扫描仪下文件列表
  284. const sureScaner = async () => {
  285. if (!checkScanId.value) return;
  286. const res = await getFileByScanerId(checkScanId.value);
  287. // console.log("sureScanerres", res);
  288. scannerFiles.value = res.data;
  289. checkScanner.value = false;
  290. openScan.value = true;
  291. };
  292. // 关闭窗口
  293. const closeCheckScanner = () => {
  294. checkScanner.value = false;
  295. };
  296. const closeOpen = () => {
  297. openScan.value = false;
  298. };
  299. // 移动到事件
  300. const saveScanFile = (arr) => {
  301. // console.log("arr", arr);
  302. openScan.value = false;
  303. scanFileArr.value = arr;
  304. openScanMove.value = true;
  305. };
  306. // 关闭窗口
  307. const closeOpenScanMove = () => {
  308. openScanMove.value = false;
  309. // refreshFile();
  310. };
  311. let lisetenMessageTime = null;
  312. onMounted(() => {
  313. canChatFn();
  314. document.addEventListener("click", (e) => {
  315. if (e.target.className !== "oneMenu finger") {
  316. hideMoreMenu();
  317. }
  318. });
  319. window.addEventListener("click", hideShowMenu, true);
  320. //红点相关
  321. clearInterval(lisetenMessageTime);
  322. lisetenMessageTime = setInterval(() => {
  323. let tmplist = localStorage.getItem("noreadlist");
  324. if (tmplist == null || tmplist == "") {
  325. hasNewMessage.value = false;
  326. return;
  327. }
  328. tmplist = JSON.parse(tmplist);
  329. if (tmplist != null) hasNewMessage.value = true;
  330. else hasNewMessage.value = false;
  331. }, 1000);
  332. });
  333. watchEffect(async () => {
  334. if (websoctStore.noReadList != null) hasNewMessage.value = true;
  335. else hasNewMessage.value = false;
  336. // console.log("===============websoctStore.noReadList:",websoctStore.noReadList,'===========',hasNewMessage.value)
  337. });
  338. </script>
  339. <style lang="scss" scoped>
  340. .TopMenu {
  341. width: 100%;
  342. height: 80px;
  343. display: flex;
  344. justify-content: space-between;
  345. padding: 16px;
  346. // align-items: center;
  347. }
  348. .logo {
  349. width: 266px;
  350. height: 48px;
  351. cursor: pointer;
  352. display: flex;
  353. align-items: center;
  354. img {
  355. width: 66px;
  356. height: 100%;
  357. margin-right: 8px;
  358. }
  359. .name {
  360. font-size: 20px;
  361. font-family: Inter-LOGO;
  362. // line-height: 28px;
  363. color: #fff;
  364. }
  365. }
  366. .menu {
  367. width: 350px;
  368. height: 48px;
  369. position: relative;
  370. font-family: Inter-Medium;
  371. .menuList {
  372. width: 100%;
  373. height: 100%;
  374. display: flex;
  375. justify-content: space-around;
  376. .oneMenu {
  377. display: flex;
  378. align-items: center;
  379. span {
  380. color: #fff;
  381. font-size: 16px;
  382. // font-weight: bold;
  383. }
  384. }
  385. }
  386. .moreMenu {
  387. width: 250px;
  388. // height: 280px;
  389. background-color: #fff;
  390. border-radius: 12px;
  391. position: absolute;
  392. bottom: -110px;
  393. right: -130px;
  394. display: flex;
  395. font-size: 14px;
  396. color: #030102;
  397. // font-weight: 500;
  398. padding: 10px;
  399. justify-content: space-around;
  400. z-index: 1000000;
  401. .oneBox {
  402. width: 68px;
  403. height: 84px;
  404. border-radius: 8px 8px 8px 8px;
  405. display: flex;
  406. flex-direction: column;
  407. align-items: center;
  408. cursor: pointer;
  409. img {
  410. width: 48px;
  411. height: 48px;
  412. margin-top: 6px;
  413. // border: 1px solid #d0d6e6;
  414. border-radius: 8px 8px 8px 8px;
  415. }
  416. &:hover {
  417. background-color: #f5f7f9;
  418. }
  419. }
  420. }
  421. }
  422. .user {
  423. // width: 220px;
  424. height: 44px;
  425. position: relative;
  426. display: flex;
  427. justify-content: space-around;
  428. font-family: Inter-Medium;
  429. .clockBox {
  430. position: relative;
  431. .yuandian {
  432. width: 8px;
  433. height: 8px;
  434. position: absolute;
  435. right: 20px;
  436. top: 6px;
  437. background: #fa5151;
  438. border-radius: 4px;
  439. }
  440. }
  441. .AIBot {
  442. width: 105px;
  443. height: 44px;
  444. margin-right: 12px;
  445. padding: 10px;
  446. background: linear-gradient(96deg, #bddcff 0%, #d2f7ff 100%);
  447. border-radius: 8px 8px 8px 8px;
  448. display: flex;
  449. align-items: center;
  450. justify-content: space-between;
  451. img {
  452. width: 24px;
  453. height: 24px;
  454. }
  455. span {
  456. font-size: 16px;
  457. font-weight: 500;
  458. color: #464df8;
  459. }
  460. }
  461. img {
  462. margin-right: 12px;
  463. }
  464. .userInfo {
  465. width: 134px;
  466. height: 44px;
  467. border-radius: 51px;
  468. cursor: pointer;
  469. border: 1px solid #edf0fa;
  470. color: #fff;
  471. font-size: 16px;
  472. padding: 0 10px;
  473. display: flex;
  474. align-items: center;
  475. justify-content: space-between;
  476. .upArrow {
  477. transform: rotate(180deg);
  478. }
  479. }
  480. .menu {
  481. position: absolute;
  482. top: 120%;
  483. right: 0;
  484. width: 140px;
  485. height: 96px;
  486. padding: 8px;
  487. display: flex;
  488. flex-direction: column;
  489. align-items: center;
  490. justify-content: space-between;
  491. background: #ffffff;
  492. border-radius: 8px 8px 8px 8px;
  493. box-shadow: 0px 3px 26px 1px rgba(191, 191, 191, 0.25),
  494. 0px 2px 3px 0px rgba(210, 210, 210, 0.25);
  495. .oneBox {
  496. width: 110px;
  497. height: 36px;
  498. display: flex;
  499. padding: 0 8px;
  500. align-items: center;
  501. justify-content: space-between;
  502. .img {
  503. width: 20px;
  504. height: 20px;
  505. }
  506. span {
  507. font-weight: 500;
  508. font-size: 14px;
  509. color: #0d0f39;
  510. }
  511. &:hover {
  512. background: #f5f7f9;
  513. }
  514. }
  515. }
  516. }
  517. .finger {
  518. cursor: pointer;
  519. }
  520. .checkScan {
  521. background-color: #cbe5ff !important;
  522. border-bottom: 1px solid #9b9bdf;
  523. }
  524. .Onescan {
  525. height: 48px;
  526. line-height: 48px;
  527. font-size: 14px;
  528. display: flex;
  529. align-items: center;
  530. background-color: #f1f1f7;
  531. margin-bottom: 5px;
  532. }
  533. .hand {
  534. cursor: pointer;
  535. }
  536. :deep(.el-overlay) {
  537. z-index: 99999999 !important;
  538. }
  539. // 底部标签样式
  540. </style>