index.tsx 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. import {
  2. Transition,
  3. defineComponent,
  4. onMounted,
  5. ref,
  6. reactive,
  7. onUnmounted,
  8. watch,
  9. computed
  10. } from 'vue';
  11. import LayoutSilder from './layoutSilder';
  12. import LayoutTop from './layoutTop';
  13. import styles from './index.module.less';
  14. import { NButton, NImage, NModal, NPopover, NSpace, useDialog } from 'naive-ui';
  15. import Moveable from 'moveable';
  16. import toolStartClass from './images/toolStartClass.png';
  17. import timerMeterClose from './images/close.png';
  18. import toolbox from './images/toolbox.png';
  19. import setTimeIcon from './images/setTimeIcon.png';
  20. import beatIcon from './images/beatIcon.png';
  21. import toneIcon from './images/toneIcon.png';
  22. import iconWhiteBorad from './images/icon-whiteborad.png';
  23. import iconPen from './images/icon-pen.png';
  24. import iconNote from './images/icon-note.png';
  25. import beatImage from './images/beatImage.png';
  26. import toneImage from './images/toneImage.png';
  27. import setTimeImage from './images/setTimeImage.png';
  28. import dragingBoxIcon from './images/dragingBoxIcon.png';
  29. import TimerMeter from '../timerMeter';
  30. import Metronome from '../Metronome';
  31. import { useRoute, useRouter } from 'vue-router';
  32. import { vaildUrl } from '/src/utils/urlUtils';
  33. import ChioseModal from '/src/views/home/modals/chioseModal';
  34. import {
  35. eventGlobal,
  36. iframeDislableKeyboard,
  37. px2vw,
  38. px2vwH
  39. } from '@/utils/index';
  40. import PlaceholderTone from './modals/placeholderTone';
  41. import { state } from '/src/state';
  42. import PreviewWindow from '/src/views/preview-window';
  43. import { fscreen } from '@/utils/index';
  44. import AttendClass from '/src/views/prepare-lessons/model/attend-class';
  45. import Pen from '/src/views/attend-class/component/tools/pen';
  46. import study from '/src/views/home/components/study';
  47. import TheAuth from '../TheAuth';
  48. import useDrag from '@/hooks/useDrag';
  49. import { getGuidanceShow } from '@/hooks/useDrag/useDragGuidance';
  50. import { useUserStore } from '@/store/modules/users';
  51. export default defineComponent({
  52. name: 'layoutView',
  53. setup() {
  54. const router = useRouter();
  55. const previewModal = ref(false);
  56. const previewItem = ref({});
  57. const directionType = ref('left');
  58. const showClass = ref(false);
  59. const showAuthMask = ref(false);
  60. const showModalBeat = ref(false);
  61. const showModalTone = ref(false);
  62. const showModalTime = ref(false);
  63. const showBoxConent = ref(false);
  64. const dialog = useDialog();
  65. const boxBoundaryInfo = reactive({
  66. isBoundary: false,
  67. isBoundaryType: '' as any,
  68. mainWidth: '' as any,
  69. mainHeight: '' as any,
  70. subWidth: '' as any,
  71. subHeight: '' as any
  72. });
  73. const classBoundaryInfo = reactive({
  74. isBoundary: true,
  75. isBoundaryType: 'right' as any,
  76. mainWidth: '' as any,
  77. mainHeight: '' as any,
  78. subWidth: '' as any,
  79. subHeight: '' as any
  80. });
  81. const route = useRoute();
  82. const isDragIng = ref(false);
  83. const NPopoverRef = ref();
  84. const initMoveable = async () => {
  85. if (document.querySelector('.wrap')) {
  86. const moveable = new Moveable(document.querySelector('.wrap') as any, {
  87. target: document.querySelector('#moveNPopover') as any,
  88. // If the container is null, the position is fixed. (default: parentElement(document.body))
  89. container: document.querySelector('.wrap') as any,
  90. // snappable: true,
  91. // bounds: {"left":100,"top":100,"right":100,"bottom":100},
  92. draggable: true,
  93. resizable: false,
  94. scalable: false,
  95. rotatable: false,
  96. warpable: false,
  97. pinchable: false, // ["resizable", "scalable", "rotatable"]
  98. origin: false,
  99. keepRatio: false,
  100. // Resize, Scale Events at edges.
  101. edge: false,
  102. throttleDrag: 0,
  103. throttleResize: 0,
  104. throttleScale: 0,
  105. throttleRotate: 0
  106. });
  107. moveable
  108. // .on('dragStart', ({ target, clientX, clientY }) => {
  109. // console.log('dragStart');
  110. // })
  111. .on(
  112. 'drag',
  113. ({
  114. target,
  115. // transform,
  116. left,
  117. top,
  118. right,
  119. bottom
  120. // beforeDelta,
  121. // beforeDist,
  122. // delta,
  123. // dist,
  124. // clientX,
  125. // clientY
  126. }) => {
  127. isDragIng.value = true;
  128. if (NPopoverRef.value) {
  129. NPopoverRef.value.setShow(false);
  130. }
  131. const subdEl = document.getElementById(
  132. `moveNPopover`
  133. ) as HTMLDivElement;
  134. // console.log(subdEl, "subdEl", "drag");
  135. const subdElStyle = getComputedStyle(subdEl, null);
  136. const RectInfo = {
  137. left: Number(subdElStyle.left.replace('px', '')),
  138. top: Number(subdElStyle.top.replace('px', '')),
  139. width: Number(subdElStyle.width.replace('px', '')),
  140. height: Number(subdElStyle.height.replace('px', ''))
  141. };
  142. // target.style.transition = ''
  143. const mainWidth =
  144. parseInt(
  145. window.getComputedStyle(
  146. document.querySelector('.wrap') as Element
  147. ).width
  148. ) - RectInfo.width;
  149. const mainHeight =
  150. parseInt(
  151. window.getComputedStyle(
  152. document.querySelector('.wrap') as Element
  153. ).height
  154. ) - RectInfo.height;
  155. subdEl.style.transition = '';
  156. boxBoundaryInfo.isBoundary = false;
  157. boxBoundaryInfo.isBoundaryType = '';
  158. boxBoundaryInfo.mainHeight = mainHeight;
  159. boxBoundaryInfo.mainWidth = mainWidth;
  160. boxBoundaryInfo.subWidth = RectInfo.width;
  161. boxBoundaryInfo.subHeight = RectInfo.height;
  162. if (left < 0) {
  163. left = 2;
  164. boxBoundaryInfo.isBoundary = true;
  165. boxBoundaryInfo.isBoundaryType = 'left';
  166. }
  167. if (top < 0) {
  168. top = 2;
  169. boxBoundaryInfo.isBoundary = true;
  170. boxBoundaryInfo.isBoundaryType = 'top';
  171. }
  172. if (right < 0) {
  173. right = 2;
  174. }
  175. if (bottom < 0) {
  176. bottom = 2;
  177. }
  178. if (left > mainWidth - 2) {
  179. left = mainWidth - 2;
  180. // top = 2;
  181. boxBoundaryInfo.isBoundary = true;
  182. boxBoundaryInfo.isBoundaryType = 'right';
  183. }
  184. if (top > mainHeight - 2) {
  185. top = mainHeight - 2;
  186. boxBoundaryInfo.isBoundary = true;
  187. boxBoundaryInfo.isBoundaryType = 'bottom';
  188. }
  189. target!.style.left = `${left}px`;
  190. target!.style.top = `${top}px`;
  191. }
  192. )
  193. .on(
  194. 'dragEnd',
  195. async ({
  196. target,
  197. // isDrag,
  198. clientX
  199. // clientY
  200. }) => {
  201. if (document.body.clientWidth / 2 - clientX > 0) {
  202. // 往左出
  203. directionType.value = 'right';
  204. } else {
  205. // 往又出
  206. directionType.value = 'left';
  207. }
  208. isDragIng.value = false;
  209. // 在这里进行动画
  210. if (boxBoundaryInfo.isBoundary) {
  211. // 这里说明贴边了
  212. target.style.transition = '.3s';
  213. actionEnd(target, boxBoundaryInfo.isBoundaryType);
  214. }
  215. }
  216. );
  217. }
  218. };
  219. const initMoveableClass = async () => {
  220. if (document.querySelector('.wrap')) {
  221. const moveable = new Moveable(document.querySelector('.wrap') as any, {
  222. target: document.querySelector('#moveNPopover2') as any,
  223. // If the container is null, the position is fixed. (default: parentElement(document.body))
  224. container: document.querySelector('.wrap') as any,
  225. // snappable: true,
  226. // bounds: {"left":100,"top":100,"right":100,"bottom":100},
  227. draggable: true,
  228. resizable: false,
  229. scalable: false,
  230. rotatable: false,
  231. warpable: false,
  232. pinchable: false, // ["resizable", "scalable", "rotatable"]
  233. origin: false,
  234. keepRatio: false,
  235. // Resize, Scale Events at edges.
  236. edge: false,
  237. throttleDrag: 0,
  238. throttleResize: 0,
  239. throttleScale: 0,
  240. throttleRotate: 0
  241. });
  242. moveable
  243. .on(
  244. 'drag',
  245. ({
  246. target,
  247. // transform,
  248. left,
  249. top,
  250. right,
  251. bottom
  252. }) => {
  253. isDragIng.value = true;
  254. const subdEl = document.getElementById(
  255. `moveNPopover2`
  256. ) as HTMLDivElement;
  257. // console.log(subdEl, "subdEl", "drag");
  258. const subdElStyle = getComputedStyle(subdEl, null);
  259. const RectInfo = {
  260. left: Number(subdElStyle.left.replace('px', '')),
  261. top: Number(subdElStyle.top.replace('px', '')),
  262. width: Number(subdElStyle.width.replace('px', '')),
  263. height: Number(subdElStyle.height.replace('px', ''))
  264. };
  265. const mainWidth =
  266. parseInt(
  267. window.getComputedStyle(
  268. document.querySelector('.wrap') as Element
  269. ).width
  270. ) - RectInfo.width;
  271. const mainHeight =
  272. parseInt(
  273. window.getComputedStyle(
  274. document.querySelector('.wrap') as Element
  275. ).height
  276. ) - RectInfo.height;
  277. subdEl.style.transition = '';
  278. classBoundaryInfo.isBoundary = false;
  279. classBoundaryInfo.isBoundaryType = '';
  280. classBoundaryInfo.mainHeight = mainHeight;
  281. classBoundaryInfo.mainWidth = mainWidth;
  282. classBoundaryInfo.subWidth = RectInfo.width;
  283. classBoundaryInfo.subHeight = RectInfo.height;
  284. if (left < 0) {
  285. left = 2;
  286. classBoundaryInfo.isBoundary = true;
  287. classBoundaryInfo.isBoundaryType = 'left';
  288. }
  289. if (top < 0) {
  290. top = 2;
  291. classBoundaryInfo.isBoundary = true;
  292. classBoundaryInfo.isBoundaryType = 'top';
  293. }
  294. if (right < 0) {
  295. right = 2;
  296. }
  297. if (bottom < 0) {
  298. bottom = 2;
  299. }
  300. if (left > mainWidth - 2) {
  301. left = mainWidth - 2;
  302. // top = 2;
  303. classBoundaryInfo.isBoundary = true;
  304. classBoundaryInfo.isBoundaryType = 'right';
  305. }
  306. if (top > mainHeight - 2) {
  307. top = mainHeight - 2;
  308. classBoundaryInfo.isBoundary = true;
  309. classBoundaryInfo.isBoundaryType = 'bottom';
  310. }
  311. target!.style.left = `${left}px`;
  312. target!.style.top = `${top}px`;
  313. }
  314. )
  315. .on(
  316. 'dragEnd',
  317. async ({
  318. target,
  319. // isDrag,
  320. clientX
  321. // clientY
  322. }) => {
  323. if (document.body.clientWidth / 2 - clientX > 0) {
  324. // 往左出
  325. directionType.value = 'right';
  326. } else {
  327. // 往又出
  328. directionType.value = 'left';
  329. }
  330. if (classBoundaryInfo.isBoundary) {
  331. // 这里说明贴边了
  332. target.style.transition = '.3s';
  333. actionEnd(target, classBoundaryInfo.isBoundaryType);
  334. }
  335. isDragIng.value = false;
  336. }
  337. )
  338. .on('click', () => {
  339. showClass.value = true;
  340. });
  341. }
  342. };
  343. watch(
  344. () => route.path,
  345. (val: any) => {
  346. const elDoc = document.getElementById('WrapcoreViewWrap') as any;
  347. if (elDoc) {
  348. elDoc.scrollTo(0, 0);
  349. window.scrollTo(0, 0);
  350. }
  351. }
  352. );
  353. // 帮助指引状态
  354. const helpNoteList = reactive({
  355. baseListTab: ''
  356. });
  357. const helpNoteStatus = computed(() => {
  358. const routePath = route.path;
  359. const hidePath = [
  360. '/classDetail',
  361. '/classStudentDetail',
  362. '/notation',
  363. '/xiaoku-ai',
  364. '/studentDetail',
  365. '/classStudentRecode',
  366. '/afterWorkDetail'
  367. ];
  368. // 单独判断个人信息页面[学校设置]有引导
  369. if (route.path === '/setting') {
  370. return helpNoteList.baseListTab === 'school' ? true : false;
  371. } else {
  372. return hidePath.includes(routePath) ? false : true;
  373. }
  374. });
  375. const startClassStatus = computed(() => {
  376. const routePath = route.path;
  377. console.log(routePath, 'routePath', routePath);
  378. const hidePath = ['/prepare-lessons'];
  379. return hidePath.includes(routePath) ? false : true;
  380. });
  381. onMounted(() => {
  382. initMoveable();
  383. // // initMoveableClass();
  384. const subdEl = document.getElementById(`moveNPopover`) as HTMLDivElement;
  385. // // const classEl = document.getElementById(
  386. // // `moveNPopover2`
  387. // // ) as HTMLDivElement;
  388. // // initBoxRectInfo(classEl, classBoundaryInfo);
  389. initBoundaryWrap(subdEl, boxBoundaryInfo);
  390. initBoxRectInfo(subdEl, boxBoundaryInfo);
  391. // // initBoundaryWrap(classEl, classBoundaryInfo);
  392. window.addEventListener('resize', resetSize);
  393. eventGlobal.on('base-setting-emit', (val: string) => {
  394. helpNoteList.baseListTab = val;
  395. });
  396. // 判断是否显示证书提示
  397. eventGlobal.on('auth-not-installed', () => {
  398. showAuthMask.value = true;
  399. });
  400. });
  401. const resetSize = () => {
  402. const subdEl = document.getElementById(`moveNPopover`) as HTMLDivElement;
  403. subdEl.style.display = 'none';
  404. // const boxBoundaryInfo = reactive({
  405. // isBoundary: true,
  406. // isBoundaryType: 'right' as any,
  407. // mainWidth: '' as any,
  408. // mainHeight: '' as any,
  409. // subWidth: '' as any,
  410. // subHeight: '' as any
  411. // });
  412. // boxBoundaryInfo.isBoundary = true;
  413. // boxBoundaryInfo.isBoundaryType= 'right'
  414. if (NPopoverRef.value) {
  415. NPopoverRef.value.setShow(false);
  416. }
  417. setTimeout(() => {
  418. subdEl.style.transition = '';
  419. initBoxRectInfo(subdEl, boxBoundaryInfo);
  420. initBoundaryWrap(subdEl, boxBoundaryInfo);
  421. console.log('resize');
  422. subdEl.style.display = 'block';
  423. }, 100);
  424. };
  425. onUnmounted(() => {
  426. window.removeEventListener('resize', resetSize);
  427. });
  428. const initBoundaryWrap = (target: any, wrapInfo: any) => {
  429. target.addEventListener('mouseover', () => {
  430. if (wrapInfo.isBoundary) {
  431. // 如果在边框 就得还原 元素位置 还原完毕后 去除transition
  432. if (wrapInfo.isBoundaryType == 'left') {
  433. target.style.left = '2px';
  434. } else if (wrapInfo.isBoundaryType == 'right') {
  435. target.style.left = `${wrapInfo.mainWidth - 2}px`;
  436. } else if (wrapInfo.isBoundaryType == 'top') {
  437. target.style.top = `${2}px`;
  438. } else if (wrapInfo.isBoundaryType == 'bottom') {
  439. target.style.top = `${wrapInfo.mainHeight - 2}px`;
  440. }
  441. }
  442. rate(target, 0);
  443. });
  444. target.addEventListener('mouseout', () => {
  445. if (wrapInfo.isBoundary) {
  446. // 如果在边框 就得还原 元素位置 还原完毕后 去除transition
  447. if (wrapInfo.isBoundaryType == 'left') {
  448. actionEnd(target, 'left');
  449. } else if (wrapInfo.isBoundaryType == 'right') {
  450. actionEnd(target, 'right');
  451. } else if (wrapInfo.isBoundaryType == 'top') {
  452. actionEnd(target, 'top');
  453. } else if (wrapInfo.isBoundaryType == 'bottom') {
  454. actionEnd(target, 'bottom');
  455. }
  456. }
  457. // rate(target, 0)
  458. });
  459. // target.addEventListener('contextmenu', (event: any) => {
  460. // event.preventDefault();
  461. // dialog.warning({
  462. // title: '提示',
  463. // content: '是否收入托盘',
  464. // positiveText: '确定',
  465. // negativeText: '取消',
  466. // onPositiveClick: () => {
  467. // console.log('确定');
  468. // },
  469. // onNegativeClick: () => {
  470. // console.log('取消');
  471. // }
  472. // });
  473. // });
  474. // actionEnd(target, 'right');
  475. };
  476. const startShowModal = (
  477. val:
  478. | 'setTimeIcon'
  479. | 'beatIcon'
  480. | 'toneIcon'
  481. | 'iconWhiteBorad'
  482. | 'iconPen'
  483. | 'iconNote'
  484. ) => {
  485. if (val == 'setTimeIcon') {
  486. showModalTime.value = true;
  487. }
  488. if (val == 'beatIcon') {
  489. showModalBeat.value = true;
  490. }
  491. if (val == 'toneIcon') {
  492. showModalTone.value = true;
  493. }
  494. if (val == 'iconNote') {
  495. if (NPopoverRef.value) {
  496. NPopoverRef.value.setShow(false);
  497. }
  498. console.log(route.name, 'guideInfo');
  499. eventGlobal.emit('teacher-guideInfo', route.name);
  500. }
  501. if (val == 'iconWhiteBorad') {
  502. studyData.whiteboardShow = true;
  503. studyData.type = 'whiteboard';
  504. studyData.homeStatus = false;
  505. if (NPopoverRef.value) {
  506. NPopoverRef.value.setShow(false);
  507. }
  508. }
  509. if (val == 'iconPen') {
  510. studyData.penShow = true;
  511. studyData.type = 'pen';
  512. studyData.homeStatus = false;
  513. if (NPopoverRef.value) {
  514. NPopoverRef.value.setShow(false);
  515. }
  516. }
  517. };
  518. // const moveTargetBoundary = (target: any, type: any) => {
  519. // console.log('moveTargetBoundary', target, type);
  520. // };
  521. // 这里是旋转
  522. const rate = (target: any, rate: any) => {
  523. target.style.transform = ' rotate(' + rate + ')';
  524. };
  525. // 这里是选装的方式
  526. const actionEnd = (target: any, type: any) => {
  527. switch (type) {
  528. case 'left':
  529. rate(target, '90deg');
  530. target!.style.left = `${2 - boxBoundaryInfo.subWidth / 2}px`;
  531. target!.style.top = `${top}px`;
  532. break;
  533. case 'right':
  534. rate(target, '-90deg');
  535. target!.style.left = `${
  536. boxBoundaryInfo.mainWidth - 2 + boxBoundaryInfo.subWidth / 2
  537. }px`;
  538. target!.style.top = `${top}px`;
  539. break;
  540. case 'top':
  541. target!.style.top = `${2 - boxBoundaryInfo.subHeight / 2}px`;
  542. rate(target, '-180deg');
  543. break;
  544. case 'bottom':
  545. target!.style.top = `${
  546. boxBoundaryInfo.mainHeight - 2 + boxBoundaryInfo.subHeight / 2
  547. }px`;
  548. break;
  549. default:
  550. rate(target, '-0');
  551. break;
  552. }
  553. };
  554. const initBoxRectInfo = (target: any, wrapInfo: any) => {
  555. // const subdEl = document.getElementById(`moveNPopover`) as HTMLDivElement;
  556. // console.log(subdEl, "subdEl", "drag");
  557. const subdElStyle = getComputedStyle(target, null);
  558. const RectInfo = {
  559. left: Number(subdElStyle.left.replace('px', '')),
  560. top: Number(subdElStyle.top.replace('px', '')),
  561. width: Number(subdElStyle.width.replace('px', '')),
  562. height: Number(subdElStyle.height.replace('px', ''))
  563. };
  564. // target.style.transition = ''
  565. const mainWidth =
  566. parseInt(
  567. window.getComputedStyle(document.querySelector('.wrap') as Element)
  568. .width
  569. ) - RectInfo.width;
  570. const mainHeight =
  571. parseInt(
  572. window.getComputedStyle(document.querySelector('.wrap') as Element)
  573. .height
  574. ) - RectInfo.height;
  575. // boxBoundaryInfo.isBoundary = false;
  576. // boxBoundaryInfo.isBoundaryType = '';
  577. wrapInfo.mainHeight = mainHeight;
  578. wrapInfo.mainWidth = mainWidth;
  579. wrapInfo.subWidth = RectInfo.width;
  580. wrapInfo.subHeight = RectInfo.height;
  581. target.style.transition = '.3s .3s';
  582. };
  583. /** 教学数据 */
  584. const studyData = reactive({
  585. homeStatus: true, // 是否显示首页
  586. type: '',
  587. penShow: false,
  588. whiteboardShow: false
  589. });
  590. /* 弹窗加拖动 */
  591. // 引导页
  592. getGuidanceShow();
  593. //计时器
  594. const users = useUserStore();
  595. const timerMeterConBoxClass = 'timerMeterConBoxClass_drag';
  596. const timerMeterConDragData = useDrag(
  597. [
  598. `${timerMeterConBoxClass} .timeBomCon .bom_drag`,
  599. `${timerMeterConBoxClass} .topDragDom`
  600. ],
  601. timerMeterConBoxClass,
  602. showModalTime,
  603. users.info.id
  604. );
  605. // 节拍器
  606. const metronomeConBoxClass = 'metronomeConBoxClass_drag';
  607. const metronomeConBoxDragData = useDrag(
  608. [
  609. `${metronomeConBoxClass} .topDragDom`,
  610. `${metronomeConBoxClass} .bom_drag`
  611. ],
  612. metronomeConBoxClass,
  613. showModalBeat,
  614. users.info.id
  615. );
  616. return () => (
  617. <div class={[styles.wrap, 'wrap']}>
  618. <div>
  619. <LayoutSilder></LayoutSilder>
  620. </div>
  621. <div class={styles.Wrapcore}>
  622. <LayoutTop></LayoutTop>
  623. <div class={styles.WrapcoreView} id="WrapcoreViewWrap">
  624. {/* <div class={styles.WrapcoreViewInfo}> */}
  625. <router-view>
  626. {(obj: any) => (
  627. <Transition name="fade-slide" mode="out-in">
  628. <obj.Component />
  629. </Transition>
  630. )}
  631. </router-view>
  632. {/* </div> */}
  633. </div>
  634. </div>
  635. {/* <img
  636. src={toolStartClass}
  637. id="moveNPopover2"
  638. style={{
  639. display: ['/', '/home', '/classList', '/prepare-lessons'].includes(
  640. route.path
  641. )
  642. ? 'none'
  643. : 'block'
  644. }}
  645. class={[
  646. styles.toolClassImg,
  647. 'moveNPopover2',
  648. isDragIng.value ? styles.isDragIng : ''
  649. ]}
  650. alt=""
  651. /> */}
  652. <NPopover
  653. raw
  654. trigger="click"
  655. ref={NPopoverRef}
  656. show-arrow={false}
  657. placement={directionType.value as 'left' | 'right'}
  658. v-slots={{
  659. trigger: () => (
  660. // 首页不显示工具箱 ['/', '/home'].includes(route.path) ||
  661. <img
  662. // src={isDragIng.value ? dragingBoxIcon : toolbox}
  663. src={toolbox}
  664. id="moveNPopover"
  665. style={{
  666. display: !studyData.homeStatus ? 'none' : 'block'
  667. }}
  668. class={[
  669. styles.toolboxImg,
  670. 'moveNPopover',
  671. isDragIng.value ? styles.isDragIng : ''
  672. ]}
  673. alt=""
  674. />
  675. )
  676. }}>
  677. <div class={styles.booxToolWrap}>
  678. <div>
  679. <div
  680. class={styles.booxToolItem}
  681. onClick={() => startShowModal('beatIcon')}>
  682. <img src={beatIcon} alt="" />
  683. 节拍器
  684. </div>
  685. {/* <div
  686. class={styles.booxToolItem}
  687. onClick={() => startShowModal('toneIcon')}>
  688. <img src={toneIcon} alt="" />
  689. 调音器
  690. </div> */}
  691. <div
  692. class={styles.booxToolItem}
  693. onClick={() => startShowModal('setTimeIcon')}>
  694. <img src={setTimeIcon} alt="" />
  695. 计时器
  696. </div>
  697. {/* <div
  698. class={[
  699. styles.booxToolItem,
  700. !startClassStatus.value && styles.booxToolDisabled
  701. ]}
  702. onClick={() => {
  703. if (!startClassStatus.value) return;
  704. showClass.value = true;
  705. }}>
  706. <img
  707. src={toolStartClass}
  708. class={[styles.toolClassImg]}
  709. alt=""
  710. />
  711. 开始上课
  712. </div> */}
  713. </div>
  714. <div>
  715. {/* <div
  716. class={[
  717. styles.booxToolItem,
  718. !helpNoteStatus.value && styles.booxToolDisabled
  719. ]}
  720. onClick={() => {
  721. if (!helpNoteStatus.value) return;
  722. // 默认滚动到页面顶部,在显示指引
  723. document.querySelector('#WrapcoreViewWrap')?.scrollTo(0, 0);
  724. startShowModal('iconNote');
  725. }}>
  726. <img src={iconNote} alt="" />
  727. 功能引导
  728. </div> */}
  729. <div
  730. class={styles.booxToolItem}
  731. onClick={() => startShowModal('iconPen')}>
  732. <img src={iconWhiteBorad} alt="" />
  733. 批注
  734. </div>
  735. <div
  736. class={styles.booxToolItem}
  737. onClick={() => startShowModal('iconWhiteBorad')}>
  738. <img src={iconPen} alt="" />
  739. 白板
  740. </div>
  741. </div>
  742. </div>
  743. </NPopover>
  744. {/* 批注 */}
  745. {studyData.penShow && (
  746. <Pen
  747. show={studyData.type === 'pen'}
  748. type={studyData.type as any}
  749. close={() => {
  750. studyData.type = 'init';
  751. studyData.homeStatus = true;
  752. }}
  753. />
  754. )}
  755. {studyData.whiteboardShow && (
  756. <Pen
  757. show={studyData.type === 'whiteboard'}
  758. type={studyData.type as any}
  759. close={() => {
  760. studyData.type = 'init';
  761. studyData.homeStatus = true;
  762. }}
  763. />
  764. )}
  765. {/* <NModal
  766. class={['modalTitle background']}
  767. style={{ width: '687px' }}
  768. title={'节拍器'}
  769. preset="card"
  770. v-model:show={showModalBeat.value}>
  771. <div class={styles.modeWrap}>
  772. <iframe
  773. src={`${vaildUrl()}/metronome/?id=${new Date().getTime()}`}
  774. scrolling="no"
  775. frameborder="0"
  776. width="100%"
  777. onLoad={(val: any) => {
  778. iframeDislableKeyboard(val.target);
  779. }}
  780. height={'650px'}></iframe>
  781. </div>
  782. </NModal> */}
  783. <Metronome
  784. v-model={showModalBeat.value}
  785. dragClass={metronomeConBoxClass}
  786. dragStyle={metronomeConBoxDragData.styleDrag.value}></Metronome>
  787. <NModal v-model:show={showModalTone.value} class={['background']}>
  788. {/* <div
  789. onClick={() => {
  790. showModalTone.value = false;
  791. }}>
  792. <NImage
  793. src={toneImage}
  794. previewDisabled
  795. class={styles.beatImage}></NImage>
  796. </div> */}
  797. <div>
  798. <PlaceholderTone
  799. onClose={() => {
  800. showModalTone.value = false;
  801. }}></PlaceholderTone>
  802. </div>
  803. </NModal>
  804. <NModal
  805. v-model:show={showModalTime.value}
  806. class={timerMeterConBoxClass}
  807. style={timerMeterConDragData.styleDrag.value}>
  808. <div>
  809. <img
  810. class={styles.timerMeterClose}
  811. src={timerMeterClose}
  812. onClick={() => {
  813. showModalTime.value = false;
  814. }}
  815. />
  816. <div class="topDragDom"></div>
  817. <TimerMeter></TimerMeter>
  818. </div>
  819. </NModal>
  820. <NModal
  821. v-model:show={showClass.value}
  822. class={['modalTitle background', styles.showClass]}
  823. preset="card"
  824. title={'开始上课'}>
  825. <AttendClass
  826. onClose={() => (showClass.value = false)}
  827. type="change"
  828. onConfirm={(item: any) => {
  829. showClass.value = false;
  830. router.push({
  831. path: '/prepare-lessons',
  832. query: {
  833. ...item
  834. }
  835. });
  836. }}
  837. />
  838. </NModal>
  839. {/* 弹窗查看 */}
  840. <PreviewWindow
  841. v-model:show={previewModal.value}
  842. type="attend"
  843. params={previewItem.value}
  844. />
  845. <NModal
  846. v-model:show={showAuthMask.value}
  847. closeOnEsc={false}
  848. maskClosable={false}>
  849. <TheAuth onClose={() => (showAuthMask.value = false)} />
  850. </NModal>
  851. </div>
  852. );
  853. }
  854. });