Browse Source

添加上传

lex 8 months ago
parent
commit
a0cfe1fcb9

+ 6 - 2
src/constant/music.ts

@@ -17,6 +17,10 @@ export const teacherChargeType = {
   2: '是',
   0: '否'
 }
+export const teacherPaymentType = {
+  CHARGE: '是',
+  FREE: '否',
+}
 
 /** 是否支持简谱 */
 export const teacherNotationType = {
@@ -37,8 +41,8 @@ export const teachershowFingeringType = {
 
 /** 老师端展示播放类型 */
 export const teachershowAudiType = {
-  MIDI: 'MIDI',
-  MP3: 'MP3'
+  MP3: 'MP3',
+  MIDI: 'MIDI'
 }
 
 /** 老师端展示是否包含节拍器类型 */

BIN
src/teacher/music/upload/images/error-icon.png


BIN
src/teacher/music/upload/images/message-top-bg.png


+ 23 - 1
src/teacher/music/upload/index.module.less

@@ -7,6 +7,20 @@
   background-color: #BEEBFD;
 }
 
+.uploadMessage {
+  position: absolute;
+  top: -100px;
+  right: -14px;
+  font-weight: 500;
+  font-size: 12px;
+  color: #FFFFFF;
+  line-height: 17px;
+  border-radius: 12px 0px 0px 12px;
+  background: rgba(0, 0, 0, 0.3);
+  padding: 3px 4px 3px 6px;
+  cursor: pointer;
+}
+
 .area {
   position: relative;
   padding: 44px 0 12px;
@@ -52,6 +66,14 @@
 
   }
 
+  .hideValue {
+    :global {
+      .van-field__value {
+        display: none;
+      }
+    }
+  }
+
   .fieldTypeBottom {
     flex-direction: column;
 
@@ -311,4 +333,4 @@
   margin: 0 0 12px;
   margin-top: 0 !important;
   position: relative;
-}
+}

+ 390 - 305
src/teacher/music/upload/index.tsx

@@ -14,7 +14,8 @@ import {
   Toast,
   NoticeBar,
   CellGroup,
-  Cell
+  Cell,
+  Dialog
 } from 'vant'
 import ColFieldGroup from '@/components/col-field-group'
 // import { MusicType } from 'src/teacher/music/list/item.d'
@@ -30,7 +31,8 @@ import {
   teachershowHasBeatType,
   teacherNotationType,
   teacherStyleType,
-  teacherExquisiteType
+  teacherExquisiteType,
+  teacherPaymentType
 } from '@/constant/music'
 import { getXmlInfo, FormatXMLInfo } from '@/helpers/music-xml'
 import Upload from './upload'
