TopMenu.vue 13 KB

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