index.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import MHeader from '@/components/m-header';
  2. import MSticky from '@/components/m-sticky';
  3. import { defineComponent, onMounted, reactive } from 'vue';
  4. import styles from './index.module.less';
  5. import { Button, Field, showToast } from 'vant';
  6. import MUploader from '@/components/m-uploader';
  7. import { api_userMusicDetail, api_userMusicSave } from '../api';
  8. import { useRoute, useRouter } from 'vue-router';
  9. import videoBg from '../images/videoBg.png';
  10. import { postMessage } from '@/helpers/native-message';
  11. export default defineComponent({
  12. name: 'creation-edit',
  13. setup() {
  14. const route = useRoute();
  15. const router = useRouter();
  16. const state = reactive({
  17. id: route.query.id,
  18. playType: '',
  19. musicDetail: {} as any,
  20. desc: '',
  21. videoImg: '', // 视频封面
  22. img: [] as any
  23. });
  24. const onSubmit = async () => {
  25. try {
  26. await api_userMusicSave({
  27. id: state.id,
  28. img: state.img.join(','),
  29. videoImg: state.videoImg,
  30. desc: state.desc || '我发布了一首演奏作品,快来听听吧~',
  31. musicPracticeRecordId: state.musicDetail.musicPracticeRecordId,
  32. type: 'FORMAL'
  33. });
  34. router.back();
  35. } catch {
  36. //
  37. }
  38. };
  39. // 截图
  40. const onCropper = () => {
  41. postMessage(
  42. {
  43. api: 'videoCrop',
  44. content: {
  45. url: state.musicDetail.videoUrl
  46. }
  47. },
  48. res => {
  49. if (res?.content.videoCover) {
  50. state.videoImg = res.content.videoCover;
  51. }
  52. }
  53. );
  54. };
  55. onMounted(async () => {
  56. try {
  57. const { data } = await api_userMusicDetail(state.id);
  58. state.musicDetail = data;
  59. state.desc = data.desc;
  60. state.videoImg = data.videoImg;
  61. state.img = data.img ? [data.img] : [];
  62. if (data?.videoUrl.lastIndexOf('mp4') !== -1) {
  63. state.playType = 'Video';
  64. } else {
  65. state.playType = 'Audio';
  66. }
  67. } catch {
  68. //
  69. }
  70. });
  71. return () => (
  72. <div>
  73. <MSticky position="top">
  74. <MHeader background={"#F1F1F1"} border={false} />
  75. </MSticky>
  76. <div class={[styles.section, styles.sectionFile]}>
  77. <div class={styles.uploadImg}>
  78. <MUploader
  79. class={styles.muploader}
  80. // native
  81. cropper
  82. deletable={false}
  83. v-model:modelValue={state.img}
  84. />
  85. {/* <div class={styles.tip}>选封面</div> */}
  86. </div>
  87. <div class={styles.musicDetail}>
  88. <p class={styles.musicName}>{state.musicDetail.musicSheetName}</p>
  89. <p class={styles.username}>{state.musicDetail.username}</p>
  90. </div>
  91. </div>
  92. {state.playType === 'Video' && (
  93. <div class={[styles.section, styles.sectionVideo]}>
  94. <img src={state.videoImg || videoBg} class={styles.videoBg} />
  95. <div class={styles.btnGroup}>
  96. <MUploader
  97. class={styles.btnImg}
  98. cropper
  99. deletable={false}
  100. onUploadChange={img => {
  101. if (img.length > 0) {
  102. state.videoImg = img[0];
  103. }
  104. }}
  105. options={{
  106. fixedNumber: [16, 9]
  107. }}
  108. />
  109. <div class={styles.btnCropper} onClick={onCropper}>
  110. 视频截取封面
  111. </div>
  112. </div>
  113. </div>
  114. )}
  115. <div class={styles.section}>
  116. <Field
  117. rows={4}
  118. autosize
  119. type="textarea"
  120. maxlength={150}
  121. placeholder="我发布了一首演奏作品,快来听听吧~"
  122. showWordLimit
  123. v-model={state.desc}
  124. />
  125. </div>
  126. <div class={styles.btnGroup}>
  127. <Button
  128. type="primary"
  129. round
  130. block
  131. color="linear-gradient(90deg, #44C9FF 0%, #259CFE 100%)"
  132. onClick={onSubmit}>
  133. {state.musicDetail.type === 'FORMAL' ? '保存' : '发布'}
  134. </Button>
  135. </div>
  136. </div>
  137. );
  138. }
  139. });