index.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. import {
  2. PropType,
  3. defineComponent,
  4. nextTick,
  5. onMounted,
  6. reactive,
  7. ref,
  8. toRef
  9. } from 'vue';
  10. import styles from './index.module.less';
  11. import { NTabs, NTabPane, NModal } from 'naive-ui';
  12. import SelectMusicModal from '../../model/select-music';
  13. import { usePrepareStore } from '/src/store/modules/prepareLessons';
  14. import SelectResources from '../../model/select-resources';
  15. import SelectMusic, { typeFormat } from './components/select-music';
  16. import ResourceItem from './components/resource-item';
  17. import TrainUpdate from '/src/views/attend-class/model/train-update';
  18. import requestOrigin from 'umi-request';
  19. import { eventGlobal } from '/src/utils';
  20. import useDrag from '@/hooks/useDrag';
  21. import Dragbom from '@/hooks/useDrag/dragbom';
  22. import { useUserStore } from '@/store/modules/users';
  23. export default defineComponent({
  24. name: 'resource-main',
  25. props: {
  26. /** 类型 */
  27. cardType: {
  28. type: String as PropType<'' | 'homerowk-record' | 'prepare'>,
  29. default: ''
  30. },
  31. from: {
  32. // 来自哪里
  33. type: String,
  34. default: ''
  35. }
  36. },
  37. setup(props, { expose }) {
  38. const prepareStore = usePrepareStore();
  39. const forms = reactive({
  40. tabType: 'relateResources',
  41. tabWorkType: 'myMusic',
  42. selectMusicStatus: false,
  43. selectResourceStatus: false,
  44. editStatus: false,
  45. editItem: {} as any
  46. });
  47. const tabRef = ref();
  48. const workRef = ref();
  49. const onAdd = async (item: any) => {
  50. let xmlStatus = 'init';
  51. // 第一个声部小节
  52. let firstMeasures: any = null;
  53. try {
  54. // 获取文件
  55. const res = await requestOrigin.get(item.xmlFileUrl, {
  56. mode: 'cors'
  57. });
  58. const xmlParse = new DOMParser().parseFromString(res, 'text/xml');
  59. const parts = xmlParse.getElementsByTagName('part');
  60. firstMeasures = parts[0]?.getElementsByTagName('measure');
  61. xmlStatus = 'success';
  62. } catch (error) {
  63. xmlStatus = 'error';
  64. }
  65. // 判断读取小节数
  66. if (xmlStatus == 'success') {
  67. item.practiceChapterMax = firstMeasures.length;
  68. } else {
  69. item.practiceChapterMax = 0;
  70. }
  71. item.coursewareKnowledgeDetailId = prepareStore.getSelectKey;
  72. item.subjectId = prepareStore.getSubjectId;
  73. forms.editItem = item;
  74. forms.editStatus = true;
  75. };
  76. const resetTabPosition = () => {
  77. nextTick(() => {
  78. tabRef.value?.syncBarPosition();
  79. workRef.value?.syncBarPosition();
  80. });
  81. };
  82. onMounted(() => {
  83. resetTabPosition();
  84. });
  85. // 弹窗拖动
  86. // 曲目资源
  87. let selectResourceStatusAddBoxDragData: any;
  88. let selectResourceStatusAddBoxClass: string;
  89. if (props.from === 'class') {
  90. const users = useUserStore();
  91. selectResourceStatusAddBoxClass = 'selectResourceStatusAddBoxClass_drag';
  92. selectResourceStatusAddBoxDragData = useDrag(
  93. [
  94. `${selectResourceStatusAddBoxClass} .select-resource>.n-tabs>.n-tabs-nav--top.n-tabs-nav`,
  95. `${selectResourceStatusAddBoxClass} .bom_drag`
  96. ],
  97. selectResourceStatusAddBoxClass,
  98. toRef(forms, 'selectMusicStatus'),
  99. users.info.id
  100. );
  101. }
  102. // 曲目资源 作业设置
  103. let workSetingBoxDragData: any;
  104. let workSetingBoxClass: string;
  105. if (props.from === 'class') {
  106. const users = useUserStore();
  107. workSetingBoxClass = 'workSetingBoxClass_drag';
  108. workSetingBoxDragData = useDrag(
  109. [
  110. `${workSetingBoxClass}>.n-card-header`,
  111. `${workSetingBoxClass} .bom_drag`
  112. ],
  113. workSetingBoxClass,
  114. toRef(forms, 'editStatus'),
  115. users.info.id
  116. );
  117. }
  118. //
  119. expose({
  120. resetTabPosition
  121. });
  122. return () => (
  123. <div
  124. class={[
  125. styles['resource-main'],
  126. forms.selectMusicStatus || forms.selectResourceStatus
  127. ? styles.resourceClose
  128. : ''
  129. ]}>
  130. {prepareStore.getTabType === 'courseware' &&
  131. !['homerowk-record', 'prepare'].includes(props.cardType) ? (
  132. <NTabs
  133. id="lessonsIn-0"
  134. ref={tabRef}
  135. animated
  136. class={styles.homerowkTabs}
  137. value={forms.tabType}
  138. paneClass={styles.paneTitle}
  139. paneWrapperClass={styles.paneWrapperContainer}
  140. onUpdate:value={(val: string) => {
  141. forms.tabType = val;
  142. }}>
  143. {{
  144. suffix: () => (
  145. <div
  146. class={styles.iconScreen}
  147. onClick={() => {
  148. forms.selectResourceStatus = true;
  149. prepareStore.setSelectResourceStatus(true);
  150. }}>
  151. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  152. <g fill="none">
  153. <path
  154. d="M5 6a1 1 0 0 1 1-1h2a1 1 0 0 0 0-2H6a3 3 0 0 0-3 3v2a1 1 0 0 0 2 0V6zm0 12a1 1 0 0 0 1 1h2a1 1 0 1 1 0 2H6a3 3 0 0 1-3-3v-2a1 1 0 1 1 2 0v2zM18 5a1 1 0 0 1 1 1v2a1 1 0 1 0 2 0V6a3 3 0 0 0-3-3h-2a1 1 0 1 0 0 2h2zm1 13a1 1 0 0 1-1 1h-2a1 1 0 1 0 0 2h2a3 3 0 0 0 3-3v-2a1 1 0 1 0-2 0v2z"
  155. fill="#198CFE"></path>
  156. </g>
  157. </svg>
  158. </div>
  159. ),
  160. default: () => (
  161. <>
  162. <NTabPane name="relateResources" tab="相关资源">
  163. <ResourceItem type="relateResources" />
  164. </NTabPane>
  165. <NTabPane
  166. name="shareResources"
  167. tab="共享资源"
  168. // displayDirective="show:lazy"
  169. >
  170. <ResourceItem type="shareResources" />
  171. </NTabPane>
  172. <NTabPane
  173. name="myResources"
  174. tab="我的资源"
  175. // displayDirective="show:lazy"
  176. >
  177. <ResourceItem type="myResources" />
  178. </NTabPane>
  179. <NTabPane
  180. name="myCollect"
  181. tab="我的收藏"
  182. // displayDirective="show:lazy"
  183. >
  184. <ResourceItem type="myCollect" />
  185. </NTabPane>
  186. </>
  187. )
  188. }}
  189. </NTabs>
  190. ) : (
  191. <NTabs
  192. ref={workRef}
  193. animated
  194. value={forms.tabWorkType}
  195. paneClass={styles.paneTitle}
  196. paneWrapperClass={styles.paneWrapperContainer}
  197. onUpdate:value={(val: string) => {
  198. forms.tabWorkType = val;
  199. }}>
  200. {{
  201. suffix: () => (
  202. <div
  203. class={styles.iconScreen}
  204. onClick={() => {
  205. forms.selectMusicStatus = true;
  206. prepareStore.setSelectMusicStatus(true);
  207. }}>
  208. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  209. <g fill="none">
  210. <path
  211. d="M5 6a1 1 0 0 1 1-1h2a1 1 0 0 0 0-2H6a3 3 0 0 0-3 3v2a1 1 0 0 0 2 0V6zm0 12a1 1 0 0 0 1 1h2a1 1 0 1 1 0 2H6a3 3 0 0 1-3-3v-2a1 1 0 1 1 2 0v2zM18 5a1 1 0 0 1 1 1v2a1 1 0 1 0 2 0V6a3 3 0 0 0-3-3h-2a1 1 0 1 0 0 2h2zm1 13a1 1 0 0 1-1 1h-2a1 1 0 1 0 0 2h2a3 3 0 0 0 3-3v-2a1 1 0 1 0-2 0v2z"
  212. fill="#198CFE"></path>
  213. </g>
  214. </svg>
  215. </div>
  216. ),
  217. default: () => (
  218. <>
  219. <NTabPane name="myMusic" tab="我的曲目">
  220. <SelectMusic
  221. from={props.from}
  222. cardType={props.cardType}
  223. type="myMusic"
  224. />
  225. </NTabPane>
  226. <NTabPane name="sahreMusic" tab="共享曲目">
  227. <SelectMusic
  228. from={props.from}
  229. cardType={props.cardType}
  230. type="sahreMusic"
  231. />
  232. </NTabPane>
  233. <NTabPane name="collectMusic" tab="收藏曲目">
  234. <SelectMusic
  235. from={props.from}
  236. cardType={props.cardType}
  237. type="collectMusic"
  238. />
  239. </NTabPane>
  240. </>
  241. )
  242. }}
  243. </NTabs>
  244. )}
  245. <NModal
  246. v-model:show={forms.selectResourceStatus}
  247. onUpdate:show={(val: any) => {
  248. if (!val) {
  249. prepareStore.setSelectResourceStatus(val);
  250. }
  251. }}
  252. class={['modalTitle', styles.selectMusicModal]}
  253. preset="card"
  254. title={'选择资源'}>
  255. <SelectResources type={forms.tabType} />
  256. </NModal>
  257. <NModal
  258. style={
  259. props.from === 'class'
  260. ? selectResourceStatusAddBoxDragData.styleDrag.value
  261. : {}
  262. }
  263. v-model:show={forms.selectMusicStatus}
  264. onUpdate:show={(val: any) => {
  265. if (!val) {
  266. prepareStore.setSelectMusicStatus(val);
  267. }
  268. }}
  269. class={[
  270. 'modalTitle',
  271. styles.selectMusicModal,
  272. selectResourceStatusAddBoxClass
  273. ]}
  274. preset="card"
  275. title={'选择曲目'}>
  276. <SelectMusicModal
  277. from={props.from}
  278. onAdd={(item: any) => onAdd(item)}
  279. />
  280. {props.from === 'class' && <Dragbom class={styles.dragbom}></Dragbom>}
  281. </NModal>
  282. <NModal
  283. style={
  284. props.from === 'class' ? workSetingBoxDragData.styleDrag.value : {}
  285. }
  286. v-model:show={forms.editStatus}
  287. class={[
  288. 'modalTitle background',
  289. styles.trainEditModal,
  290. workSetingBoxClass
  291. ]}
  292. preset="card"
  293. title="作业设置">
  294. <TrainUpdate
  295. item={forms.editItem}
  296. onClose={() => (forms.editStatus = false)}
  297. onConfirm={(item: any) => {
  298. const tList = typeFormat(
  299. item.trainingType,
  300. item.trainingConfigJson
  301. );
  302. const train = {
  303. ...item,
  304. id: null,
  305. musicName: forms.editItem.title,
  306. typeList: tList
  307. };
  308. eventGlobal.emit('onTrainAddItem', train);
  309. }}
  310. />
  311. {props.from === 'class' && <Dragbom class={styles.dragbom}></Dragbom>}
  312. </NModal>
  313. </div>
  314. );
  315. }
  316. });