index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. <template>
  2. <!-- 右侧固定栏 -->
  3. <div
  4. class="v-widget-window syno-sds-widget v-window"
  5. style="
  6. position: absolute;
  7. width: 344px;
  8. height: 466px;
  9. min-height: 165px !important;
  10. "
  11. :style="{
  12. zIndex: fixWindowMessage.zIndex,
  13. display: fixWindowMessage.display,
  14. top: top ? top : '',
  15. bottom: bottom ? bottom : '',
  16. left: left ? left : '',
  17. right: right ? right : '',
  18. }"
  19. :class="fixWindowMessage.cls"
  20. @click.capture="clickFixWindow"
  21. >
  22. <div
  23. class="v-window-header-wrapper draggable"
  24. @mousedown="mousedownWidgetHeader"
  25. >
  26. <div class="v-widget-header">
  27. <div class="v-widget-header-left">
  28. <button
  29. type="button"
  30. class="v-btn v-btn-styleless v-btn-grey v-btn-dropdown"
  31. >
  32. <span>
  33. <div
  34. class="v-widget-header-tool-icon add"
  35. @click.capture="selectWidgetItem"
  36. ></div>
  37. </span>
  38. </button>
  39. </div>
  40. <div class="v-widget-header-right">
  41. <div
  42. class="v-widget-header-tool-icon minimize"
  43. @click.capture="minimizeFixWndow"
  44. ></div>
  45. <div
  46. class="v-widget-header-tool-icon pin"
  47. @click.capture="pinFixWndow"
  48. ></div>
  49. <button
  50. type="button"
  51. class="v-btn v-btn-styleless v-btn-grey v-btn-dropdown"
  52. >
  53. <span>
  54. <div
  55. class="v-widget-header-tool-icon dock"
  56. @click.capture="selectWidgetPosition"
  57. ></div>
  58. </span>
  59. </button>
  60. </div>
  61. </div>
  62. </div>
  63. <div tabindex="-1" class="v-window-body">
  64. <div tabindex="0" class="v-trap-focus-indicator"></div>
  65. <div class="v-trap-focus-body">
  66. <div
  67. tabindex="0"
  68. role="application"
  69. class="v-trap-focus-indicator"
  70. ></div>
  71. <div class="v-widget-items-wrapper">
  72. <div
  73. class="v-ps show ps--active-y"
  74. @scroll="scrollList"
  75. style="overflow: scroll"
  76. >
  77. <!-- <div class="v-widget-list" style="overflow-y:scroll;height:100%" @scroll="scrollList"> -->
  78. <div class="v-widget-list">
  79. <RunningState></RunningState>
  80. <ResourceMonitor></ResourceMonitor>
  81. <Storage></Storage>
  82. <ConnectedUser></ConnectedUser>
  83. <ScheduledTask></ScheduledTask>
  84. <ChangeLog></ChangeLog>
  85. <NewLog></NewLog>
  86. <Copy></Copy>
  87. <!-- 当打开窗口个数为零时显示 -->
  88. <!-- <div class="v-widget-list-empty" :style="{display: selectedNum ? 'none':'flex'}"> -->
  89. <div class="v-widget-list-empty" v-show="!selectedNum">
  90. <div class="v-widget-list-empty-img"></div>
  91. <div class="v-widget-list-empty-content">
  92. 单击 + 按钮可添加小工具。
  93. </div>
  94. </div>
  95. </div>
  96. <div class="ps__rail-x" style="left: 0px; bottom: 0px">
  97. <div
  98. class="ps__thumb-x"
  99. tabindex="0"
  100. style="left: 0px; width: 0px"
  101. ></div>
  102. </div>
  103. <div class="ps__rail-y" style="top: 0px; right: 0px; height: 424px">
  104. <div
  105. class="ps__thumb-y"
  106. tabindex="0"
  107. style="top: 0px"
  108. :style="{ height: thumbYHeight, display: thumbYDisplay }"
  109. @mousedown="mousedownProgress"
  110. ></div>
  111. </div>
  112. </div>
  113. </div>
  114. </div>
  115. <div tabindex="0" class="v-trap-focus-indicator"></div>
  116. </div>
  117. <div class="v-window-resizable">
  118. <div class="handler v-window-resizable-n"></div>
  119. <div class="handler v-window-resizable-s"></div>
  120. </div>
  121. <!-- 弹出小窗口选择框 -->
  122. <PortalSelectDialogWindow></PortalSelectDialogWindow>
  123. <!-- 弹出位置选择框 -->
  124. <PortaSelectPosition></PortaSelectPosition>
  125. </div>
  126. </template>
  127. <script>
  128. import RunningState from "./RunningState";
  129. import ResourceMonitor from "./ResourceMonitor";
  130. import Storage from "./Storage";
  131. import ConnectedUser from "./ConnectedUser";
  132. import ScheduledTask from "./ScheduledTask";
  133. import ChangeLog from "./ChangeLog";
  134. import NewLog from "./NewLog";
  135. import Copy from "./Copy";
  136. // 弹出小窗口选择框
  137. import PortalSelectDialogWindow from "../PortalSelectDialogWindow";
  138. // 弹出位置选择框
  139. import PortaSelectPosition from "../PortaSelectPosition";
  140. export default {
  141. props: ["defaultZIndex", "fixWindowData"],
  142. data() {
  143. return {
  144. fixWindowMessage: {
  145. zIndex: 9050,
  146. display: "block",
  147. cls: "deactive-win",
  148. },
  149. selectedNum: 2,
  150. display: "block",
  151. top: 0,
  152. bottom: '10px',
  153. right: 0,
  154. left: '220px',
  155. // widgetZindexIsMax: false,
  156. progrecssFirstClick: {
  157. lastY: 0,
  158. clickY: 0,
  159. clientY: 0,
  160. moveY: 0,
  161. thumbStyletop: 0,
  162. },
  163. widgetFirstClick: {
  164. layerX: 0,
  165. layerY: 0,
  166. screenX: 0,
  167. screenY: 0,
  168. },
  169. widgetListIsBottom: false,
  170. thumbYHeight: "424px",
  171. thumbYDisplay: "none",
  172. portalDetail: {
  173. display: "none",
  174. detailMessageList: [
  175. {
  176. id: 0,
  177. title: "系统状况",
  178. cls: "v-menu-item-select-selected selected active",
  179. },
  180. {
  181. id: 1,
  182. title: "资源监控",
  183. cls: "v-menu-item-select-selected selected",
  184. },
  185. {
  186. id: 2,
  187. title: "存储",
  188. cls: "",
  189. },
  190. {
  191. id: 3,
  192. title: "已连接用户",
  193. cls: "",
  194. },
  195. {
  196. id: 4,
  197. title: "计划的任务",
  198. cls: "",
  199. },
  200. {
  201. id: 5,
  202. title: "文件更改日志",
  203. cls: "",
  204. },
  205. {
  206. id: 6,
  207. title: "最新日志",
  208. cls: "",
  209. },
  210. {
  211. id: 7,
  212. title: "备份",
  213. cls: "",
  214. },
  215. ],
  216. },
  217. portalDetail1: {
  218. display: "none",
  219. detailMessageList: [
  220. {
  221. id: 0,
  222. title: "右上角",
  223. cls: "active",
  224. top: "47px",
  225. bottom: 0,
  226. left: 0,
  227. right: "10px",
  228. },
  229. {
  230. id: 1,
  231. title: "右下角",
  232. cls: "v-menu-item-select-selected selected",
  233. top: 0,
  234. bottom: "10px",
  235. left: 0,
  236. right: "10px",
  237. },
  238. {
  239. id: 2,
  240. title: "左上角",
  241. top: "47px",
  242. bottom: 0,
  243. right: 0,
  244. left: "10px",
  245. cls: "",
  246. },
  247. {
  248. id: 3,
  249. title: "左下角",
  250. top: 0,
  251. bottom: "10px",
  252. left: "10px",
  253. right: 0,
  254. cls: "",
  255. },
  256. ],
  257. },
  258. };
  259. },
  260. components: {
  261. RunningState,
  262. ResourceMonitor,
  263. Storage,
  264. ConnectedUser,
  265. ScheduledTask,
  266. ChangeLog,
  267. NewLog,
  268. Copy,
  269. // 弹出小窗口选择框
  270. PortalSelectDialogWindow,
  271. // 弹出位置选择框
  272. PortaSelectPosition,
  273. },
  274. mounted() {
  275. this.$bus.on("showOrHiddenWidgetItem", this.showOrHiddenWidgetItem);
  276. this.$bus.on("changeThumbHeight", this.changeThumbHeight);
  277. this.$bus.on("showOrHiddenWidget", this.showOrHiddenWidget);
  278. this.$bus.on("changeWidgetPosition", this.changeWidgetPosition);
  279. this.$bus.on('closeWidgetItem',this.closeWidgetItem)
  280. this.fixWindowMessage = this.fixWindowData;
  281. let el = document.querySelector(".v-widget-window .ps__thumb-y");
  282. let el1 = document.querySelector(
  283. ".v-widget-window .v-window-header-wrapper"
  284. );
  285. el.addEventListener("mouseup", this.mouseupProgress);
  286. el1.addEventListener("mouseup", this.mouseupWidgetHeader);
  287. let el2 = document.querySelector(".v-widget-window .v-widget-list");
  288. let el3 = document.querySelector(".v-widget-window .ps__rail-y");
  289. let el4 = document.querySelector(".v-widget-window");
  290. if (el2.offsetHeight > el3.offsetHeight) {
  291. this.top = 0;
  292. this.bottom = 0;
  293. this.thumbYDisplay = "block";
  294. this.thumbYHeight = "calc((100vh - 52px) / 2)";
  295. }
  296. setTimeout(()=>{
  297. this.left = 0
  298. this.right = '10px'
  299. },400)
  300. window.addEventListener("resize", (e) => {
  301. if (el2.offsetHeight > el3.offsetHeight) {
  302. this.thumbYDisplay = "block";
  303. this.thumbYHeight = "calc((100vh - 52px) / 2)";
  304. } else {
  305. this.thumbYDisplay = "none";
  306. }
  307. let left = document.documentElement.clientWidth - el4.offsetWidth
  308. if(left >= 0 && left < el4.offsetWidth){
  309. this.left = left + 'px'
  310. }else if(left < 0) {
  311. this.left = 0
  312. }
  313. });
  314. },
  315. methods: {
  316. //点击固定窗口
  317. clickFixWindow() {
  318. if (this.fixWindowMessage.cls !== "active-win") {
  319. this.fixWindowMessage.zIndex = this.defaultZIndex + 10;
  320. this.$bus.emit("changeDefaultZIndex", this.defaultZIndex + 10);
  321. this.$bus.emit("fixWindowZIndexMax", true);
  322. }
  323. },
  324. //点击进度条
  325. mousedownProgress(e) {
  326. let el = document.querySelector(".v-widget-window .ps__thumb-y");
  327. let el1 = document.querySelector(".v-widget-window");
  328. el.addEventListener("mousemove", this.moveProgress);
  329. if (el.style.top && el.style.top.includes("px")) {
  330. let top = parseInt(el.style.top.replace("px", ""));
  331. this.progrecssFirstClick.thumbStyletop = top;
  332. }
  333. this.progrecssFirstClick.lastY = el1.offsetTop + 31;
  334. this.progrecssFirstClick.clickY = e.offsetY;
  335. },
  336. //移动进度条
  337. moveProgress(e) {
  338. let el = document.querySelector(".v-widget-window .ps__thumb-y");
  339. let el1 = document.querySelector(".v-widget-window .ps__rail-y");
  340. let el2 = document.querySelector(".v-widget-window .v-widget-list");
  341. let moveY;
  342. if (e.clientY >= this.progrecssFirstClick.clientY) {
  343. moveY = e.clientY - e.offsetY - this.progrecssFirstClick.lastY;
  344. if (this.progrecssFirstClick.thumbStyletop) {
  345. moveY = this.progrecssFirstClick.thumbStyletop + 1;
  346. this.progrecssFirstClick.thumbStyletop = 0;
  347. }
  348. } else {
  349. moveY = this.moveY + (e.clientY - this.progrecssFirstClick.clientY);
  350. if (this.progrecssFirstClick.thumbStyletop) {
  351. moveY = this.progrecssFirstClick.thumbStyletop + 1;
  352. this.progrecssFirstClick.thumbStyletop = 0;
  353. }
  354. }
  355. if (moveY < 0) {
  356. moveY = 0;
  357. } else if (moveY > el1.offsetHeight - el.offsetHeight) {
  358. moveY = el1.offsetHeight - el.offsetHeight;
  359. this.widgetListIsBottom = true;
  360. }
  361. let moveY2 =
  362. -(
  363. (el2.offsetHeight - el1.offsetHeight) /
  364. (el1.offsetHeight - el.offsetHeight)
  365. ) * moveY;
  366. console.log(moveY)
  367. el.style.top = moveY + "px";
  368. el2.style.top = moveY2 + "px";
  369. el.addEventListener("mouseup", this.mouseupProgress);
  370. el1.addEventListener("mouseleave", this.mouseupProgress);
  371. this.progrecssFirstClick.clientY = e.clientY;
  372. this.moveY = moveY;
  373. },
  374. // 进度条鼠标抬起/离开
  375. mouseupProgress() {
  376. let el = document.querySelector(".v-widget-window .ps__thumb-y");
  377. el.removeEventListener("mousemove", this.moveProgress);
  378. },
  379. // 滚动窗口列表
  380. scrollList(e) {
  381. let el = document.querySelector(".v-widget-window .ps__thumb-y");
  382. let el1 = document.querySelector(".v-widget-window .ps__rail-y");
  383. let el2 = document.querySelector(".v-widget-window .ps--active-y");
  384. let moveY =
  385. ((el1.offsetHeight - el.offsetHeight) /
  386. (e.target.scrollHeight - el2.offsetHeight)) *
  387. e.target.scrollTop;
  388. el.style.top = moveY + e.target.scrollTop + "px";
  389. console.log(moveY,el.style.top)
  390. },
  391. // 点击勾选小窗口的加号
  392. selectWidgetItem() {
  393. this.$bus.emit("showOrHiddenSelectWidgetItem", this.portalDetail);
  394. },
  395. // 点击小窗口选择框的每一项
  396. showOrHiddenWidgetItem(obj) {
  397. this.portalDetail.detailMessageList[obj.index].cls = obj.cls1;
  398. this.portalDetail.detailMessageList.forEach((item, index) => {
  399. if (item.cls && item.cls.includes("active") && index !== 0) {
  400. item.cls = item.cls.replace("active", "");
  401. }
  402. });
  403. },
  404. // 跟随可视小窗口的个数改变进度条高度
  405. changeThumbHeight(selectedNum) {
  406. let el1 = document.querySelector(".v-widget-window .v-widget-list");
  407. let el2 = document.querySelector(".v-widget-window .ps__rail-y");
  408. this.$nextTick(()=>{
  409. this.$nextTick(()=>{
  410. if (el1.offsetHeight > el2.offsetHeight) {
  411. if (selectedNum >= 6) {
  412. selectedNum = 6;
  413. }
  414. this.thumbYDisplay = "block";
  415. if(el2.offsetHeight > (7 - selectedNum) * 70){
  416. this.thumbYHeight = (7 - selectedNum) * 70 + "px";
  417. }else{
  418. this.thumbYHeight = "calc((100vh - 52px) / 2)";
  419. }
  420. } else {
  421. this.thumbYDisplay = "none";
  422. }
  423. this.selectedNum = selectedNum;
  424. })
  425. })
  426. },
  427. //点击固定窗口头部
  428. mousedownWidgetHeader(e) {
  429. let el = document.querySelector(
  430. ".v-widget-window .v-window-header-wrapper"
  431. );
  432. this.widgetFirstClick.layerX = e.layerX;
  433. this.widgetFirstClick.screenX = document.documentElement.clientWidth;
  434. this.widgetFirstClick.layerY = e.layerY;
  435. this.widgetFirstClick.screenY = document.documentElement.clientHeight;
  436. document.addEventListener("mousemove", this.mousemoveWidgetHeader);
  437. document.addEventListener("mouseup", this.mouseupWidgetHeader);
  438. },
  439. //移动固定窗口头部
  440. mousemoveWidgetHeader(e) {
  441. let el = document.querySelector(
  442. ".v-widget-window .v-window-header-wrapper"
  443. );
  444. let el1 = document.querySelector(".v-widget-window");
  445. let el2 = document.querySelector(".v-widget-window .v-widget-list");
  446. el2.style.display = "none";
  447. // X轴
  448. let moveX = e.pageX - this.widgetFirstClick.layerX;
  449. if (moveX > this.widgetFirstClick.screenX - el1.offsetWidth) {
  450. moveX = this.widgetFirstClick.screenX - el1.offsetWidth;
  451. }
  452. if (moveX < 0) {
  453. moveX = 0;
  454. }
  455. // Y轴
  456. let moveY = e.pageY - this.widgetFirstClick.layerY;
  457. if (moveY > this.widgetFirstClick.screenY - el1.offsetHeight) {
  458. moveY = this.widgetFirstClick.screenY - el1.offsetHeight;
  459. }
  460. if (moveY < 0) {
  461. moveY = 0;
  462. }
  463. this.left = moveX + "px";
  464. this.top = moveY + "px";
  465. if (!el1.className.includes(" move")) {
  466. el1.className = el1.className + " move";
  467. }
  468. if (!el1.className.includes(" ghost")) {
  469. el1.className = el1.className + " ghost";
  470. }
  471. },
  472. //鼠标抬起固定窗口头部停止移动
  473. mouseupWidgetHeader() {
  474. let el = document.querySelector(
  475. ".v-widget-window .v-window-header-wrapper"
  476. );
  477. let el1 = document.querySelector(".v-widget-window .v-widget-list");
  478. let el2 = document.querySelector(".v-widget-window");
  479. document.removeEventListener("mousemove", this.mousemoveWidgetHeader);
  480. document.removeEventListener("mouseup", this.mouseupWidgetHeader);
  481. // document.addEventListener("mouseleave", this.mouseupWidgetHeader);
  482. el1.style.display = "flex";
  483. el2.className = el2.className.replace(" move", "");
  484. el2.className = el2.className.replace(" ghost", "");
  485. },
  486. //显示或隐藏固定窗口
  487. showOrHiddenWidget(e) {
  488. let el = document.querySelector(
  489. ".v-widget-window .v-widget-header-tool-icon.pin"
  490. );
  491. if (this.fixWindowMessage.display === "block") {
  492. if (e.srcElement.className.includes(" pressed")) {
  493. e.srcElement.className = e.srcElement.className.replace(
  494. " pressed",
  495. ""
  496. );
  497. }
  498. if (
  499. this.fixWindowMessage.zIndex >= this.defaultZIndex &&
  500. this.fixWindowMessage.cls === "active-win"
  501. ) {
  502. this.fixWindowMessage.zIndex = this.defaultZIndex - 10;
  503. this.$bus.emit("changeDefaultZIndex", this.defaultZIndex - 10);
  504. this.$bus.emit("fixWindowZIndexMax", false);
  505. }
  506. this.fixWindowMessage.display = "none";
  507. } else {
  508. this.fixWindowMessage.display = "block";
  509. this.fixWindowMessage.zIndex = this.defaultZIndex + 10;
  510. this.$bus.emit("changeDefaultZIndex", this.defaultZIndex + 10);
  511. this.$bus.emit("fixWindowZIndexMax", true);
  512. if (!e.srcElement.className.includes(" pressed")) {
  513. e.srcElement.className = e.srcElement.className + " pressed";
  514. }
  515. }
  516. },
  517. //最小化固定窗口
  518. minimizeFixWndow() {
  519. this.fixWindowMessage.display = "none";
  520. this.fixWindowMessage.zIndex = this.defaultZIndex - 10;
  521. this.$bus.emit("changeDefaultZIndex", this.defaultZIndex - 10);
  522. this.$bus.emit("fixWindowZIndexMax", false);
  523. let el = document.querySelector(".tray-item.widget-button");
  524. if (el.className && el.className.includes(" pressed")) {
  525. el.className = el.className.replace(" pressed", "");
  526. }
  527. },
  528. // 显示或隐藏位置选择框
  529. selectWidgetPosition() {
  530. this.$bus.emit("showOrHiddenSelectWidgetPosition", this.portalDetail1);
  531. },
  532. //改变固定弹出框的位置
  533. changeWidgetPosition(obj) {
  534. this.portalDetail1.detailMessageList = obj.detailMessageList;
  535. let detailMessageItem = this.portalDetail1.detailMessageList[obj.index];
  536. this.top = detailMessageItem.top;
  537. this.bottom = detailMessageItem.bottom;
  538. this.left = detailMessageItem.left;
  539. this.right = detailMessageItem.right;
  540. let el = document.querySelector(
  541. ".v-widget-window .v-widget-header-tool-icon.dock"
  542. );
  543. el.className = el.className + " active";
  544. },
  545. //点击小钉子
  546. pinFixWndow() {
  547. let el = document.querySelector(
  548. ".v-widget-window .v-widget-header-tool-icon.pin"
  549. );
  550. if (el.className.includes("active")) {
  551. el.className = el.className.replace(" active", "");
  552. this.$bus.emit("fixWindowZIndexMax", false);
  553. this.fixWindowMessage.zIndex = this.defaultZIndex - 10;
  554. this.$bus.emit("changeDefaultZIndex", this.defaultZIndex - 10);
  555. } else {
  556. el.className = el.className + " active";
  557. this.fixWindowMessage.zIndex = 999999999;
  558. this.$bus.emit("changeDefaultZIndex", this.defaultZIndex + 10);
  559. this.$bus.emit("fixWindowZIndexMax", true);
  560. }
  561. },
  562. // 关闭widgetItem
  563. closeWidgetItem(title){
  564. this.portalDetail.detailMessageList.forEach(item=>{
  565. if(item.title === title){
  566. item.cls = item.cls.replace('v-menu-item-select-selected selected','')
  567. }
  568. })
  569. },
  570. //节流函数
  571. throttle(fn, time, e) {
  572. var lastTime = 0;
  573. return function () {
  574. var nowTime = Date.now();
  575. if (nowTime - lastTime > time) {
  576. fn.call(this, e);
  577. lastTime = nowTime;
  578. }
  579. };
  580. },
  581. },
  582. beforeDestroy() {},
  583. name: "FixWindow",
  584. };
  585. </script>
  586. <style scoped lang="css">
  587. .v-widget-window .v-ps.show::-webkit-scrollbar {
  588. display: none;
  589. }
  590. .v-ps {
  591. height: 424px;
  592. }
  593. input:-moz-placeholder,
  594. textarea:-moz-placeholder {
  595. color: #fff !important;
  596. }
  597. input:-ms-input-placeholder,
  598. textarea:-ms-input-placeholder {
  599. color: #fff !important;
  600. }
  601. input::-webkit-input-placeholder,
  602. textarea::-webkit-input-placeholder {
  603. color: #fff !important;
  604. }
  605. </style>