index.tsx 4.6 KB

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