lex-xin před 3 roky
rodič
revize
b433479f4c

+ 4 - 0
src/components/col-header/index.module.less

@@ -11,3 +11,7 @@
     }
   }
 }
+
+.headerSection {
+  min-height: var(--van-nav-bar-height);
+}

+ 21 - 9
src/components/col-header/index.tsx

@@ -44,6 +44,12 @@ export default defineComponent({
     this.headerTitle = this.title || this.$route.meta.title;
     this.navBarInit();
   },
+  unmounted() {
+    // 设置是否显示导航栏 0 显示 1 不显示
+    postMessage({ api: 'setBarStatus', content: { status: 1 } })
+    // 设置返回按钮颜色
+    postMessage({ api: 'backIconChange', content: { iconStyle: 'white' as backIconColor } })
+  },
   methods: {
     navBarInit() {
       // 设置是否显示导航栏 0 显示 1 不显示
@@ -82,15 +88,21 @@ export default defineComponent({
   render() {
     return (
       <>
-        <NavBar title={this.headerTitle}
-          style={{ paddingTop: `${this.navBarHeight}px`, height: this.titleHeight + 'px', lineHeight: this.titleHeight + 'px' }}
-          class={[this.background === 'green' ? styles.green : null, styles.colHeader]}
-          left-arrow={this.isBack}
-          rightText={this.rightText}
-          fixed={this.isFixed}
-          onClick-right={this.clickRight}
-          onClick-left={this.onClickLeft}></NavBar>
-          { this.$slots.default ? this.$slots.default() : null }
+        {this.$slots.content ?
+          <div style={{ paddingTop: `${this.navBarHeight}px` }} class={styles.headerSection}>
+            {this.$slots.content()}
+          </div> :
+          <><div style={{ paddingTop: `${this.navBarHeight}px` }} class={styles.headerSection}>
+            <NavBar title={this.headerTitle}
+              style={{ height: this.titleHeight + 'px', lineHeight: this.titleHeight + 'px' }}
+              class={[this.background === 'green' ? styles.green : null, styles.colHeader]}
+              left-arrow={this.isBack}
+              rightText={this.rightText}
+              fixed={this.isFixed}
+              onClick-right={this.clickRight}
+              onClick-left={this.onClickLeft}></NavBar>
+          </div>
+            {this.$slots.default ? this.$slots.default() : null}</>}
       </>
     )
   }

+ 2 - 2
src/components/col-img-code/index.tsx

@@ -22,7 +22,7 @@ export default defineComponent({
     let origin = window.location.origin
     return {
       showStatus: false,
-      identifyingCode: origin + '/api-student/code/getLoginImage?phone=' + this.phone,
+      identifyingCode: origin + '/api-teacher/code/getImageCode?phone=' + this.phone,
       code: null,
     }
   },
@@ -42,7 +42,7 @@ export default defineComponent({
   methods: {
     async updateIdentifyingCode() { // 刷新token
       let origin = window.location.origin
-      this.identifyingCode = `${origin}/api-student/code/getLoginImage?phone=${this.phone}&token=${Math.random()}`
+      this.identifyingCode = `${origin}/api-teacher/code/getImageCode?phone=${this.phone}&token=${Math.random()}`
     },
     async checkVerifyLoginImage() {
       try {

+ 12 - 15
src/components/col-popup/index.tsx

@@ -1,5 +1,6 @@
 import { Popup } from "vant";
 import { defineComponent } from "vue";
+import qs from 'query-string';
 
 export default defineComponent({
   name: 'col-popup',
@@ -16,9 +17,7 @@ export default defineComponent({
   },
   watch: {
     popupStatus(val) {
-      // if(val) {
-        this.onPopupClose(val)
-      // }
+      this.hashState()
     }
   },
   mounted() {
@@ -30,29 +29,27 @@ export default defineComponent({
   methods: {
     onHash() {
       this.$emit("update:popupStatus", false);
-      this.popupShow = false;
-      this.hashState();
     },
     onPopupClose(val: boolean) {
       this.$emit("update:popupStatus", val);
-      this.popupShow = val;
-
       this.hashState();
     },
     hashState() {
       // 打开弹窗
-      if (this.popupShow) {
-        const route = this.$route
-        let times = 0;
-        for (let i in route.query) {
-          times += 1
+      if (this.popupStatus) {
+        const splitUrl = window.location.hash.slice(1).split('?');
+        const query = qs.parse(splitUrl[1]);
+        let times = 0
+        for (let key in query) {
+          times++
         }
         const origin = window.location.href
         const url = times > 0 ? '&cPop=' + (+new Date()) : '?cPop=' + (+new Date())
         history.pushState("", "", `${origin}${url}`)
       } else {
-        const route = this.$route
-        if(route.query.cPop) {
+        const splitUrl = window.location.hash.slice(1).split('?');
+        const query = qs.parse(splitUrl[1]);
+        if (query.cPop) {
           window.history.go(-1)
         }
       }
@@ -63,7 +60,7 @@ export default defineComponent({
   },
   render() {
     return (
-      <Popup ref="protocolPopup" show={this.popupShow} position="bottom" style={{ height: '100%' }}>
+      <Popup ref="protocolPopup" show={this.popupStatus} transitionAppear={true} position="bottom" style={{ height: '100%' }}>
         {this.$slots.default && this.$slots.default()}
       </Popup>
     )

+ 1 - 1
src/components/col-result/index.module.less

@@ -1,7 +1,7 @@
 .col-result {
   padding: 30px 14px 14px;
   text-align: center;
-
+  margin: 0 auto;
   .tips {
     font-size: 14px;
     color: #333;

+ 10 - 4
src/components/col-result/index.tsx

@@ -1,7 +1,7 @@
 import { defineComponent } from "vue";
 import styles from './index.module.less';
 import empty from '@common/images/icon_nodata.png';
-import { Button, Image } from "vant";
+import { Button, Empty, Image } from "vant";
 import { postMessage } from "@/helpers/native-message";
 
 
@@ -15,6 +15,10 @@ export default defineComponent({
       type: String,
       default: empty
     },
+    btnStatus: {
+      type: Boolean,
+      default: true
+    },
     buttonText: {
       type: String,
       default: '我知道了'
@@ -33,11 +37,13 @@ export default defineComponent({
   render() {
     return (
       <div class={styles['col-result']}>
-        <Image fit="cover" width="100%" src={this.img} />
+        {/* <Image fit="cover" width="100%" src={this.img} /> */}
+        <Empty description={this.tips } />
 
-        { this.tips && <p class={styles.tips}>{ this.tips }</p> }
+        {/* { this.tips && <p class={styles.tips}>{ this.tips }</p> } */}
 
-        <Button class={styles.btn} round block type="primary" onClick={this.onResult}>我知道了</Button>
+        { this.btnStatus ? <Button class={styles.btn} round block type="primary" onClick={this.onResult}>{this.buttonText}</Button> : null }
+        
       </div>
     )
   }

+ 16 - 0
src/router/routes-teacher.ts

@@ -29,6 +29,22 @@ export default [
         meta: {
           title: '老师认证'
         }
+      },
+      {
+        path: 'openLive',
+        name: 'openLive',
+        component: () => import('@/teacher/open-live/index'),
+        meta: {
+          title: '开通直播'
+        }
+      },
+      {
+        path: 'musicCert',
+        name: 'musicCert',
+        component: () => import('@/teacher/music-cert/index'),
+        meta: {
+          title: '音乐人认证'
+        }
       }
     ]
   },

+ 1 - 1
src/state.ts

@@ -5,7 +5,7 @@ type status = 'init' | 'login' | 'logout' | 'error';
 export const state = reactive({
   user: {
     status: 'init' as status,
-    data: null as null | any
+    data: null as null | any,
   }
 });
 

+ 1 - 1
src/teacher/layout/auth.tsx

@@ -35,7 +35,7 @@ export default defineComponent({
       if ((state.user.status === 'init' || state.user.status === 'error')) {
         this.loading = true
         try {
-          let res = await request.get('/api-auth/api/queryUserInfo', {
+          let res = await request.get('/api-teacher/Teacher/queryUserInfo', {
             requestType: "form",
             initRequest: true // 初始化接口
           })

+ 1 - 1
src/teacher/layout/login.tsx

@@ -78,7 +78,7 @@ export default defineComponent({
         const { authentication } = res.data;
         setAuth(authentication.token_type + " " + authentication.access_token);
 
-        let userCash = await request.get('/api-student/userCashAccount/get', {
+        let userCash = await request.get('/api-teacher/Teacher/queryUserInfo', {
           initRequest: true // 初始化接口
         })
         setLogin(userCash.data)

+ 38 - 0
src/teacher/music-cert/index.module.less

@@ -0,0 +1,38 @@
+.music-cert {
+  background-color: #fff;
+  padding: 12px;
+  min-height: 100vh;
+  position: relative;
+  padding-bottom: 75px;
+
+  h2 {
+    font-size: 16px;
+    padding: 8px 0;
+    font-weight: 600;
+    color: #333333;
+    line-height: 1.5;
+  }
+
+  .cert-text {
+    font-size: 13px;
+    line-height: 1.3;
+    padding-bottom: 12px;
+    color: #999999;
+  }
+
+  .cert-img {
+    border-radius: 5px;
+    overflow: hidden;
+    line-height: 0;
+    margin-bottom: 8px;
+  }
+
+  .btn-group {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    padding: 12px;
+    background-color: #fff;
+  }
+}

+ 50 - 0
src/teacher/music-cert/index.tsx

@@ -0,0 +1,50 @@
+import { defineComponent } from "vue";
+import { Button, Image } from 'vant';
+import styles from './index.module.less';
+
+export default defineComponent({
+  name: 'music-cert',
+  data() {
+    return {
+      authStatus: null
+    }
+  },
+  methods: {
+    onClick() {
+      // teacherState.authStatus = true
+    }
+  },
+  render() {
+    return (
+      <div class={styles['music-cert']}>
+        <h2>音乐人认证是什么?</h2>
+        <p class={styles['cert-text']}>
+          酷乐秀对有能力编曲的音乐人开通上传曲谱权限,开通后您可上传自己编曲的乐谱MIDI让平台学员进行练习,并获取收益
+        </p>
+        <p class={styles['cert-img']}>
+          <Image src="https://daya.ks3-cn-beijing.ksyun.com/202110/Sn76BUQ.png" width="100%" height="150px" fit="cover" />
+        </p>
+
+        <h2>MIDI文件上传</h2>
+        <p class={styles['cert-text']}>
+          您可上传自己编曲的乐谱MIDI,并自定义乐谱价格,为平台学员提供智能陪练练习
+        </p>
+        <p class={styles['cert-img']}>
+          <Image src="https://daya.ks3-cn-beijing.ksyun.com/202110/Sn76BUQ.png" width="100%" height="150px" fit="cover" />
+        </p>
+
+        <h2>乐谱收益</h2>
+        <p class={styles['cert-text']}>
+          您可对上传的乐谱自定义价格,学员可自行挑选乐谱购买,购买后您将获取学员购买收入。
+        </p>
+        <p class={styles['cert-img']}>
+          <Image src="https://daya.ks3-cn-beijing.ksyun.com/202110/Sn76BUQ.png" width="100%" height="150px" fit="cover" />
+        </p>
+
+        <div class={styles["btn-group"]}>
+          <Button round block type="primary" disabled={this.authStatus === '1'} onClick={this.onClick}>立即认证</Button>
+        </div>
+      </div>
+    )
+  }
+})

binární
src/teacher/open-live/images/1.png


binární
src/teacher/open-live/images/2.png


binární
src/teacher/open-live/images/3.png


binární
src/teacher/open-live/images/header_bg.png


binární
src/teacher/open-live/images/icon_tips.png


+ 138 - 0
src/teacher/open-live/index.module.less

@@ -0,0 +1,138 @@
+.open-live {
+  overflow: hidden;
+  min-height: 100vh;
+  background: url('./images/header_bg.png') top center no-repeat;
+  background-size: contain;
+
+  .header-content {
+    display: flex;
+    height: var(--van-nav-bar-height);
+    align-items: center;
+    justify-content: flex-end;
+    padding: 0 17px;
+
+    :global {
+      .van-button--disabled {
+        font-weight: 500;
+        color: #999999;
+        line-height: 20px;
+        opacity: 0.6;
+      }
+    }
+  }
+
+  .openBtn {
+    background-color: #fff;
+    color: #FF4347;
+    padding: 0 15px;
+    font-size: 14px;
+  }
+
+  .open-teacher-info {
+    margin: 60px 14px 0;
+    width: auto;
+    background-color: transparent;
+    padding: 0;
+    .userLogo {
+      width: 56px;
+      height: 56px;
+      border-radius: 50%;
+      overflow: hidden;
+    }
+    :global {
+      .van-cell__value {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+      }
+    }
+
+    .teacher-info {
+      display: flex;
+      align-items: flex-start;
+      justify-content: center;
+      flex-direction: column;
+      padding-left: 8px;
+      .teacher-name {
+        font-weight: 500;
+        color: #1A1A1A;
+        line-height: 1.2;
+        font-size: 20px;
+        padding-top: 5px;
+        padding-bottom: 5px;
+      }
+      .level {
+        line-height: 1.2;
+      }
+    }
+
+    .teacher-desc {
+      display: flex;
+      align-items: center;
+      .teacherItem {
+        padding-left: 8px;
+        text-align: center;
+        min-width: 58px;
+        .title {
+          font-size: 17px;
+          font-weight: 500;
+          color: #000000;
+          line-height: 24px;
+        }
+        .content {
+          font-size: 12px;
+          font-weight: 400;
+          color: #666666;
+          line-height: 28px;
+        }
+      }
+    }
+  }
+
+  .open-tips {
+    margin: 12px 14px 0;
+    padding: 0 10px;
+    display: flex;
+    align-items: center;
+    background: #FFFFFF;
+    border-radius: 10px;
+    font-size: 13px;
+    color: #FF9E5A;
+    line-height: 22px;
+    height: 36px;
+    p {
+      padding-left: 5px;
+    }
+  }
+
+  .open-content {
+    border-radius: 10px;
+    margin: 12px 14px 40px;
+    background-color: #fff;
+    padding: 12px;
+    min-height: 100vh;
+    position: relative;
+
+    h2 {
+      font-size: 16px;
+      padding: 8px 0;
+      font-weight: 600;
+      color: #333333;
+      line-height: 1.5;
+    }
+
+    .cert-text {
+      font-size: 13px;
+      line-height: 1.3;
+      padding-bottom: 12px;
+      color: #999999;
+    }
+
+    .cert-img {
+      border-radius: 5px;
+      overflow: hidden;
+      line-height: 0;
+      margin-bottom: 8px;
+    }
+  }
+}

+ 84 - 0
src/teacher/open-live/index.tsx

@@ -0,0 +1,84 @@
+import { defineComponent } from "vue";
+import { Button, Cell, Icon, Image, NavBar, Rate, Sticky } from "vant";
+import styles from './index.module.less';
+
+import tips from './images/icon_tips.png';
+import banner1 from './images/1.png';
+import banner2 from './images/2.png';
+import banner3 from './images/3.png';
+import ColHeader from "@/components/col-header";
+
+export default defineComponent({
+  name: 'live-cert',
+  data() {
+    return {
+      rate: 4
+    }
+  },
+  render() {
+    return (
+      <div class={styles['open-live']}>
+        <ColHeader v-slots={{
+          content: () => (
+            <Sticky>
+              <div class={styles['header-content']}>
+                <Button round plain size="small" class={styles.openBtn}>开通直播</Button>
+              </div>
+            </Sticky>
+          )
+        }}>
+        </ColHeader>
+
+        <Cell class={styles['open-teacher-info']} border={false} v-slots={{
+          icon: () => (<Image class={styles.userLogo} src="https://daya.ks3-cn-beijing.ksyun.com/202108/SfbC1JU.jpeg" fit="cover" />)
+        }}>
+            <div class={styles['teacher-info']}>
+              <div class={styles['teacher-name']}>李老师</div>
+              <div class={styles.level}>
+                <Rate v-model={this.rate} color="#FFC459" void-icon="star" voidColor="#D6D6D6" size={15} />
+              </div>
+            </div>
+            <div class={styles['teacher-desc']}>
+              <div class={styles.teacherItem}>
+                <div class={styles.title}>12/20</div>
+                <div class={styles.content}>粉丝</div>
+              </div>
+              <div class={styles.teacherItem} style={{ textAlign: 'right' }}>
+                <div class={styles.title}>12/20</div>
+                <div class={styles.content}>已上课时</div>
+              </div>
+            </div>
+        </Cell>
+
+        <div class={styles['open-tips']}>
+          <Icon name={tips} size="16" />
+          <p>你尚未达到开通直播的条件</p>
+        </div>
+
+        <div class={styles['open-content']}>
+          <h2>开通直播能为您带来什么?</h2>
+          <p class={styles['cert-text']}>
+            酷乐秀对平台入驻的优秀老师开放直播及直播课程的功能,帮助老师拓展获客渠道及教学场景。
+          </p>
+          <p class={styles['cert-img']}>
+            <Image src={banner1} width="100%" height="150px" fit="contain" />
+          </p>
+          <h2>直播</h2>
+          <p class={styles['cert-text']}>
+            开通直播功能后,您可以创建自己的直播间开启直播。
+          </p>
+          <p class={styles['cert-img']}>
+            <Image src={banner2} width="100%" height="150px" fit="contain" />
+          </p>
+          <h2>直播课</h2>
+          <p class={styles['cert-text']}>
+            您可制定教学方案设置直播课程,学员购买后,您可在直播间对购买直播课的学员进行直播教学,直播课程无人数上限,可极大的提高课程收入。
+          </p>
+          <p class={styles['cert-img']}>
+            <Image src={banner3} width="100%" height="150px" fit="contain" />
+          </p>
+        </div>
+      </div>
+    )
+  }
+})

+ 9 - 9
src/teacher/teacher-cert/cert-info.tsx

@@ -18,11 +18,11 @@ export default defineComponent({
       <div class={styles['cert-info']}>
         <h2>认证酷乐秀老师能为您带来什么?</h2>
         <p class={styles['cert-text']}>
-            酷乐秀是一款为器乐学习者提供智能陪练及线上授课撮合的乐器教学平台,器乐老师可通过自身的专业知识位自己带来授课及曲谱销售收益。
-          </p>
-          <p class={styles['cert-img']}>
-            <Image src="https://daya.ks3-cn-beijing.ksyun.com/202110/Sn76BUQ.png" width="100%" height="150px" fit="cover" />
-          </p>
+          酷乐秀是一款为器乐学习者提供智能陪练及线上授课撮合的乐器教学平台,器乐老师可通过自身的专业知识位自己带来授课及曲谱销售收益。
+        </p>
+        <p class={styles['cert-img']}>
+          <Image src="https://daya.ks3-cn-beijing.ksyun.com/202110/Sn76BUQ.png" width="100%" height="150px" fit="cover" />
+        </p>
 
         <h2>线上授课</h2>
         <p class={styles['cert-text']}>
@@ -34,7 +34,7 @@ export default defineComponent({
 
         <h2>个人风采展示</h2>
         <p class={styles['cert-text']}>
-        可发布自己的专业经历、获奖记录及音视频资料对求学者展示,让学员更加深入的了解您的专业技能,从而提高约课率。
+          可发布自己的专业经历、获奖记录及音视频资料对求学者展示,让学员更加深入的了解您的专业技能,从而提高约课率。
         </p>
         <p class={styles['cert-img']}>
           <Image src="https://daya.ks3-cn-beijing.ksyun.com/202110/Sn76BUQ.png" width="100%" height="150px" fit="cover" />
@@ -42,7 +42,7 @@ export default defineComponent({
 
         <h2>曲谱上传</h2>
         <p class={styles['cert-text']}>
-        可上传您制作的MIDI乐谱为求学者提供学习曲目的途径,并从中获得收益。
+          可上传您制作的MIDI乐谱为求学者提供学习曲目的途径,并从中获得收益。
         </p>
         <p class={styles['cert-img']}>
           <Image src="https://daya.ks3-cn-beijing.ksyun.com/202110/Sn76BUQ.png" width="100%" height="150px" fit="cover" />
@@ -50,12 +50,12 @@ export default defineComponent({
 
         <h2>收益提现</h2>
         <p class={styles['cert-text']}>
-        在您授课及上传曲谱销售后,经过平台核算,将您获得的收益发放至您的个人账户下,您可随时将自己获得的收益提现。
+          在您授课及上传曲谱销售后,经过平台核算,将您获得的收益发放至您的个人账户下,您可随时将自己获得的收益提现。
         </p>
 
         <h2>酷乐秀欢迎您的加入!</h2>
         <p class={styles['cert-text']}>
-        在艺术的殿堂中,为他人照亮前进的道路,用自己的经验和点拨,传播艺术的种子,获取硕果。
+          在艺术的殿堂中,为他人照亮前进的道路,用自己的经验和点拨,传播艺术的种子,获取硕果。
         </p>
 
         <div class={styles["btn-group"]}>

+ 1 - 1
src/teacher/teacher-cert/cert-three.tsx

@@ -30,7 +30,7 @@ export default defineComponent({
 
         <div class={styles.items}>
           <ColField title="毕业证书">
-            <ColUpload deletable={false} v-model:value={teacherState.teacherCert.gradCertificate} tips="点击上传学历证书" />
+            <ColUpload v-model:value={teacherState.teacherCert.gradCertificate} tips="点击上传学历证书" />
           </ColField>
         </div>
 

+ 1 - 1
src/teacher/teacher-cert/index.tsx

@@ -55,7 +55,7 @@ export default defineComponent({
         console.log(res)
       } catch {
         //
-      } 
+      }
 
       teacherState.active = 2;
     },

+ 18 - 2
src/teacher/teacher-cert/module/subject-model.tsx

@@ -4,6 +4,8 @@ import styles from './subject-model.module.less';
 
 import checkBoxActive from '../images/checkbox_active.png';
 import checkBoxDefault from '../images/checkbox_default.png';
+import request from "@/helpers/request";
+import ColResult from "@/components/col-result";
 
 export default defineComponent({
   name: "subject-model",
@@ -15,14 +17,28 @@ export default defineComponent({
   },
   data() {
     return {
+      subjectList: [],
       checkBox: []
     }
   },
+  async mounted() {
+    try {
+      const res = await request.get('/api-teacher/subject/queryPage', {
+        params: {
+          rows: 100,
+          page: 1
+        }
+      })
+      console.log(res)
+    } catch {
+      // 
+    }
+  },
   render() {
     return (
       <div class={styles.subjects}>
         <div class={styles['subject-list']}>
-          {[1, 2, 3, 4, 5].map((item: any) => (
+          { this.subjectList.length ? [1, 2, 3, 4, 5].map((item: any) => (
             <div class={styles['subject-item']}>
             <Image src="https://daya.ks3-cn-beijing.ksyun.com/202110/Sn76BUQ.png" width="100%" height="100%" fit="cover" />
             <div class={styles.topBg}>
@@ -34,7 +50,7 @@ export default defineComponent({
               <p class={styles.name}>长笛</p>
             </div>
           </div>
-          )) }
+          )) : <ColResult tips="暂无声部数据" btnStatus={false} /> }
         </div>
 
         <div class={styles["btn-group"]}>

+ 1 - 1
src/teacher/teacher-cert/teacherState.ts

@@ -2,7 +2,7 @@ import { reactive } from 'vue';
 
 export const teacherState = reactive({
   authStatus: false, // 是否立即认证
-  active: 1,
+  active: 2,
   teacherCert: {
     realName: null,
     idCardNo: null,

+ 2 - 0
src/views/404/index.module.less

@@ -1,11 +1,13 @@
 .f404 {
   min-height: 100vh;
+  text-align: center;
   :global {
     .van-image {
       margin-top: 100px;
       width: 70%;
     }
     .van-button {
+      margin-top: 20px;
       background-color: transparent;
       height: 30px;
       line-height: 28px;