index.tsx 11 KB

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