index.tsx 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. import { computed, defineComponent, ref } from 'vue';
  2. import {
  3. NImage,
  4. NDivider,
  5. NButton,
  6. NModal,
  7. useMessage,
  8. ImageRenderToolbarProps
  9. } from 'naive-ui';
  10. import TheNoticeBar from '/src/components/TheNoticeBar';
  11. import styles from './index.module.less';
  12. import { PageEnum } from '/src/enums/pageEnum';
  13. import nodata from '../images/nomore.png';
  14. import CardPreview from '/src/components/card-preview';
  15. import { checkUrlType, iframeDislableKeyboard } from '/src/utils';
  16. import { useUserStore } from '/src/store/modules/users';
  17. import { vaildMusicScoreUrl } from '/src/utils/urlUtils';
  18. export default defineComponent({
  19. name: 'work-item',
  20. props: {
  21. item: {
  22. type: Object,
  23. default: () => ({})
  24. }
  25. },
  26. setup(props) {
  27. const userStore = useUserStore();
  28. const message = useMessage();
  29. const previewShow = ref(false);
  30. const preivewItem = ref({
  31. type: 'MUSIC',
  32. content: props.item.musicId,
  33. title: props.item.musicName
  34. });
  35. const reportSrc = ref('');
  36. const detailVisiable = ref(false);
  37. // const isDownload = computed(() => {
  38. // if (
  39. // props.item.fileList?.expireFlag &&
  40. // props.item.fileList?.fileType === 'EVALUATION'
  41. // ) {
  42. // return true;
  43. // } else {
  44. // return false;
  45. // }
  46. // });
  47. return () => (
  48. <div
  49. class={[
  50. styles.workItem,
  51. (props.item.fileList?.expireFlag || !props.item.fileList?.fileType) &&
  52. styles['work-content-disabled']
  53. ]}>
  54. <div
  55. class={[styles['work-content']]}
  56. style={{
  57. cursor: !props.item.fileList?.fileType ? 'default' : 'pointer'
  58. }}>
  59. {/* ("文件类型:评测:EVALUATION,IMG:图片,SOUND:音频,VIDEO:视频")
  60. private String fileType; */}
  61. {!props.item.fileList?.fileType && (
  62. <NImage
  63. src={nodata}
  64. class={styles.nodata}
  65. previewDisabled
  66. objectFit="contain"
  67. />
  68. )}
  69. {props.item.fileList?.fileType === 'IMG' && (
  70. <NImage
  71. src={props.item.fileList?.filePath}
  72. objectFit="contain"
  73. // renderToolbar={({ nodes }: ImageRenderToolbarProps) => {
  74. // return [
  75. // nodes.prev,
  76. // nodes.next,
  77. // nodes.rotateCounterclockwise,
  78. // nodes.rotateClockwise,
  79. // nodes.resizeToOriginalSize,
  80. // nodes.zoomOut,
  81. // nodes.close
  82. // ];
  83. // }}
  84. />
  85. )}
  86. {props.item.fileList?.fileType === 'SOUND' && (
  87. <div
  88. onClick={() => {
  89. preivewItem.value.content = props.item.fileList?.filePath;
  90. preivewItem.value.title = props.item.musicName;
  91. preivewItem.value.type = 'SONG';
  92. previewShow.value = true;
  93. }}>
  94. <NImage
  95. src={PageEnum.SONG_DEFAULT_COVER}
  96. previewDisabled
  97. objectFit="contain"
  98. />
  99. </div>
  100. )}
  101. {props.item.fileList?.fileType === 'EVALUATION' &&
  102. (checkUrlType(props.item.fileList?.content) === 'video' ? (
  103. <video
  104. style={{ height: '100%' }}
  105. src={props.item.fileList?.content}
  106. onClick={() => {
  107. preivewItem.value.content = props.item.fileList?.content;
  108. preivewItem.value.title = props.item.musicName;
  109. preivewItem.value.type = 'VIDEO';
  110. previewShow.value = true;
  111. }}
  112. />
  113. ) : (
  114. <div
  115. onClick={() => {
  116. preivewItem.value.content = props.item.fileList?.content;
  117. preivewItem.value.title = props.item.musicName;
  118. preivewItem.value.type = 'SONG';
  119. previewShow.value = true;
  120. }}>
  121. <NImage
  122. src={PageEnum.SONG_DEFAULT_COVER}
  123. previewDisabled
  124. objectFit="contain"
  125. />
  126. </div>
  127. ))}
  128. {/* 'https://oss.dayaedu.com/ktqy/1715586967518b42c4fe5.mp4' */}
  129. {props.item.fileList?.fileType === 'VIDEO' && (
  130. <video
  131. style={{ height: '100%' }}
  132. src={props.item.fileList?.filePath}
  133. onClick={() => {
  134. preivewItem.value.content = props.item.fileList?.filePath;
  135. preivewItem.value.title = props.item.musicName;
  136. preivewItem.value.type = 'VIDEO';
  137. previewShow.value = true;
  138. }}
  139. />
  140. )}
  141. {/* 判断是否过期 */}
  142. {props.item.fileList?.expireFlag && (
  143. <div class={styles.expireBg}>文件已过期</div>
  144. )}
  145. {props.item.recordId && (
  146. <NButton
  147. color="rgba(0,0,0,0.4)"
  148. textColor="#fff"
  149. disabled={props.item.fileList?.expireFlag}
  150. class={styles.reportBtn}
  151. onClick={() => {
  152. if (!props.item.recordId) {
  153. message.error('暂无评测记录');
  154. return;
  155. }
  156. const tockn = userStore.getToken;
  157. reportSrc.value =
  158. vaildMusicScoreUrl() +
  159. `/instrument/#/evaluat-report?id=${props.item.recordId}&Authorization=${tockn}`;
  160. detailVisiable.value = true;
  161. }}>
  162. 评测报告
  163. </NButton>
  164. )}
  165. </div>
  166. <div class={styles['work-footer']}>
  167. <div class={styles.trainInfo}>
  168. <div class={styles.trainName}>
  169. <span class={[styles.type, styles[props.item.trainingType]]}>
  170. {props.item.trainingType === 'EVALUATION' ? '评测' : '练习'}
  171. </span>
  172. <div class={styles['title-text']}>
  173. <TheNoticeBar text={props.item.musicName} />
  174. </div>
  175. </div>
  176. <div class={styles.tagList}>
  177. {props.item.typeList?.map((type: string, index: number) => (
  178. <>
  179. <span>{type}</span>
  180. {props.item.typeList.length - 1 > index && (
  181. <NDivider vertical />
  182. )}
  183. </>
  184. ))}
  185. </div>
  186. </div>
  187. {props.item.trainingType === 'EVALUATION' ? (
  188. <div class={[styles.scoreGroup, styles.scoreGroupEval]}>
  189. {props.item.trainingTimes}
  190. <span>分</span>
  191. </div>
  192. ) : (
  193. <div class={[styles.scoreGroup]}>
  194. {props.item.trainingTimes
  195. ? parseInt(props.item.trainingTimes / 60 + '')
  196. : 0}
  197. <span>分钟</span>
  198. </div>
  199. )}
  200. </div>
  201. <CardPreview
  202. v-model:show={previewShow.value}
  203. item={preivewItem.value}
  204. />
  205. <NModal
  206. v-model:show={detailVisiable.value}
  207. preset="card"
  208. class={['modalTitle background', styles.reportModel]}
  209. title={'评测报告'}>
  210. <div class={styles.reportContainer} style={{ lineHeight: 0 }}>
  211. <iframe
  212. width={'100%'}
  213. height={'450px'}
  214. frameborder="0"
  215. onLoad={(val: any) => {
  216. iframeDislableKeyboard(val.target);
  217. }}
  218. src={reportSrc.value}></iframe>
  219. </div>
  220. </NModal>
  221. </div>
  222. );
  223. }
  224. });