瀏覽代碼

Merge branch 'master' of http://git.dayaedu.com/lex/orchestra-app

mo 2 年之前
父節點
當前提交
aebe5f4525

二進制
src/common/images/icon_jiaofu.png


二進制
src/common/images/icon_zibei.png


+ 3 - 0
src/school/mass-message/component/class-list/index.tsx

@@ -119,6 +119,7 @@ export default defineComponent({
     }
 
     const onSelect = (type: string) => {
+      console.log(type, '2121')
       forms.checkboxRefs[type].toggle()
 
       const list: any = []
@@ -214,7 +215,9 @@ export default defineComponent({
                           name={item.id}
                           ref={(el: any) => (forms.checkboxRefs[item.id] = el)}
                           onClick={(e: any) => {
+                            e.preventDefault()
                             e.stopPropagation()
+                            onSelect(item.id)
                           }}
                         ></Checkbox>
                       )

+ 2 - 0
src/school/mass-message/component/manage-list/index.tsx

@@ -183,7 +183,9 @@ export default defineComponent({
                           name={item.id}
                           ref={(el: any) => (forms.checkboxRefs[item.id] = el)}
                           onClick={(e: any) => {
+                            e.preventDefault()
                             e.stopPropagation()
+                            onSelect(item.id)
                           }}
                         ></Checkbox>
                       )

+ 2 - 0
src/school/mass-message/component/student-list/index.tsx

@@ -179,7 +179,9 @@ export default defineComponent({
                           name={item.id}
                           ref={(el: any) => (forms.checkboxRefs[item.id] = el)}
                           onClick={(e: any) => {
+                            e.preventDefault()
                             e.stopPropagation()
+                            onSelect(item.id)
                           }}
                         ></Checkbox>
                       )

+ 2 - 0
src/school/mass-message/component/teacher-list/teacher-list.tsx

@@ -184,7 +184,9 @@ export default defineComponent({
                           name={item.id}
                           ref={(el: any) => (forms.checkboxRefs[item.id] = el)}
                           onClick={(e: any) => {
+                            e.preventDefault()
                             e.stopPropagation()
+                            onSelect(item.id)
                           }}
                         ></Checkbox>
                       )

+ 3 - 2
src/school/mass-message/create-message.tsx

@@ -21,11 +21,12 @@ import {
   TimePicker,
   Uploader
 } from 'vant'
-import { computed, defineComponent, getCurrentInstance, onMounted, reactive, watch } from 'vue'
+import { computed, defineComponent, onMounted, reactive } from 'vue'
 import styles from './index.module.less'
 import SelectSned from './select-sned'
 import iconStudent from '@common/images/icon_student.png'
 import iconTeacher from '@common/images/icon_teacher.png'
+import iconJiaoFu from '@common/images/icon_jiaofu.png'
 import ODialog from '@/components/o-dialog'
 import OSticky from '@/components/o-sticky'
 import { useRoute, useRouter } from 'vue-router'
@@ -379,7 +380,7 @@ export default defineComponent({
           {forms.receives.map((item: any) => {
             let img: any = iconStudent
             if (item.receiveType === 'CLASS') {
-              img = ''
+              img = iconJiaoFu
             } else if (item.receiveType === 'STUDENT') {
               img = iconStudent
             } else if (item.receiveType === 'TEACHER' || item.receiveType === 'SCHOOL') {

+ 8 - 0
src/school/mass-message/index.module.less

@@ -19,6 +19,14 @@
       }
     }
   }
+  .messageSend {
+    color: #aaaaaa;
+    :global {
+      .van-cell__value {
+        color: #aaaaaa;
+      }
+    }
+  }
 
   .send {
     color: #aaa;

+ 8 - 4
src/school/mass-message/index.tsx

@@ -132,13 +132,17 @@ export default defineComponent({
           >
             {state.list.map((item: any) => (
               <CellGroup inset onClick={() => onDetail(item)} style={{ marginBottom: '12px' }}>
-                <Cell class={styles.waitSend} titleStyle={{ flex: '1 auto' }}>
+                <Cell
+                  class={[styles.waitSend, item.sendStatus === 'SEND' && styles.messageSend]}
+                  titleStyle={{ flex: '1 auto' }}
+                >
                   {{
                     title: () => (
                       <div class={styles.time}>
-                        <Icon name="clock-o" class={styles.clockO} />
-                        {/* {item.sendStatus === 'WAIT' ? item.createTime : ''} */}
-                        {/* {item.sendStatus === 'SEND' ? item.sendTime : ''} */}
+                        {item.sendStatus === 'WAIT' && (
+                          <Icon name="clock-o" class={styles.clockO} />
+                        )}
+
                         {item.sendTime}
                       </div>
                     ),

+ 23 - 12
src/school/orchestra/compontent/information.tsx

@@ -53,7 +53,7 @@ export default defineComponent({
         page: 1,
         rows: 20
       },
-
+      statistics: {} as any,
       orchestraInfo: {} as any // 乐团详情
     })
 
@@ -107,6 +107,15 @@ export default defineComponent({
 
     const getDetails = async () => {
       try {
+        const { data } = await request.get('/api-school/orchestra/detail/' + route.query.id)
+        state.orchestraInfo = data || {}
+      } catch {
+        //
+      }
+    }
+
+    const getStatistics = async () => {
+      try {
         const { data } = await request.post('/api-school/classGroup/statistics', {
           data: {
             orchestraId: route.query.id,
@@ -114,7 +123,7 @@ export default defineComponent({
             endTime: state.params.endTime
           }
         })
-        state.orchestraInfo = data || {}
+        state.statistics = data || {}
 
         initNumCountUp()
       } catch {
@@ -164,16 +173,17 @@ export default defineComponent({
     const initNumCountUp = () => {
       nextTick(() => {
         // 在读学生
-        const orchestraInfo = state.orchestraInfo
-        new CountUp('currentStudentNum', orchestraInfo.studentNum || 0).start()
-        new CountUp('time1', orchestraInfo.attendanceRate || 0).start()
-        new CountUp('time2', orchestraInfo.homeworkRate || 0).start()
-        new CountUp('time3', orchestraInfo.homeworkQualifiedRate || 0).start()
+        const statistics = state.statistics
+        new CountUp('currentStudentNum', statistics.studentNum || 0).start()
+        new CountUp('time1', statistics.attendanceRate || 0).start()
+        new CountUp('time2', statistics.homeworkRate || 0).start()
+        new CountUp('time3', statistics.homeworkQualifiedRate || 0).start()
       })
     }
 
     onMounted(() => {
       getDetails()
+      getStatistics()
       getList()
     })
 
@@ -205,26 +215,26 @@ export default defineComponent({
         <Grid border={false} class={styles.gridContainer}>
           <GridItem>
             <p class={[styles.title, styles.red]}>
-              <span id="currentStudentNum">{state.orchestraInfo.studentNum || 0}</span>
+              <span id="currentStudentNum">{state.statistics.studentNum || 0}</span>
               <i>名</i>
             </p>
             <p class={styles.name}>在读学生</p>
           </GridItem>
           <GridItem>
             <p class={[styles.title, styles.red]}>
-              <span id="time1">{state.orchestraInfo.attendanceRate || 0}</span>%
+              <span id="time1">{state.statistics.attendanceRate || 0}</span>%
             </p>
             <p class={styles.name}>到课率</p>
           </GridItem>
           <GridItem>
             <p class={[styles.title, styles.red]}>
-              <span id="time2">{state.orchestraInfo.homeworkRate || 0}</span>%
+              <span id="time2">{state.statistics.homeworkRate || 0}</span>%
             </p>
             <p class={styles.name}>作业提交率</p>
           </GridItem>
           <GridItem>
             <p class={[styles.title, styles.red]}>
-              <span id="time3">{state.orchestraInfo.homeworkQualifiedRate || 0}</span>%
+              <span id="time3">{state.statistics.homeworkQualifiedRate || 0}</span>%
             </p>
             <p class={styles.name}>练习合格率</p>
           </GridItem>
@@ -271,7 +281,8 @@ export default defineComponent({
         )}
 
         {/*  */}
-        {state.orchestraInfo.type === 'DELIVERY' &&
+        {(state.orchestraInfo.deliveryType === 'SINGLE_DELIVERY' ||
+          state.orchestraInfo.deliveryType === 'MULTIPLE_DELIVERY') &&
           ['REGISTER', 'DOING', 'DONE'].includes(state.orchestraInfo.status) && (
             <OSticky position="bottom">
               <div class={'btnGroup'}>

+ 1 - 1
src/school/orchestra/modal/student-list.tsx

@@ -179,7 +179,7 @@ export default defineComponent({
     return () => (
       <div class={styles.studentList}>
         <OSticky position="top">
-          <OHeader title="选择学生" />
+          <OHeader title="选择学生" desotry={false} />
           <OSearch
             inputBackground="white"
             background="#F8F8F8"

+ 26 - 0
src/student/music-group/layout/index.module.less

@@ -73,4 +73,30 @@
       color: #000 !important;
     }
   }
+
+  .popupContainer {
+    .dialogTitle {
+      i {
+        display: inline-block;
+        width: 4px;
+        height: 14px;
+        background: #ff8057;
+        border-radius: 2px;
+        margin-right: 6px;
+      }
+
+      text-align: left;
+      font-size: 18px;
+      font-weight: 500;
+      color: #333333;
+      line-height: 25px;
+      padding: 20px 0 20px 25px;
+    }
+
+    .popupTips {
+      text-align: center;
+      padding: 15px 0 45px;
+      font-size: 16px;
+    }
+  }
 }

+ 65 - 5
src/student/music-group/layout/login.tsx

@@ -1,11 +1,12 @@
 import { defineComponent } from 'vue'
-import { CellGroup, Field, Button, CountDown, Row, Col, showToast } from 'vant'
+import { CellGroup, Field, Button, CountDown, Row, Col, showToast, Popup } from 'vant'
 import ImgCode from '@/components/o-img-code'
 import { checkPhone } from '@/helpers/validate'
 import { setLogin, state } from '@/state'
 import { removeAuth, setAuth } from './utils'
 import styles from './index.module.less'
 import request from '@/helpers/request'
+import { browser, getUrlCode } from '@/helpers/utils'
 
 type loginType = 'PWD' | 'SMS'
 export default defineComponent({
@@ -19,7 +20,9 @@ export default defineComponent({
       countDownStatus: true, // 是否发送验证码
       countDownTime: 1000 * 120, // 倒计时时间
       // countDownRef: null as any, // 倒计时实例
-      imgCodeStatus: false
+      imgCodeStatus: false,
+      showPopup: false,
+      code: '' // 授权code码
     }
   },
   computed: {
@@ -32,15 +35,57 @@ export default defineComponent({
   mounted() {
     removeAuth()
     this.directNext()
+
+    // 判断是否是微信,只能微信中打开
+    if (browser().weixin) {
+      // 微信公众号支付
+      //授权
+      const code = getUrlCode()
+      console.log('login mounted code: ' + code)
+      if (!code) {
+        this.getAppIdAndCode()
+      } else {
+        this.code = code
+      }
+    } else {
+      this.showPopup = true
+    }
   },
   methods: {
+    async getAppIdAndCode() {
+      try {
+        const { data } = await request.get('/api-student/open/paramConfig/wechatAppId')
+        // 判断是否有微信appId
+        if (data) {
+          this.goAuth(data)
+        }
+      } catch {
+        //
+      }
+    },
+    goAuth(wxAppId: string) {
+      // 用户授权
+      const urlNow = encodeURIComponent(window.location.href)
+      const scope = 'snsapi_base' //snsapi_userinfo   //静默授权 用户无感知
+      const appid = wxAppId || 'wx8654c671631cfade'
+      const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${urlNow}&response_type=code&scope=${scope}&state=STATE&connect_redirect=1#wechat_redirect`
+      window.location.replace(url)
+    },
     directNext() {
       if (state.user.status === 'login' || state.user.status === 'error') {
         const { returnUrl, isRegister, ...rest } = this.$route.query
+        console.log(
+          {
+            ...rest,
+            code: this.code
+          },
+          'jump pre registration'
+        )
         this.$router.replace({
           path: returnUrl as any,
           query: {
-            ...rest
+            ...rest,
+            code: this.code
           }
         })
       }
@@ -136,8 +181,7 @@ export default defineComponent({
                 placeholder="请输入验证码"
                 type="tel"
                 maxlength={6}
-                // @ts-ignore
-                vSlots={{
+                v-slots={{
                   button: () =>
                     this.countDownStatus ? (
                       <span class={styles.codeText} onClick={this.onSendCode}>
@@ -173,6 +217,22 @@ export default defineComponent({
             onSendCode={this.onCodeSend}
           />
         ) : null}
+
+        <Popup
+          v-model:show={this.showPopup}
+          round
+          style={{ width: '92%' }}
+          closeOnClickOverlay={false}
+        >
+          <div class={styles.popupContainer}>
+            <div class={styles.dialogTitle}>
+              <i></i>
+              提示
+            </div>
+
+            <p class={styles.popupTips}>请使用微信打开</p>
+          </div>
+        </Popup>
       </div>
     )
   }

+ 21 - 2
src/student/music-group/pre-apply/component/apply.tsx

@@ -13,8 +13,9 @@ import {
   Tag
 } from 'vant'
 import { defineComponent, onMounted, reactive } from 'vue'
-import { useRoute } from 'vue-router'
+import { useRoute, useRouter } from 'vue-router'
 import styles from '../index.module.less'
+import { setLogout } from '@/state'
 
 // 乐团交付,乐团停止或关闭,有新的交付团;则不允许报名
 const classList: any = []
@@ -37,7 +38,9 @@ export default defineComponent({
   emits: ['next'],
   setup(props, { slots, attrs, emit }) {
     const route = useRoute()
+    const router = useRouter()
     const state = reactive({
+      code: '' as any, // 微信授权code码
       detail: {} as any, // 学生详情
       currentGrade: [
         { text: '一年级', value: 1 },
@@ -153,7 +156,8 @@ export default defineComponent({
         }
         await request.post('/api-student/orchestraRegister/save', {
           data: {
-            ...params
+            ...params,
+            code: state.code
           }
         })
         setTimeout(() => {
@@ -166,12 +170,27 @@ export default defineComponent({
     }
 
     onMounted(async () => {
+      state.code = route.query.code || ''
+      console.log('pre register code: ' + state.code)
       await getSubjects()
       // 判断学年制
       if (props.schoolSystem === 'sixYearSystem') {
         state.currentGrade.push({ text: '六年级', value: 6 })
       }
       await studentRegister()
+
+      // 判断是否有授权码
+      if (!state.code) {
+        setLogout()
+        const query = {
+          returnUrl: route.path,
+          ...route.query
+        } as any
+        router.replace({
+          path: '/loginMusic',
+          query: query
+        })
+      }
     })
     return () => (
       <>

+ 26 - 0
src/student/music-group/pre-apply/index.module.less

@@ -15,6 +15,32 @@
     }
   }
 
+  .popupContainer {
+    .dialogTitle {
+      i {
+        display: inline-block;
+        width: 4px;
+        height: 14px;
+        background: #ff8057;
+        border-radius: 2px;
+        margin-right: 6px;
+      }
+
+      text-align: left;
+      font-size: 18px;
+      font-weight: 500;
+      color: #333333;
+      line-height: 25px;
+      padding: 20px 0 20px 25px;
+    }
+
+    .popupTips {
+      text-align: center;
+      padding: 15px 0 45px;
+      font-size: 16px;
+    }
+  }
+
   .banner {
     background: url('./images/banner.png') no-repeat center center;
     background-size: cover;

+ 54 - 1
src/student/music-group/pre-apply/index.tsx

@@ -1,5 +1,5 @@
 import { defineComponent, onMounted, reactive, ref, nextTick } from 'vue'
-import { Image, showDialog, Sticky, Tab, Tabs } from 'vant'
+import { Image, Popup, showDialog, Sticky, Tab, Tabs } from 'vant'
 import styles from './index.module.less'
 // import { useRect } from '@vant/use'
 import Apply from './component/apply'
@@ -9,6 +9,7 @@ import { useRoute, useRouter } from 'vue-router'
 
 import { setLogout } from '@/state'
 import request from '@/helpers/request'
+import { browser, getUrlCode } from '@/helpers/utils'
 
 export default defineComponent({
   name: 'pre-apply',
@@ -22,6 +23,8 @@ export default defineComponent({
       registerInfo: {} as any,
       purchase: false, // 购买状态
       register: true // 是否注册
+      // showPopup: false,
+      // code: '' as any
     })
 
     const onNext = async (name: string) => {
@@ -120,12 +123,46 @@ export default defineComponent({
       }
     }
 
+    // const getAppIdAndCode = async () => {
+    //   try {
+    //     const { data } = await request.get('/api-student/open/paramConfig/wechatAppId')
+    //     // 判断是否有微信appId
+    //     if (data) {
+    //       goAuth(data)
+    //     }
+    //   } catch {
+    //     //
+    //   }
+    // }
+    // const goAuth = (wxAppId: string) => {
+    //   // 用户授权
+    //   const urlNow = encodeURIComponent(window.location.href)
+    //   const scope = 'snsapi_base' //snsapi_userinfo   //静默授权 用户无感知
+    //   const appid = wxAppId || 'wx8654c671631cfade'
+    //   const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${urlNow}&response_type=code&scope=${scope}&state=STATE&connect_redirect=1#wechat_redirect`
+    //   window.location.replace(url)
+    // }
+
     // 先请求接口
     getRegisterStatus()
 
     onMounted(() => {
+      // state.code = route.query.code || ''
       // const { height } = useRect(bannerRef.value)
       // state.heightV = height
+      // 判断是否是微信,只能微信中打开
+      // if (browser().weixin) {
+      //   // 微信公众号支付
+      //   //授权
+      //   const code = getUrlCode()
+      //   if (!code || !state.code) {
+      //     getAppIdAndCode()
+      //   } else {
+      //     state.code = code
+      //   }
+      // } else {
+      //   state.showPopup = true
+      // }
     })
     return () => (
       <div class={styles.preApply}>
@@ -157,6 +194,22 @@ export default defineComponent({
         )}
         {state.tabValue === 'payment' && <Payment onNext={onNext} />}
         {state.tabValue === 'order' && <Order onNext={onNext} />}
+
+        {/* <Popup
+          v-model:show={state.showPopup}
+          round
+          style={{ width: '92%' }}
+          closeOnClickOverlay={false}
+        >
+          <div class={styles.popupContainer}>
+            <div class={styles.dialogTitle}>
+              <i></i>
+              提示
+            </div>
+
+            <p class={styles.popupTips}>请使用微信打开</p>
+          </div>
+        </Popup> */}
       </div>
     )
   }

+ 8 - 4
src/student/my-orchestra/apply-withdrawal.tsx

@@ -19,7 +19,7 @@ export default defineComponent({
     })
     const forms = reactive({
       status: false,
-      reason: null,
+      reason: '',
       id: route.query.id,
       dataInfo: {} as any,
       isClick: false
@@ -81,7 +81,11 @@ export default defineComponent({
           />
 
           <div class={styles.userInfo}>
-            <Image src={forms.dataInfo.studentAvatar || iconStudent} class={styles.img} />
+            <Image
+              src={forms.dataInfo.studentAvatar || iconStudent}
+              class={styles.img}
+              fit="cover"
+            />
             <div class={styles.userName}>{forms.dataInfo.studentName} 同学</div>
             <div class={styles.timer}>
               您已在{forms.dataInfo.orchestraName}训练<span>{forms.dataInfo.joinDays}</span>天
@@ -90,7 +94,7 @@ export default defineComponent({
         </div>
         <div class={styles.content}>
           <span>在乐团训练的日子里,</span>
-          有付出有汗水,从0到1的喜悦也有攻克难关的坚持。你的付出为你带来成长,你的成长让老师感到欣喜。
+          有付出有汗水,从0到1的喜悦也有攻克难关的坚持。你的付出为你带来成长,你的成长让老师感到欣喜。
         </div>
 
         <div class={styles.resion}>
@@ -98,7 +102,7 @@ export default defineComponent({
             <div class={styles.name}>
               <i></i>退团原因<span>*</span>
             </div>
-            <div class={styles.nums}>0/400</div>
+            <div class={styles.nums}>{forms.reason.length || 0}/400</div>
           </div>
           <Field v-model={forms.reason} placeholder="请输入退团详细原因" type="textarea" rows={3} />
         </div>

+ 2 - 2
src/views/courseList/index.tsx

@@ -115,15 +115,15 @@ export default defineComponent({
             )
           })}
         </Grid>
+        {!data.list.length && <Empty description="空空如也" />}
         {/* <Button
           onClick={() => {
             location.href =
-              'http://192.168.3.114:1000/teacher.html#/coursewarePlay?id=1610595720511209474'
+              'http://192.168.3.114:1000/teacher.html#/coursewarePlay?id=1610595720511209474&courseId=1612270880549044226'
           }}
         >
           测试
         </Button> */}
-        {!data.list.length && <Empty description="空空如也" />}
       </div>
     )
   }

+ 1 - 1
src/views/coursewarePlay/component/musicScore.tsx

@@ -13,7 +13,7 @@ export default defineComponent({
   setup(props, {}) {
     const Authorization = sessionStorage.getItem('Authorization') || ''
     const origin = /(localhost|192)/.test(location.host)
-      ? 'http://192.168.3.114:3000'
+      ? 'https://ponline.colexiu.com'//'http://192.168.3.114:3000'
       : location.origin
     const query = qs.stringify({
       id: props.music.content,

+ 24 - 0
src/views/coursewarePlay/image/icon-dian.svg

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>切片</title>
+    <defs>
+        <path d="M23.21608,16.0687402 L23.3033009,16.1464466 C23.6659306,16.5090763 23.6918327,17.0809217 23.3810072,17.4734394 L23.3033009,17.5606602 L17.6464466,23.2175144 C17.2838169,23.5801441 16.7119715,23.6060462 16.3194539,23.2952208 L16.232233,23.2175144 L12.6966991,19.6819805 C12.3061748,19.2914562 12.3061748,18.6582912 12.6966991,18.267767 C13.0593288,17.9051373 13.6311742,17.8792351 14.0236919,18.1900606 L14.1109127,18.267767 L16.9384817,21.0967502 L21.8890873,16.1464466 C22.251717,15.7838169 22.8235624,15.7579148 23.21608,16.0687402 Z M11,0 C14.8659932,0 18,3.13400675 18,7 C18,9.41274397 16.7793245,11.5403839 14.9218582,12.7990351 C15.9323681,13.229421 16.8689386,13.8268917 17.694678,14.5714883 C18.1048344,14.9413398 18.1375079,15.5736612 17.7676564,15.9838176 C17.3978048,16.393974 16.7654834,16.4266475 16.355327,16.0567959 C14.8954225,14.7403517 13.0066893,14 11,14 C6.581722,14 3,17.581722 3,22 C3,22.5522847 2.55228475,23 2,23 C1.44771525,23 1,22.5522847 1,22 C1,17.8693735 3.50442274,14.3236863 7.07765565,12.7985509 C5.22023262,11.5396119 4,9.41230625 4,7 C4,3.13400675 7.13400675,0 11,0 Z M11,2 C8.23857625,2 6,4.23857625 6,7 C6,9.76142375 8.23857625,12 11,12 C13.7614237,12 16,9.76142375 16,7 C16,4.23857625 13.7614237,2 11,2 Z" id="path-1"></path>
+        <filter x="-13.3%" y="-12.8%" width="126.6%" height="125.5%" filterUnits="objectBoundingBox" id="filter-2">
+            <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.125792177 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="课件播放(老师)" transform="translate(-740.000000, -151.000000)" fill-rule="nonzero">
+            <g id="编组-8" transform="translate(732.000000, 66.000000)">
+                <g id="编组-7" transform="translate(0.000000, 75.000000)">
+                    <g id="形状结合" transform="translate(8.000000, 10.000000)">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
+                        <use fill="#FFFFFF" xlink:href="#path-1"></use>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 15 - 9
src/views/coursewarePlay/image/icon-menu.svg

@@ -2,19 +2,25 @@
 <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
     <title>切片</title>
     <defs>
-        <path d="M8.41697068,5.70140135 L20.095405,5.70140135 C20.5949959,5.70140135 21,5.29824534 21,4.80093423 C21,4.30362313 20.5949959,3.90046712 20.095405,3.90046712 L8.41697068,3.90046712 C7.91737983,3.90046712 7.51237569,4.30362313 7.51237569,4.80093423 C7.51237569,5.29824534 7.91737983,5.70140135 8.41697068,5.70140135 Z M8.41671626,12.883105 L20.0522954,12.883105 C20.5518863,12.883105 20.9568904,12.479949 20.9568904,11.9826379 C20.9568904,11.4853268 20.5518863,11.0821708 20.0522954,11.0821708 L8.41671626,11.0821708 C7.91712541,11.0821708 7.51212128,11.4853268 7.51212128,11.9826379 C7.51212128,12.479949 7.91712541,12.883105 8.41671626,12.883105 Z M20.095405,18.3036919 L8.41697068,18.3036919 C7.91737983,18.3036919 7.51237569,18.7068479 7.51237569,19.204159 C7.51237569,19.7014701 7.91737983,20.1046261 8.41697068,20.1046261 L20.095405,20.1046261 C20.5949959,20.1046261 21,19.7014701 21,19.204159 C21,18.7068479 20.5949959,18.3036919 20.095405,18.3036919 L20.095405,18.3036919 Z M2,4.80093423 C2,5.79556275 2.81000194,6.60186847 3.80918997,6.60186847 C4.808378,6.60186847 5.61837994,5.79556275 5.61837994,4.80093423 C5.61837994,3.80630572 4.808378,3 3.80918997,3 C2.81000194,3 2,3.80630572 2,4.80093423 Z M2,11.9718604 C2,12.9664889 2.81000194,13.7727946 3.80918997,13.7727946 C4.808378,13.7727946 5.61837994,12.9664889 5.61837994,11.9718604 C5.61837994,10.9772319 4.808378,10.1709262 3.80918997,10.1709262 C2.81000194,10.1709262 2,10.9772319 2,11.9718604 Z M2,19.1990658 C2,20.1936943 2.81000194,21 3.80918997,21 C4.808378,21 5.61837994,20.1936943 5.61837994,19.1990658 C5.61837994,18.2044373 4.808378,17.3981315 3.80918997,17.3981315 C2.81000194,17.3981315 2,18.2044373 2,19.1990658 Z" id="path-1"></path>
-        <filter x="-15.8%" y="-16.7%" width="131.6%" height="133.3%" filterUnits="objectBoundingBox" id="filter-2">
-            <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+        <path d="M12,12.5 L12,5.83333333 C13.3333333,4.64814815 14.6666667,4.05555556 16,4.05555556 C17.3333333,4.05555556 18.6666667,4.05555556 20,4.05555556 L20,19.1666667 C18.7195163,19.1666667 18.4037995,19.1666667 17.0528496,19.1666667 C15.7018997,19.1666667 13.3509499,18.7592593 12,19.9444444 C10.4052541,18.7592593 7.98478324,19.1666667 6.73858743,19.1666667 C5.49239162,19.1666667 5.24619581,19.1666667 4,19.1666667 L4,4.05555556 C5.33333333,4.05555556 6.66666667,4.05555556 8,4.05555556" id="path-1"></path>
+        <filter x="-25.0%" y="-25.2%" width="150.0%" height="150.3%" filterUnits="objectBoundingBox" id="filter-2">
+            <feMorphology radius="1" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
+            <feOffset dx="0" dy="0" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
+            <feMorphology radius="1" operator="erode" in="SourceAlpha" result="shadowInner"></feMorphology>
+            <feOffset dx="0" dy="0" in="shadowInner" result="shadowInner"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="shadowInner" operator="out" result="shadowOffsetOuter1"></feComposite>
             <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
             <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.125792177 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
         </filter>
     </defs>
-    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="课件播放(学生)" transform="translate(-741.000000, -157.000000)" fill-rule="nonzero">
-            <g id="编组-4" transform="translate(734.000000, 147.000000)">
-                <g id="形状结合" transform="translate(7.000000, 10.000000)">
-                    <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
-                    <use fill="#FFFFFF" xlink:href="#path-1"></use>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
+        <g id="课件播放(老师)" transform="translate(-740.000000, -76.000000)" fill-rule="nonzero">
+            <g id="编组-8" transform="translate(732.000000, 66.000000)">
+                <g id="编组-2" transform="translate(2.000000, 10.000000)">
+                    <g id="路径" transform="translate(6.000000, 0.000000)">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
+                        <use stroke="#FFFFFF" stroke-width="2" xlink:href="#path-1"></use>
+                    </g>
                 </g>
             </g>
         </g>

+ 24 - 0
src/views/coursewarePlay/image/icon-point.svg

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>切片</title>
+    <defs>
+        <path d="M17.9889353,7.03683462 C15.5779696,4.12723478 11.4245096,3.37164362 8.14331066,5.24573351 C4.86211176,7.1198234 3.40277969,11.0812175 4.68401757,14.6360727 C5.96525544,18.190928 9.6162626,20.3104404 13.338596,19.6602991 C17.0609294,19.0101577 19.7773154,15.7785188 19.7776894,11.9998178 C19.7776894,11.3862113 20.2751133,10.888785 20.8887168,10.888785 C21.5023203,10.888785 21.9997442,11.3862113 21.9997442,11.9998178 C21.9997099,16.8400427 18.5329414,20.9853151 13.7690477,21.8413977 C9.00515408,22.6974802 4.31207278,20.0185514 2.62687668,15.4811663 C0.941680576,10.9437811 2.7482686,5.85083589 6.91602308,3.38965046 C11.0837776,0.928465034 16.4159405,1.80576128 19.5754824,5.47250055 L20.1087755,4.94698208 C20.545968,4.51623039 21.2495741,4.52145337 21.6803238,4.95864794 C22.1110734,5.39584251 22.1058505,6.09945198 21.668658,6.5302037 L12.3204735,15.742887 C11.8856052,16.1721277 11.185738,16.1696459 10.7539248,15.7373318 L6.69200863,11.6742852 C6.27096012,11.2383394 6.2769817,10.5453817 6.70554253,10.1168189 C7.13410335,9.688256 7.82705768,9.68223439 8.26300138,10.1032849 L11.5460874,13.3863866 L17.9889353,7.03683462 L17.9889353,7.03683462 Z" id="path-1"></path>
+        <filter x="-15.0%" y="-15.0%" width="130.0%" height="130.0%" filterUnits="objectBoundingBox" id="filter-2">
+            <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.125792177 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="课件播放(老师)" transform="translate(-740.000000, -208.000000)" fill-rule="nonzero">
+            <g id="编组-8" transform="translate(732.000000, 66.000000)">
+                <g id="编组-7" transform="translate(0.000000, 75.000000)">
+                    <g id="路径" transform="translate(8.000000, 67.000000)">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
+                        <use fill="#FFFFFF" xlink:href="#path-1"></use>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 17 - 6
src/views/coursewarePlay/index.module.less

@@ -9,7 +9,7 @@
   left: 0;
   right: 0;
   z-index: 1;
-  padding: 10Px 10Px 0 40Px;
+  padding: 10px 10px 0 40px;
   display: flex;
   align-items: center;
 }
@@ -26,7 +26,7 @@
   flex: 1;
   display: flex;
   justify-content: center;
-  margin-left: 10Px;
+  margin-left: 10px;
   .menuLine {
     position: absolute;
     left: 0;
@@ -101,13 +101,24 @@
   width: 100%;
   height: 100%;
 }
-.fullBtn {
+.rightFixedBtns {
   position: fixed;
   top: 50%;
+  transform: translateY(-50%);
   right: 40px;
+  .point {
+    margin-top: 10px;
+    border-bottom-left-radius: 0;
+    border-bottom-right-radius: 0;
+  }
+  .point + .fullBtn {
+    border-top-left-radius: 0;
+    border-top-right-radius: 0;
+  }
+}
+.fullBtn {
   width: 38px;
   height: 55px;
-  transform: translateY(-50%);
   background: rgba(51, 51, 51, 0.15);
   border-radius: 8px;
   display: flex;
@@ -125,12 +136,12 @@
 .overlayClass {
   --van-overlay-background: transparent;
 }
-:global{
+:global {
   .top-enter-active,
   .top-leave-active {
     transition: transform 0.5s;
   }
-  
+
   .top-enter-from,
   .top-leave-to {
     transform: translateY(-100%);

+ 50 - 9
src/views/coursewarePlay/index.tsx

@@ -17,9 +17,10 @@ import request from '@/helpers/request'
 import { state } from '@/state'
 import { useRoute } from 'vue-router'
 import { postMessage } from '@/helpers/native-message'
-import OHeader from '@/components/o-header'
 import MusicScore from './component/musicScore'
 import iconMenu from './image/icon-menu.svg'
+import iconDian from './image/icon-dian.svg'
+import iconPoint from './image/icon-point.svg'
 import Points from './component/points'
 
 export default defineComponent({
@@ -76,12 +77,21 @@ export default defineComponent({
       })
     }
     const videoInit = () => {
-      // console.log(document.querySelectorAll('.player'))
+      console.log(document.querySelectorAll('.player'))
       data.players = Plyr.setup('.player', {
         debug: false,
         ratio: '16:9',
         clickToPlay: true,
-        controls: ['play-large',  'play', 'progress', 'current-time','duration', 'mute', 'volume',  'restart']
+        controls: [
+          'play-large',
+          'play',
+          'progress',
+          'current-time',
+          'duration',
+          'mute',
+          'volume',
+          'restart'
+        ]
       })
       data.players.forEach((p: Plyr) => {
         // console.log(p)
@@ -110,7 +120,8 @@ export default defineComponent({
     })
     // 返回
     const goback = () => {
-      history.go(-1)
+      // history.go(-1)
+      postMessage({ api: 'back' })
     }
     // 所有的切换
     const handleChange = () => {
@@ -165,9 +176,22 @@ export default defineComponent({
         data.showHead = true
       }
     )
+
+    // 去点名
+    const gotoRollCall = (pageTag: string) => {
+      postMessage({
+        api: 'open_app_page',
+        content: {
+          action: 'app',
+          pageTag: pageTag,
+          url: '',
+          params: JSON.stringify({ courseId: route.query.courseId })
+        }
+      })
+    }
     return () => (
       <div class={styles.coursewarePlay}>
-        <Transition name='top'>
+        <Transition name="top">
           {data.showHead && (
             <div class={styles.headerContainer}>
               <div class={styles.backBtn} onClick={() => goback()}>
@@ -198,7 +222,7 @@ export default defineComponent({
             </div>
           )}
         </Transition>
-                  
+
         <Tabs class={styles.tabsContent} animated lazyRender={false} v-model:active={data.active}>
           {data.knowledgePointList.map((item: any) => {
             return (
@@ -246,9 +270,26 @@ export default defineComponent({
             )
           })}
         </Tabs>
-        <div class={styles.fullBtn} onClick={() => (popupData.open = true)}>
-          <img src={iconMenu} />
-          <span>列表</span>
+        <div class={styles.rightFixedBtns}>
+          <div class={styles.fullBtn} onClick={() => (popupData.open = true)}>
+            <img src={iconMenu} />
+            <span>知识点</span>
+          </div>
+          {route.query.courseId && (
+            <>
+              <div
+                class={[styles.fullBtn, styles.point]}
+                onClick={() => gotoRollCall('student_roll_call')}
+              >
+                <img src={iconDian} />
+                <span>点名</span>
+              </div>
+              <div class={styles.fullBtn} onClick={() => gotoRollCall('sign_out')}>
+                <img src={iconPoint} />
+                <span>签退</span>
+              </div>
+            </>
+          )}
         </div>
         <Popup
           class={styles.popup}