@@ -51,6 +53,7 @@ import {
 import { state } from '@/state'
 import ColHeader from '@/components/col-header'
 import ColSticky from '@/components/col-sticky'
+import MessageTip from './message-tip'
 
 export type BackgroundMp3 = {
   url?: string
@@ -72,7 +75,7 @@ export default defineComponent({
   data() {
     return {
       reason: '',
-      audioType: 'MP3',
+      playMode: 'MP3',
       xmlFileUrl: '',
       xmlFileLoading: false,
       midiUrl: '',
@@ -85,12 +88,12 @@ export default defineComponent({
       composer: '',
       remark: '',
       repeatedBeats: 0,
-      playSpeed: '',
+      playSpeed: null as any,
       hasBeat: 0,
       titleImg: '',
       accompanimentType: 'HOMEMODE',
       chargeType: 0,
-      paymentType: '',
+      paymentType: 'CHARGE',
       showFingering: 1,
       canEvaluate: 1,
       notation: 1,
@@ -121,46 +124,49 @@ export default defineComponent({
         }
       ] as BackgroundMp3[],
       checked: false,
+      messageTipStatus: false,
+      messageTipTitle: '上传须知',
+      messageTipType: 'upload' as 'upload' | 'error' | 'origin',
       cbsSubjectList: [] as any,
       cbsInstrumentList: [] as any
     }
   },
-  // watch: {
-  //   formated() {
-  //     this.mergeXmlData(this.formated)
+  watch: {
+    formated() {
+      this.mergeXmlData(this.formated)
+    }
+    // chargeType() {
+    //   if (this.chargeType === 0) {
+    //     this.musicPrice = ''
+    //     this.paymentType = ''
+    //   }
+    // }
+  },
+  // computed: {
+  //   choiceSubject() {
+  //     // 选择的科目
+  //     const tempArr: any[] = []
+  //     this.cbsSubjectList.forEach((parent: any) => {
+  //       if (this.subjectIds.includes(parent.id)) {
+  //         tempArr.push(parent as never)
+  //       }
+  //     })
+  //     console.log(tempArr, 'child', this.subjectIds, this.cbsSubjectList)
+  //     return tempArr
   //   },
-  //   chargeType() {
-  //     if (this.chargeType === 0) {
-  //       this.musicPrice = ''
-  //       this.paymentType = ''
-  //     }
+  //   choiceInstrument() {
+  //     const tempArr: any[] = []
+  //     this.cbsSubjectList.forEach((parent: any) => {
+  //       const instruments = parent.instruments || []
+  //       instruments.forEach(child => {
+  //         if (this.musicalInstrumentIdList.includes(child.id)) {
+  //           tempArr.push(child as never)
+  //         }
+  //       })
+  //     })
+  //     return tempArr
   //   }
   // },
-  computed: {
-    choiceSubject() {
-      // 选择的科目
-      const tempArr: any[] = []
-      this.cbsSubjectList.forEach((parent: any) => {
-        if (this.subjectIds.includes(parent.id)) {
-          tempArr.push(parent as never)
-        }
-      })
-      console.log(tempArr, 'child', this.subjectIds, this.cbsSubjectList)
-      return tempArr
-    },
-    choiceInstrument() {
-      const tempArr: any[] = []
-      this.cbsSubjectList.forEach((parent: any) => {
-        const instruments = parent.instruments || []
-        instruments.forEach(child => {
-          if (this.musicalInstrumentIdList.includes(child.id)) {
-            tempArr.push(child as never)
-          }
-        })
-      })
-      return tempArr
-    }
-  },
   async mounted() {
     // 获取基础数据
     request
@@ -170,7 +176,6 @@ export default defineComponent({
         }
       })
       .then((res: any) => {
-        console.log(res, 'res')
         const data = res.data || []
         data.forEach((item: any) => {
           if (item.paramName === 'music_sheet_service_fee') {
@@ -182,162 +187,142 @@ export default defineComponent({
       })
 
     // request
-    //   .get('/api-admin/subject/queryPage', {
-    //     data: { page: 1, row: -1 }
+    //   .post('/api-teacher/subject/queryPage', {
+    //     data: { page: 1, row: -1, parentSubjectId: 0 }
     //   })
     //   .then((response: any) => {
     //     console.log(response, 'response')
 
     //     const data = response.data.rows || []
     //     console.log(data, 'data')
-    //     const tempSubject = [] as any
-    //     data.forEach((item: any) => {
-    //       const temp = {
-    //         id: item.id,
-    //         name: item.name,
-    //         instruments: [] as any
-    //       }
-    //       const instruments = item.instruments || []
-    //       instruments.forEach(child => {
-    //         temp.instruments.push({
-    //           id: child.id,
-    //           name: child.name,
-    //           subjectId: child.subjectId
-    //         })
-    //       })
-    //       tempSubject.push(temp)
-    //     })
-    //     this.cbsSubjectList = tempSubject
     //   })
-    this.cbsSubjectList = [
+    // request
+    //   .get('/api-teacher/subject/subjectSelect', {
+    //     params: { parentSubjectId: 0 }
+    //   })
+    //   .then(res => {
+    //     console.log(res, '2112')
+    //   })
+    this.cbsInstrumentList = [
       {
-        id: 1,
-        name: '木管',
-        instruments: [
-          {
-            id: 1004,
-            name: '德式竖笛',
-            subjectId: 1
-          },
-          {
-            id: 1005,
-            name: '黄式竖笛',
-            subjectId: 1
-          }
-        ]
+        id: 1004,
+        name: '德式竖笛',
+        code: 'Tenor Recorder'
       },
       {
-        id: 7,
-        name: '单簧管',
-        instruments: [
-          {
-            id: 1006,
-            name: '德式竖笛1',
-            subjectId: 1
-          },
-          {
-            id: 1007,
-            name: '黄式竖笛2',
-            subjectId: 1
-          }
-        ]
+        id: 1005,
+        name: '英式竖笛',
+        code: 'Baroque Recorder'
       },
       {
-        id: 12,
-        name: '小号',
-        instruments: [
-          {
-            id: 1008,
-            name: '德式竖笛3',
-            subjectId: 1
-          },
-          {
-            id: 1009,
-            name: '黄式竖笛4',
-            subjectId: 1
-          }
-        ]
+        id: 1006,
+        name: '长笛',
+        code: 'Flute'
       },
       {
-        id: 13,
-        name: '圆号',
-        instruments: [
-          {
-            id: 2,
-            name: '德式笛',
-            subjectId: 1
-          },
-          {
-            id: 3,
-            name: '竖笛',
-            subjectId: 1
-          }
-        ]
+        id: 1007,
+        name: '中音萨克斯',
+        code: 'AltoSaxophone'
       },
       {
-        id: 14,
-        name: '长号',
-        instruments: [
-          {
-            id: 4,
-            name: '柠檬黄',
-            subjectId: 1
-          },
-          {
-            id: 5,
-            name: '天才',
-            subjectId: 1
-          }
-        ]
+        id: 1008,
+        name: '单簧管',
+        code: 'Clarinet'
+      },
+      {
+        id: 1009,
+        name: '黄式竖笛4',
+        code: 'Flute'
       }
-      // { id: 15, name: '上低音号', instruments: [] },
-      // { id: 17, name: '大号', instruments: [] },
-      // { id: 23, name: '小军鼓', instruments: [] },
-      // { id: 120, name: '英式竖笛', instruments: [] }
     ]
   },
   methods: {
-    onChoiceSubject(val: any) {
-      this.subJectVisible = false
-      this.subjectIds = [...val]
-    },
-    onRemoveSubject(val: any) {
-      const index = this.subjectIds.findIndex(s => s === val)
-      if (index > -1) {
-        this.subjectIds.splice(index, 1)
-
-        const cbsInstrumentList: any[] = []
-        this.cbsSubjectList.forEach(element => {
-          const index = this.subjectIds.findIndex(s => s === element.id)
-          if (index > -1) {
-            if (this.subjectIds.includes(element.id)) {
-              const instruments = element.instruments ? element.instruments : []
-              cbsInstrumentList.push(...instruments)
-            }
-          }
-        })
+    // onChoiceSubject(val: any) {
+    //   this.subJectVisible = false
+    //   this.subjectIds = [...val]
+    // },
+    // onRemoveSubject(val: any) {
+    //   const index = this.subjectIds.findIndex(s => s === val)
+    //   if (index > -1) {
+    //     this.subjectIds.splice(index, 1)
+
+    //     const cbsInstrumentList: any[] = []
+    //     this.cbsSubjectList.forEach(element => {
+    //       const index = this.subjectIds.findIndex(s => s === element.id)
+    //       if (index > -1) {
+    //         if (this.subjectIds.includes(element.id)) {
+    //           const instruments = element.instruments ? element.instruments : []
+    //           cbsInstrumentList.push(...instruments)
+    //         }
+    //       }
+    //     })
 
-        const tempInstrumentIds: any = []
-        this.musicalInstrumentIdList.forEach((item: any) => {
-          const index = cbsInstrumentList.findIndex(
-            instrument => instrument.id === item
+    //     const tempInstrumentIds: any = []
+    //     this.musicalInstrumentIdList.forEach((item: any) => {
+    //       const index = cbsInstrumentList.findIndex(
+    //         instrument => instrument.id === item
+    //       )
+    //       if (index > -1) {
+    //         tempInstrumentIds.push(item)
+    //       }
+    //     })
+    //     this.musicalInstrumentIdList = tempInstrumentIds
+    //   }
+    // },
+    // onChoiceInstrument(val: any) {
+    //   this.instrumentVisible = false
+    //   this.musicalInstrumentIdList = [...val]
+    // },
+    // onRemoveInstrument(val: any) {
+    //   const index = this.musicalInstrumentIdList.findIndex(s => s === val)
+    //   console.log(val, 'val', index, this.musicalInstrumentIdList)
+    //   if (index > -1) {
+    //     this.musicalInstrumentIdList.splice(index, 1)
+    //   }
+    // },
+    readerFile(file: File) {
+      const reader = new FileReader()
+      reader.onload = () => {
+        const xml = reader.result as string
+        const formated = getXmlInfo(xml)
+
+        let resultIndexStatus = false
+        const partNames = formated.partNames || []
+        for (const i of partNames) {
+          const index = this.cbsInstrumentList.findIndex(
+            cbs => cbs.code?.indexOf(i) > -1
           )
-          if (index > -1) {
-            tempInstrumentIds.push(item)
+          if (index === -1) {
+            resultIndexStatus = true
+            break
           }
-        })
-        this.musicalInstrumentIdList = tempInstrumentIds
+        }
+
+        if (partNames.length <= 0 || resultIndexStatus) {
+          this.messageTipStatus = true
+          this.messageTipTitle = '解析失败'
+          this.messageTipType = 'error'
+          this.xmlFileUrl = ''
+          return
+        }
+
+        this.formated = formated
       }
+      reader.readAsText(file)
     },
-    onChoiceInstrument(val: any) {
-      this.instrumentVisible = false
-      this.musicalInstrumentIdList = [...val]
-    },
-    onRemoveInstrument(val: any) {
-      const index = this.musicalInstrumentIdList.findIndex(s => s === val)
-      console.log(val, 'val', index, this.musicalInstrumentIdList)
-      if (index > -1) {
-        this.musicalInstrumentIdList.splice(index, 1)
+    mergeXmlData(data: FormatXMLInfo) {
+      this.formated = data
+      // this.backgroundMp3s = data.partNames.map((partName: string) => ({
+      //   track: partName
+      // }))
+      if (!this.musicSheetName) {
+        this.musicSheetName = data.title
+      }
+      if (!this.composer) {
+        this.composer = data.composer
+      }
+      if (!this.playSpeed && data.speed) {
+        this.playSpeed = '' + data.speed
       }
     },
     naiveXMLFile() {
@@ -349,9 +334,30 @@ export default defineComponent({
           this.xmlFileUrl = evt?.fileUrl || this.xmlFileUrl || ''
           this.xmlFileLoading = false
           if (this.xmlFileUrl) {
-            requestOrigin(this.xmlFileUrl).then(
-              res => (this.formated = getXmlInfo(res))
-            )
+            requestOrigin(this.xmlFileUrl).then(res => {
+              // this.formated = getXmlInfo(res)
+              const formated = getXmlInfo(res)
+
+              let resultIndexStatus = false
+              const partNames = formated.partNames || []
+              for (const i of partNames) {
+                const index = this.cbsInstrumentList.findIndex(
+                  cbs => cbs.code?.indexOf(i) > -1
+                )
+                if (index === -1) {
+                  resultIndexStatus = true
+                  break
+                }
+              }
+              if (partNames.length <= 0 || resultIndexStatus) {
+                this.messageTipStatus = true
+                this.messageTipTitle = '解析失败'
+                this.messageTipType = 'error'
+                this.xmlFileUrl = ''
+                return
+              }
+              this.formated = formated
+            })
           }
         }
       )
@@ -403,25 +409,7 @@ export default defineComponent({
       return num
     },
     fileName(name = '') {
-      return name.split('/').pop()
-    },
-    onDetail(type: string) {
-      let url = `${location.origin}/teacher/#/registerProtocol`
-
-      if (type === 'question') {
-        url = `${location.origin}/teacher/muic-standard/question.html`
-      } else if (type === 'music') {
-        url = `${location.origin}/teacher/muic-standard/index.html`
-      }
-
-      postMessage({
-        api: 'openWebView',
-        content: {
-          url,
-          orientation: 1,
-          isHideTitle: false
-        }
-      })
+      return name?.split('/').pop()
     }
   },
   render() {
@@ -432,17 +420,28 @@ export default defineComponent({
         <ColHeader hideHeader={false} background="transparent" border={false} />
 
         <CellGroup class={[styles.area, styles.topArea]}>
+          <div
+            class={styles.uploadMessage}
+            onClick={() => {
+              this.messageTipStatus = true
+              this.messageTipTitle = '上传须知'
+              this.messageTipType = 'upload'
+            }}
+          >
+            上传须知
+          </div>
+
           <div class={styles['section-title']}></div>
           <Field required label="播放类型" center inputAlign="right">
             {{
               input: () => (
                 <RadioGroup
                   class={styles['radio-group']}
-                  modelValue={this.audioType}
-                  onUpdate:modelValue={val => (this.audioType = val)}
+                  modelValue={this.playMode}
+                  onUpdate:modelValue={val => (this.playMode = val)}
                 >
                   {Object.keys(teachershowAudiType).map((item: string) => {
-                    const isActive = item === this.audioType
+                    const isActive = item === this.playMode
                     const type = isActive ? 'primary' : 'default'
                     return (
                       <Radio class={styles.radio} name={item}>
@@ -456,62 +455,111 @@ export default defineComponent({
               )
             }}
           </Field>
-          {/*  */}
-          {this.audioType === 'MP3' && (
-            <Field required label="伴奏类型" center inputAlign="right">
+
+          {this.playMode === 'MP3' ? (
+            <Field
+              name="mp3Url"
+              class={styles.fieldTypeBottom}
+              modelValue={this.mp3Url}
+              rules={[{ required: true, message: '请选择MP3文件' }]}
+            >
+              {{
+                label: () => (
+                  <div class={styles.fieldTitle}>
+                    <span>
+                      <i>*</i>上传伴奏
+                    </span>
+                    <span class={styles.titleTip}>仅支持MP3格式文件</span>
+                  </div>
+                ),
+                input: () => (
+                  <Button
+                    icon={UploadIcon}
+                    class={styles.upbtn}
+                    loading={this.mp3Loading}
+                    onClick={this.naiveMp3File}
+                  >
+                    {this.mp3Url ? this.fileName(this.mp3Url) : '上传伴奏文件'}
+                  </Button>
+                )
+              }}
+            </Field>
+          ) : (
+            <Field
+              name="midiUrl"
+              class={styles.fieldTypeBottom}
+              modelValue={this.midiUrl}
+              rules={[{ required: true, message: '请选择MIDI文件' }]}
+            >
               {{
+                label: () => (
+                  <div class={styles.fieldTitle}>
+                    <span>
+                      <i>*</i>上传MIDI
+                    </span>
+                    <span class={styles.titleTip}>仅支持MIDI格式文件</span>
+                  </div>
+                ),
                 input: () => (
-                  <RadioGroup
-                    class={styles['radio-group']}
-                    modelValue={this.accompanimentType}
-                    onUpdate:modelValue={val => (this.accompanimentType = val)}
+                  <Button
+                    icon={UploadIcon}
+                    class={styles.upbtn}
+                    loading={this.mp3Loading}
+                    onClick={this.naiveMp3File}
                   >
-                    {Object.keys(teacherStyleType).map((item: string) => {
-                      const isActive = item === String(this.accompanimentType)
-                      const type = isActive ? 'primary' : 'default'
-                      return (
-                        <Radio class={styles.radio} name={item}>
-                          <Tag size="large" plain={isActive} type={type}>
-                            {teacherStyleType[item]}
-                          </Tag>
-                        </Radio>
-                      )
-                    })}
-                  </RadioGroup>
+                    {this.midiUrl
+                      ? this.fileName(this.midiUrl)
+                      : '上传MIDI文件'}
+                  </Button>
                 )
               }}
             </Field>
           )}
+
           <Field
-            name="mp3Url"
+            name="xmlFileUrl"
             class={styles.fieldTypeBottom}
-            modelValue={this.mp3Url}
+            modelValue={this.xmlFileUrl}
             rules={[{ required: true, message: '请选择MusicXML文件' }]}
           >
             {{
               label: () => (
                 <div class={styles.fieldTitle}>
                   <span>
-                    <i>*</i>上传伴奏
+                    <i>*</i>上传XML
                   </span>
-                  <span class={styles.titleTip}>仅支持MP3格式文件</span>
+                  <span class={styles.titleTip}>仅支持XML/MXML格式文件</span>
                 </div>
               ),
-              input: () => (
-                <Button
-                  icon={UploadIcon}
-                  class={styles.upbtn}
-                  loading={this.mp3Loading}
-                  onClick={this.naiveMp3File}
-                >
-                  {this.mp3Url ? this.fileName(this.mp3Url) : '上传伴奏文件'}
-                </Button>
-              )
+              input: () =>
+                browser().isApp ? (
+                  <Button
+                    icon={UploadIcon}
+                    class={styles.upbtn}
+                    loading={this.xmlFileLoading}
+                    onClick={this.naiveXMLFile}
+                  >
+                    {this.xmlFileUrl
+                      ? this.fileName(this.xmlFileUrl)
+                      : '上传XML文件'}
+                  </Button>
+                ) : (
+                  <>
+                    <Upload
+                      onUpdate:modelValue={val => (this.xmlFileUrl = val)}
+                      accept=".xml"
+                      formatFile={this.readerFile}
+                    />
+                    <div style={{ marginLeft: '8px' }}>
+                      {this.fileName(this.xmlFileUrl)}
+                    </div>
+                  </>
+                )
             }}
           </Field>
+
           <Field
-            name="xmlFileUrl"
-            class={styles.fieldTypeBottom}
+            class={[styles.fieldTypeBottom, styles.hideValue]}
             modelValue={this.xmlFileUrl}
             rules={[{ required: true, message: '请选择MusicXML文件' }]}
           >
@@ -519,26 +567,54 @@ export default defineComponent({
               label: () => (
                 <div class={styles.fieldTitle}>
                   <span>
-                    <i>*</i>上传XML
+                    <i>*</i>上传原音
                   </span>
-                  <span class={styles.titleTip}>仅支持XML/MXML格式文件</span>
+                  <span class={styles.titleTip}>仅支持MP3格式文件</span>
                 </div>
-              ),
-              input: () => (
-                <Button
-                  icon={UploadIcon}
-                  class={styles.upbtn}
-                  loading={this.xmlFileLoading}
-                  onClick={this.naiveXMLFile}
-                >
-                  {this.xmlFileUrl
-                    ? this.fileName(this.xmlFileUrl)
-                    : '上传XML文件'}
-                </Button>
               )
             }}
           </Field>
+
           <Field
+            name="xmlFileUrl"
+            class={[styles.fieldTypeBottom, styles.musicTrack]}
+            modelValue={this.xmlFileUrl}
+          >
+            {{
+              label: () => (
+                <div class={styles.fieldTitle}>
+                  <span>所属轨道:长笛</span>
+                  <span class={styles.titleTip}>删除</span>
+                </div>
+              ),
+              input: () =>
+                browser().isApp ? (
+                  <Button
+                    icon={UploadIcon}
+                    class={styles.upbtn}
+                    loading={this.bgmp3Loading}
+                    onClick={this.naiveBGMp3File}
+                  >
+                    {this.xmlFileUrl
+                      ? this.fileName(this.xmlFileUrl)
+                      : '上传XML文件'}
+                  </Button>
+                ) : (
+                  <>
+                    <Upload
+                      onUpdate:modelValue={val => (this.xmlFileUrl = val)}
+                      accept=".xml"
+                      formatFile={this.readerFile}
+                    />
+                    <div style={{ marginLeft: '8px' }}>
+                      {this.fileName(this.xmlFileUrl)}
+                    </div>
+                  </>
+                )
+            }}
+          </Field>
+
+          {/* <Field
             label="可用声部"
             placeholder=""
             inputAlign="right"
@@ -575,8 +651,8 @@ export default defineComponent({
                   )
               }}
             </Field>
-          )}
-          <Field
+          )} */}
+          {/* <Field
             label="可用乐器"
             placeholder=""
             inputAlign="right"
@@ -584,22 +660,17 @@ export default defineComponent({
             required
             readonly
             onClick={() => {
-              if (this.subjectIds.length <= 0) {
-                Toast('请选择可以声部')
-                return
-              }
-              const cbsInstrumentList: any = []
-              this.cbsSubjectList.forEach(element => {
-                if (this.subjectIds.includes(element.id)) {
-                  const instruments = element.instruments
-                    ? element.instruments
-                    : []
-                  cbsInstrumentList.push(...instruments)
-                }
-              })
-              this.cbsInstrumentList = cbsInstrumentList
-              console.log(this.cbsInstrumentList, 'this.cbsInstrumentList')
-              this.instrumentVisible = true
+              // const cbsInstrumentList: any = []
+              // this.cbsSubjectList.forEach(element => {
+              //   if (this.subjectIds.includes(element.id)) {
+              //     const instruments = element.instruments
+              //       ? element.instruments
+              //       : []
+              //     cbsInstrumentList.push(...instruments)
+              //   }
+              // })
+              // this.cbsInstrumentList = cbsInstrumentList
+              // this.instrumentVisible = true
             }}
           ></Field>
           {this.choiceInstrument && this.choiceInstrument.length > 0 && (
@@ -628,7 +699,7 @@ export default defineComponent({
                   )
               }}
             </Field>
-          )}
+          )} */}
         </CellGroup>
 
         <CellGroup class={[styles.area]}>
@@ -693,7 +764,7 @@ export default defineComponent({
             }}
           </Field>
 
-          <Field
+          {/* <Field
             required
             label="重复节拍时长"
             name="repeatedBeats"
@@ -722,7 +793,7 @@ export default defineComponent({
                 </RadioGroup>
               )
             }}
-          </Field>
+          </Field> */}
           <Field
             required
             label="曲目速度"
@@ -771,7 +842,7 @@ export default defineComponent({
             />
           )}
 
-          <Field required label="是否精品" center inputAlign="right">
+          {/* <Field required label="是否精品" center inputAlign="right">
             {{
               input: () => (
                 <RadioGroup
@@ -795,25 +866,25 @@ export default defineComponent({
                 </RadioGroup>
               )
             }}
-          </Field>
+          </Field> */}
 
           <Field required label="是否收费" center inputAlign="right">
             {{
               input: () => (
                 <RadioGroup
                   class={styles['radio-group']}
-                  modelValue={this.chargeType}
+                  modelValue={this.paymentType}
                   onUpdate:modelValue={val => {
-                    this.chargeType = Number(val)
+                    this.paymentType = val
                   }}
                 >
-                  {Object.keys(teacherChargeType).map((item: string) => {
-                    const isActive = item === String(this.chargeType)
+                  {Object.keys(teacherPaymentType).map((item: string) => {
+                    const isActive = item === String(this.paymentType)
                     const type = isActive ? 'primary' : 'default'
                     return (
                       <Radio class={styles.radio} name={item}>
                         <Tag size="large" plain={isActive} type={type}>
-                          {teacherChargeType[item]}
+                          {teacherPaymentType[item]}
                         </Tag>
                       </Radio>
                     )
@@ -822,39 +893,44 @@ export default defineComponent({
               )
             }}
           </Field>
+          {this.paymentType === 'CHARGE' && (
+            <>
+              <Field
+                label="收费价格"
+                required
+                border={false}
+                class={styles.inputControl}
+                placeholder=" "
+                formatter={this.onFormatter}
+                v-slots={{ button: () => '元' }}
+                modelValue={this.musicPrice}
+                rules={[
+                  { required: true, validator, message: '请输入收费价格' }
+                ]}
+                onUpdate:modelValue={val => (this.musicPrice = val)}
+              />
 
-          <Field
-            label="收费价格"
-            required
-            border={false}
-            class={styles.inputControl}
-            placeholder=" "
-            formatter={this.onFormatter}
-            v-slots={{ button: () => '元' }}
-            modelValue={this.musicPrice}
-            rules={[{ required: true, validator, message: '请输入收费价格' }]}
-            onUpdate:modelValue={val => (this.musicPrice = val)}
-          />
+              <div class={styles.rule}>
+                <p>扣除手续费后该曲目预计收入为:</p>
+                <p>
+                  每人:
+                  <span>
+                    {(
+                      ((parseFloat(this.musicPrice || '0') || 0) *
+                        (100 - this.music_sheet_service_fee)) /
+                      100
+                    ).toFixed(2)}
+                  </span>
+                  元/人
+                </p>
 
-          <div class={styles.rule}>
-            <p>扣除手续费后该曲目预计收入为:</p>
-            <p>
-              每人:
-              <span>
-                {(
-                  ((parseFloat(this.musicPrice || '0') || 0) *
-                    (100 - this.music_sheet_service_fee)) /
-                  100
-                ).toFixed(2)}
-              </span>
-              元/人
-            </p>
-
-            <p>
-              您的乐谱收入在学员购买后{this.music_account_period}
-              天结算到您的账户中
-            </p>
-          </div>
+                <p>
+                  您的乐谱收入在学员购买后{this.music_account_period}
+                  天结算到您的账户中
+                </p>
+              </div>
+            </>
+          )}
         </CellGroup>
 
         <ColSticky position="bottom" background="transparent">
@@ -894,7 +970,7 @@ export default defineComponent({
           />
         </Popup>
 
-        <Popup
+        {/* <Popup
           show={this.subJectVisible}
           round
           closeable
@@ -928,7 +1004,7 @@ export default defineComponent({
             onConfirm={this.onChoiceInstrument}
             onClose={() => (this.instrumentVisible = false)}
           />
-        </Popup>
+        </Popup> */}
 
         <Popup
           show={this.tagVisibility}
@@ -947,6 +1023,15 @@ export default defineComponent({
             needAllButton={false}
           />
         </Popup>
+
+        <MessageTip
+          title={this.messageTipTitle}
+          type={this.messageTipType}
+          show={this.messageTipStatus}
+          onConfirm={() => {
+            this.messageTipStatus = false
+          }}
+        />
       </Form>
     )
   }

+ 106 - 0
src/teacher/music/upload/message-tip/index.module.less

@@ -0,0 +1,106 @@
+.wxPopupDialog {
+  // position: relative;
+  overflow: initial;
+
+  // margin-top: -160px;
+  &::before {
+    position: absolute;
+    content: ' ';
+    top: -23px;
+    left: 50%;
+    margin-left: -50px;
+    display: inline-block;
+    background: url('../images/bell.png') no-repeat top center;
+    background-size: contain;
+    width: 100px;
+    height: 60px;
+  }
+}
+
+.popupContainer {
+  background: url('../images/message-top-bg.png') no-repeat top center;
+  background-size: contain;
+  border-radius: 20px;
+  overflow: hidden;
+  padding-bottom: 16px;
+
+  .title1 {
+    padding-top: 57px;
+    text-align: center;
+    font-size: 18px;
+    font-weight: 500;
+    color: #000000;
+
+    span {
+      position: relative;
+      z-index: 1;
+
+      &::after {
+        content: '';
+        position: absolute;
+        left: 0;
+        bottom: 0;
+        z-index: -1;
+        width: 100%;
+        height: 8px;
+        background: linear-gradient(to right, rgba(45, 199, 170, 1), rgba(91, 236, 255, 0.20));
+      }
+    }
+  }
+
+  .popupTips {
+    position: relative;
+    font-size: 15px;
+    color: #777777;
+    line-height: 21px;
+
+
+    // &::before {
+    //   content: '';
+    //   position: absolute;
+    //   left: 0;
+    //   bottom: 0;
+    //   height: 54px;
+    //   width: 100%;
+    //   background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #FFFFFF 100%);
+    // }
+
+    .container {
+      max-height: 300px;
+      overflow-x: hidden;
+      overflow-y: auto;
+      padding: 16px 20px 0;
+    }
+
+    .cTitle {
+      font-weight: 600;
+      font-size: 15px;
+      color: #131415;
+      line-height: 23px;
+    }
+
+    .cContent {
+      font-size: 14px;
+      color: #777777;
+      line-height: 24px;
+      padding-bottom: 14px;
+
+      span {
+        color: #14BC9C;
+        cursor: pointer;
+        font-weight: 500;
+      }
+    }
+  }
+
+  .button {
+    padding: 0 32px;
+    width: calc(100% - 70px);
+    margin: 0 auto;
+    height: 40px;
+    font-weight: 600;
+    font-size: 16px;
+    color: #FFFFFF;
+    line-height: 22px;
+  }
+}

+ 157 - 0
src/teacher/music/upload/message-tip/index.tsx

@@ -0,0 +1,157 @@
+import { Button, Popup } from 'vant'
+import { PropType, defineComponent, onMounted, ref, watch } from 'vue'
+import styles from './index.module.less'
+import { postMessage } from '@/helpers/native-message'
+
+export default defineComponent({
+  name: 'message-tip',
+  props: {
+    // 是否显示微信弹窗
+    show: {
+      type: Boolean,
+      default: true
+    },
+    type: {
+      type: String as PropType<'upload' | 'error' | 'origin'>,
+      default: 'upload'
+    },
+    title: {
+      type: String,
+      default: '温馨提示'
+    },
+    showButton: {
+      type: Boolean,
+      default: true
+    },
+    buttonText: {
+      type: String,
+      default: '我已知晓'
+    }
+  },
+  emits: ['confirm'],
+  setup(props, { emit }) {
+    const showPopup = ref(false)
+    onMounted(() => {
+      if (props.show) {
+        showPopup.value = true
+        return
+      }
+    })
+
+    watch(
+      () => [props.show],
+      () => {
+        if (props.show) {
+          showPopup.value = true
+        } else {
+          showPopup.value = false
+        }
+      }
+    )
+    // props.title, props.type
+    // watch(
+    //   () => [props.title, props.type],
+    //   () => {}
+    // )
+
+    // 详情
+    const onDetail = (type: string) => {
+      let url = `${location.origin}/teacher/#/registerProtocol`
+
+      if (type === 'question') {
+        url = `${location.origin}/teacher/muic-standard/question.html`
+      } else if (type === 'music') {
+        url = `${location.origin}/teacher/muic-standard/index.html`
+      }
+
+      postMessage({
+        api: 'openWebView',
+        content: {
+          url,
+          orientation: 1,
+          isHideTitle: false
+        }
+      })
+    }
+    return () => (
+      <>
+        <Popup
+          v-model:show={showPopup.value}
+          round
+          style={{ width: '88%' }}
+          closeOnClickOverlay={false}
+          class={styles.wxPopupDialog}
+        >
+          <div class={styles.popupContainer}>
+            <p class={styles.title1}>
+              <span>{props.title}</span>
+            </p>
+            <div class={styles.popupTips}>
+              {props.type === 'upload' && (
+                <div class={styles.container}>
+                  <p class={styles.cTitle}>注意事项:</p>
+                  <div class={styles.cContent}>
+                    1、必须是上传人自己参与制作的作品 <br />
+                    2、歌曲及歌曲信息中请勿涉及政治、宗教、广告、涉毒、犯罪、色情、低俗、暴力、血腥、消极等违规内容,违反者直接删除内容。多次违反则进行封号处理;
+                    <br />
+                    3、点击查看
+                    <span onClick={() => onDetail('protocol')}>
+                      《用户注册协议》
+                    </span>
+                    ,如果您上传了文件,即认为您完全同意并遵守该协议的内容。
+                  </div>
+                  <p class={styles.cTitle}>曲谱审核标准:</p>
+                  <div class={styles.cContent}>
+                    1、文件大小不要超过5MB,不符合版面规范的乐谱,审核未通过的不予上架,详情参考《曲谱排版规范》;
+                    <br />
+                    2、XML与MIDI文件内容必须一致,推荐使用Sibelius打谱软件;导出设置:导出XML-未压缩(*.XML)/导出MIDI:音色-其他回放设备General
+                    MIDI、MIDI、MIDI文件类型-类型0、不要勾选“将弱拍小节导出为具有休止符的完整小节”。点击查看
+                    <span onClick={() => onDetail('question')}>
+                      《常见问题》
+                    </span>
+                  </div>
+                </div>
+              )}
+
+              {props.type === 'error' && (
+                <div class={styles.container}>
+                  <div class={styles.cContent}>
+                    声轨名称解析失败,请对照
+                    <span onClick={() => onDetail('protocol')}>
+                      《曲谱排版规范》
+                    </span>
+                    检查后重试
+                  </div>
+                </div>
+              )}
+
+              {props.type === 'origin' && (
+                <div class={styles.container}>
+                  <div class={styles.cContent}>
+                    1、同一首曲目不可重复上传,如有不同版本统一用“()”补充。举例:人生的旋转木马(长笛二重奏版)
+                    <br />
+                    2、曲目名后可添加曲目信息备注,包含但不限于曲目类型等。曲目名《XXX》,举例:人声的旋转木马《哈尔的移动城堡》(长笛二重奏版)
+                    <br />
+                    3、其他信息不要写在曲目名里,如歌手、上传人员昵称等。
+                  </div>
+                </div>
+              )}
+            </div>
+
+            {props.showButton && (
+              <Button
+                round
+                type="primary"
+                block
+                class={styles.button}
+                onClick={() => emit('confirm')}
+              >
+                {props.buttonText}
+              </Button>
+            )}
+          </div>
+        </Popup>
+      </>
+    )
+  }
+})