lex 2 年之前
父節點
當前提交
9c06468e4d
共有 37 個文件被更改,包括 627 次插入179 次删除
  1. 3 3
      src/business-components/course-plan-step/index.tsx
  2. 1 1
      src/business-components/user-detail/index.module.less
  3. 二進制
      src/common/images/icon_timer3.png
  4. 49 0
      src/components/col-share/code.tsx
  5. 二進制
      src/components/col-share/images/bg1.png
  6. 二進制
      src/components/col-share/images/bg2.png
  7. 二進制
      src/components/col-share/images/bg3.png
  8. 二進制
      src/components/col-share/images/recommend.png
  9. 63 43
      src/components/col-share/index.module.less
  10. 21 19
      src/components/col-share/index.tsx
  11. 59 50
      src/components/col-share/share-item.tsx
  12. 8 0
      src/router/routes-teacher.ts
  13. 二進制
      src/student/teacher-dependent/images/cert_active.png
  14. 二進制
      src/student/teacher-dependent/images/cert_default.png
  15. 二進制
      src/student/teacher-dependent/images/live_active.png
  16. 二進制
      src/student/teacher-dependent/images/live_default.png
  17. 二進制
      src/student/teacher-dependent/images/music_active.png
  18. 二進制
      src/student/teacher-dependent/images/music_default.png
  19. 二進制
      src/student/teacher-dependent/images/video_active.png
  20. 二進制
      src/student/teacher-dependent/images/video_default.png
  21. 二進制
      src/student/teacher-dependent/images/vip_active.png
  22. 二進制
      src/student/teacher-dependent/images/vip_default.png
  23. 9 9
      src/student/teacher-dependent/model/teacher-header.module.less
  24. 72 22
      src/student/teacher-dependent/model/teacher-header.tsx
  25. 5 0
      src/styles/index.less
  26. 9 0
      src/teacher/live-class/live-detail.module.less
  27. 30 6
      src/teacher/live-class/live-detail.tsx
  28. 13 0
      src/teacher/share-page/share-live/index.module.less
  29. 113 0
      src/teacher/share-page/share-live/index.tsx
  30. 31 0
      src/teacher/share-page/share.ts
  31. 9 0
      src/teacher/video-class/video-detail.module.less
  32. 23 3
      src/teacher/video-class/video-detail.tsx
  33. 7 1
      src/views/live-class/live-item.module.less
  34. 37 11
      src/views/live-class/live-item.tsx
  35. 18 0
      src/views/music/album/icon_share.svg
  36. 4 0
      src/views/music/list/item.module.less
  37. 43 11
      src/views/music/list/item.tsx

+ 3 - 3
src/business-components/course-plan-step/index.tsx

@@ -33,9 +33,9 @@ export default defineComponent({
       list: []
     }
   },
-  mounted() {
-    console.log(this.courseId, 'courseId 121212')
-  },
+  // mounted() {
+  //   console.log(this.courseId, 'courseId 121212')
+  // },
   methods: {
     async onLookVideo(item: any) {
       // console.log(item)

+ 1 - 1
src/business-components/user-detail/index.module.less

@@ -73,7 +73,7 @@
       }
       .van-cell__title,
       .van-cell__value {
-        display: flex !important;
+        display: flex;
         align-items: center;
       }
 

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


+ 49 - 0
src/components/col-share/code.tsx

@@ -0,0 +1,49 @@
+import { defineComponent } from 'vue'
+import styles from './index.module.less'
+import logo from '@/common/images/logo.png'
+import iconLogo from '@/common/images/icon_logo.png'
+import QRCode from 'qrcode'
+
+export default defineComponent({
+  name: 'code',
+  props: {
+    shareUrl: {
+      type: String,
+      default: ''
+    }
+  },
+  mounted() {
+    console.log(this.shareUrl, 'this.shareUrl')
+    const canvas = document.getElementById('canvas')
+    QRCode.toCanvas(
+      canvas,
+      this.shareUrl,
+      {
+        margin: 1
+      },
+      (error: any) => {
+        if (error) console.log(error)
+        console.log('success')
+      }
+    )
+  },
+  render() {
+    return (
+      <>
+        <div class={[styles.download]}>
+          <div class={styles.qrcode}>
+            <canvas id="canvas" class={styles.qrcodeCanvas}></canvas>
+            <img src={iconLogo} class={styles.qrcodeLogo} />
+          </div>
+          <div class={styles.logo}>
+            <p style={{ color: '#999', fontWeight: '400' }}>
+              温馨提示:保存图片到相册或长按识别二维码进入查看喔~
+            </p>
+            <img src={logo} />
+            <p>扫码下载酷乐秀开启教学之旅</p>
+          </div>
+        </div>
+      </>
+    )
+  }
+})

二進制
src/components/col-share/images/bg1.png


二進制
src/components/col-share/images/bg2.png


二進制
src/components/col-share/images/bg3.png


二進制
src/components/col-share/images/recommend.png


+ 63 - 43
src/components/col-share/index.module.less

@@ -1,79 +1,99 @@
 .shareContainer {
   width: 333px;
 }
-.shareSection {
-  width: 305px;
-  padding: 14px;
-  background: #2dc7aa;
-  background-size: cover;
-  overflow: hidden;
-  border-radius: 10px;
 
+.shareTitle {
+  .title {
+    font-size: 24px;
+    font-weight: 600;
+    color: #333333;
+    line-height: 35px;
+  }
+  .titleTip {
+    padding-top: 5px;
+    font-size: 14px;
+    color: #666666;
+    line-height: 20px;
+  }
+}
+
+.shareTeacher {
+  margin-top: 15px;
+  padding: 12px;
+  background: linear-gradient(270deg, #baffe7 0%, #c0dcff 100%);
+  border-radius: 9px;
+  color: #333;
+  .teacherImg {
+    margin-right: 12px;
+    position: relative;
+    width: 40px;
+    text-align: center;
+  }
+  .recommend {
+    position: absolute;
+    height: 14px;
+    left: 0;
+    bottom: 3px;
+  }
   .img {
-    width: 54px;
-    height: 54px;
+    width: 33px;
+    height: 33px;
     border-radius: 50%;
-    margin-right: 12px;
   }
 
   .name {
-    font-size: 18px;
+    font-size: 17px;
     font-weight: 500;
-    color: #1a1a1a;
-    line-height: 18px;
+    line-height: 24px;
   }
 
   .titleTips {
-    padding-top: 5px;
-    font-size: 14px;
-    color: #8a8a8a;
+    font-size: 12px;
     line-height: 18px;
   }
 }
 
-.section {
-  background: #ffffff;
-  border-radius: 11px;
-  overflow: hidden;
-  padding: 14px 16px 20px;
-}
-
-.txt {
-  font-size: 16px;
-  color: #333333;
-  line-height: 1.5;
-
-  span {
-    font-size: 18px;
-    font-weight: 500;
-    color: #2dc7aa;
+.shareSection {
+  width: 305px;
+  padding: 16px;
+  background: url('./images/bg1.png') no-repeat top center #fff;
+  background-size: cover;
+  &.yellow {
+    background: url('./images/bg2.png') no-repeat top center #fff;
+    background-size: cover;
+  }
+  &.pink {
+    background: url('./images/bg3.png') no-repeat top center #fff;
+    background-size: cover;
   }
-}
-
-.teacherName {
-  padding-top: 20px;
 }
 
 .download {
-  margin-top: 10px;
+  margin-top: 16px;
   display: flex;
   align-items: center;
   justify-content: space-between;
   .logo {
-    font-size: 13px;
-    color: #349784;
+    margin-left: 12px;
+    padding-left: 14px;
+    font-size: 12px;
+    color: #333;
     line-height: 18px;
+    flex: 1;
+    border-left: 1px solid #ccc;
+    font-weight: 500;
     img {
-      width: 93px;
+      height: 20px;
       vertical-align: middle;
-      margin-bottom: 11px;
+      margin-bottom: 4px;
+      margin-top: 8px;
     }
   }
 
   .qrcode {
     position: relative;
-    width: 76px;
-    height: 76px;
+    width: 92px;
+    height: 92px;
 
     .qrcodeCanvas {
       width: 100% !important;

+ 21 - 19
src/components/col-share/index.tsx

@@ -25,13 +25,14 @@ export default defineComponent({
   },
   async mounted() {
     try {
-      const shortRes = await request.post('/api-teacher/sysConfig/shortURL', {
-        requestType: 'form',
-        data: {
-          orginURL: this.shareUrl
-        }
-      })
-      this.codeUrl = shortRes.data
+      // const shortRes = await request.post('/api-teacher/sysConfig/shortURL', {
+      //   requestType: 'form',
+      //   data: {
+      //     orginURL: this.shareUrl
+      //   }
+      // })
+      // this.codeUrl = shortRes.data
+      this.codeUrl = this.shareUrl
 
       this.$nextTick(async () => {
         const container: any = document.getElementById(
@@ -94,34 +95,35 @@ export default defineComponent({
         {this.codeUrl && (
           <>
             <div class={styles.shareContainer}>
-              <Swipe
-                showIndicators={false}
-                loop={false}
-                style={{ borderRadius: '10px', overflow: 'hidden' }}
-              >
+              <Swipe showIndicators={false} loop={false}>
                 <SwipeItem>
-                  <ShareItem
-                    teacherId={this.teacherId}
-                    shareUrl={this.codeUrl}
-                  />
+                  <ShareItem teacherId={this.teacherId} shareUrl={this.codeUrl}>
+                    {this.$slots.default && this.$slots.default()}
+                  </ShareItem>
                 </SwipeItem>
                 <SwipeItem>
                   <ShareItem
                     teacherId={this.teacherId}
                     shareUrl={this.codeUrl}
-                  />
+                    showType="yellow"
+                  >
+                    {this.$slots.default && this.$slots.default()}
+                  </ShareItem>
                 </SwipeItem>
                 <SwipeItem>
                   <ShareItem
                     teacherId={this.teacherId}
                     shareUrl={this.codeUrl}
-                  />
+                    showType="pink"
+                  >
+                    {this.$slots.default && this.$slots.default()}
+                  </ShareItem>
                 </SwipeItem>
               </Swipe>
             </div>
 
             <div class={['btnGroup', styles.shareGroupBtn]}>
-              <Button type="primary" round onClick={this.onSaveImg}>
+              <Button type="primary" plain round onClick={this.onSaveImg}>
                 保存图片
               </Button>
               <Button

+ 59 - 50
src/components/col-share/share-item.tsx

@@ -1,15 +1,19 @@
 import { Cell } from 'vant'
-import { defineComponent } from 'vue'
+import { defineComponent, PropType } from 'vue'
 import styles from './index.module.less'
 
 // import QrCodeVue from 'qrcode.vue'
 // import { toPng } from 'html-to-image'
-import QRCode from 'qrcode'
 
 import iconTeacher from '@/common/images/icon_teacher.png'
-import logo from '@/common/images/logo.png'
-import iconLogo from '@/common/images/icon_logo.png'
 import { state } from '@/state'
+import Code from './code'
+
+export const getAssetsHomeFile = (fileName: string) => {
+  const path = `./images/${fileName}`
+  const modules = import.meta.globEager('./images/*')
+  return modules[path].default
+}
 
 export default defineComponent({
   name: 'share-item',
@@ -20,35 +24,46 @@ export default defineComponent({
     shareUrl: {
       type: String,
       default: ''
+    },
+    showType: {
+      // 显示背景图
+      type: String as PropType<'yellow' | 'pink' | ''>,
+      default: ''
+    },
+    shareType: {
+      // 分享类型
+      type: String as PropType<'' | 'video' | 'music' | 'live'>,
+      default: ''
     }
   },
-  mounted() {
-    const canvas = document.getElementById('canvas')
-    QRCode.toCanvas(
-      canvas,
-      this.shareUrl,
-      {
-        margin: 1
-      },
-      (error: any) => {
-        if (error) console.log(error)
-        console.log('success')
-      }
-    )
-  },
   render() {
     return (
       <div
-        class={[styles.shareSection, styles.shareContainer]}
+        class={[
+          styles.shareSection,
+          styles.shareContainer,
+          styles[this.showType]
+        ]}
         id="share-preview-container"
       >
-        <div class={styles.section}>
-          <Cell
-            center
-            border={false}
-            style={{ padding: 0 }}
-            v-slots={{
-              icon: () => (
+        <div class={styles.shareTitle}>
+          <p class={styles.title}>
+            优秀的老师能帮助
+            <br />
+            您快速成长
+          </p>
+          <p class={styles.titleTip}>在知识中温故知新,熟能生巧</p>
+        </div>
+
+        {this.$slots.default && this.$slots.default()}
+
+        <Cell
+          center
+          border={false}
+          class={styles.shareTeacher}
+          v-slots={{
+            icon: () => (
+              <div class={styles.teacherImg}>
                 <img
                   src={
                     state.user.data.heardUrl
@@ -60,31 +75,25 @@ export default defineComponent({
                   class={styles.img}
                   crossorigin="anonymous"
                 />
-              ),
-              title: () => (
-                <div>
-                  <p class={styles.name}>{state.user.data.username}</p>
-                  <p class={styles.titleTips}>酷乐秀入驻老师</p>
-                </div>
-              )
-            }}
-          />
-          <p class={[styles.txt, styles.teacherName]}>
-            <span>{state.user.data.username}</span>邀请您加入酷乐秀
-          </p>
-          <p class={styles.txt}>来与我一起踏入音乐殿堂吧!</p>
-        </div>
+                <img
+                  class={styles.recommend}
+                  src={getAssetsHomeFile('recommend.png')}
+                />
+              </div>
+            ),
+            title: () => (
+              <div>
+                <p class={styles.name}>这套课程挺不错!推荐给你~</p>
+                <p class={styles.titleTips}>
+                  <span>{state.user.data.username}</span>
+                  酷乐秀入驻老师
+                </p>
+              </div>
+            )
+          }}
+        />
 
-        <div class={[styles.section, styles.download]}>
-          <div class={styles.logo}>
-            <img src={logo} />
-            <p>扫码下载酷乐秀开启教学之旅</p>
-          </div>
-          <div class={styles.qrcode}>
-            <canvas id="canvas" class={styles.qrcodeCanvas}></canvas>
-            <img src={iconLogo} class={styles.qrcodeLogo} />
-          </div>
-        </div>
+        <Code shareUrl={this.shareUrl} />
       </div>
     )
   }

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

@@ -14,6 +14,14 @@ const noLoginRouter = [
     meta: {
       title: '分享视频课'
     }
+  },
+  {
+    path: '/shareLive',
+    name: 'shareLive',
+    component: () => import('@/teacher/share-page/share-live/index'),
+    meta: {
+      title: '分享直播课'
+    }
   }
 ]
 

二進制
src/student/teacher-dependent/images/cert_active.png


二進制
src/student/teacher-dependent/images/cert_default.png


二進制
src/student/teacher-dependent/images/live_active.png


二進制
src/student/teacher-dependent/images/live_default.png


二進制
src/student/teacher-dependent/images/music_active.png


二進制
src/student/teacher-dependent/images/music_default.png


二進制
src/student/teacher-dependent/images/video_active.png


二進制
src/student/teacher-dependent/images/video_default.png


二進制
src/student/teacher-dependent/images/vip_active.png


二進制
src/student/teacher-dependent/images/vip_default.png


+ 9 - 9
src/student/teacher-dependent/model/teacher-header.module.less

@@ -109,15 +109,15 @@
   }
 }
 
-.cert {
-  margin-left: 5px;
-  height: 24px;
-  // background-color: red;
-  :global {
-    .van-image__img {
-      width: auto !important;
-    }
-  }
+.iconVip {
+  height: 15px;
+  margin-right: 5px;
+}
+
+.iconOther {
+  margin-left: 6px;
+  width: 18px;
+  height: 18px;
 }
 
 .teacher-info {

+ 72 - 22
src/student/teacher-dependent/model/teacher-header.tsx

@@ -3,8 +3,8 @@ import { defineComponent } from 'vue'
 import styles from './teacher-header.module.less'
 import { postMessage } from '@/helpers/native-message'
 import iconTeacher from '@common/images/icon_teacher.png'
-import musicCert from '@common/images/music_cert.png'
-import teacherCert from '@common/images/teacher_cert.png'
+// import musicCert from '@common/images/music_cert.png'
+// import teacherCert from '@common/images/teacher_cert.png'
 import request from '@/helpers/request'
 
 export const getAssetsHomeFile = (fileName: string) => {
@@ -52,7 +52,36 @@ export default defineComponent({
         let count = star ? this.userInfo.fansNum + 1 : this.userInfo.fansNum - 1
         this.userInfo.fansNum = count <= 0 ? 0 : count
         // Toast(str)
-      } catch {}
+      } catch {
+        //
+      }
+    },
+    // 检验是否有对应徽章
+    checkBadge(type: string) {
+      // tag : 老师点亮图标
+      // STYLE:个人风采
+      // VIDEO:视频课
+      // LIVE:直播课,
+      // MUSIC:曲目 逗号隔开
+      let status = false
+      const { userInfo } = this
+      switch (type) {
+        case 'STYLE':
+        case 'VIDEO':
+        case 'LIVE':
+        case 'MUSIC':
+          if (userInfo.tag) {
+            status = userInfo.tag.indexOf(type) > -1
+          }
+          break
+        case 'VIP':
+          status = userInfo.isVip > 0
+          break
+        default:
+          status = false
+          break
+      }
+      return status
     }
   },
   render() {
@@ -101,27 +130,48 @@ export default defineComponent({
                         `游客${this.userInfo.userId || ''}`}
                     </span>
 
-                    {this.userInfo.entryFlag === 1 && (
-                      <Image
-                        class={styles.cert}
-                        src={teacherCert}
-                        // fit="contain"
-                      />
-                    )}
-                    {this.userInfo.musicianFlag === 1 && (
-                      <Image
-                        class={styles.cert}
-                        src={musicCert}
-                        // fit="contain"
-                      />
-                    )}
+                    <Image
+                      class={styles.iconVip}
+                      src={
+                        this.checkBadge('VIP')
+                          ? getAssetsHomeFile('vip_active.png')
+                          : getAssetsHomeFile('vip_default.png')
+                      }
+                    />
+                    <Image
+                      class={styles.iconOther}
+                      src={
+                        this.checkBadge('STYLE')
+                          ? getAssetsHomeFile('cert_active.png')
+                          : getAssetsHomeFile('cert_default.png')
+                      }
+                    />
+                    <Image
+                      class={styles.iconOther}
+                      src={
+                        this.checkBadge('MUSIC')
+                          ? getAssetsHomeFile('music_active.png')
+                          : getAssetsHomeFile('music_default.png')
+                      }
+                    />
+                    <Image
+                      class={styles.iconOther}
+                      src={
+                        this.checkBadge('VIDEO')
+                          ? getAssetsHomeFile('video_active.png')
+                          : getAssetsHomeFile('video_default.png')
+                      }
+                    />
+                    <Image
+                      class={styles.iconOther}
+                      src={
+                        this.checkBadge('LIVE')
+                          ? getAssetsHomeFile('live_active.png')
+                          : getAssetsHomeFile('live_default.png')
+                      }
+                    />
                   </div>
                 </div>
-                {/* <p class={styles.piNameSubject}>
-                          {this.subjectNameList.map((item: any) => (
-                            <span class={styles.subject}>{item}</span>
-                          ))}
-                        </p> */}
                 <div class={styles.level}>
                   {this.starGrade ? (
                     <Rate

+ 5 - 0
src/styles/index.less

@@ -153,6 +153,11 @@ body {
   }
 }
 
+.van-sticky--fixed {
+  position: fixed;
+  z-index: 9999;
+}
+
 :root {
   --music-list-item-background-color: #fff;
   --music-list-item-title-color: #333;

+ 9 - 0
src/teacher/live-class/live-detail.module.less

@@ -10,4 +10,13 @@
       margin-bottom: 15px;
     }
   }
+
+  .shareCourse {
+    margin: 40px 0 0;
+    padding: 0;
+    background: transparent;
+    :global(.itemTitle) {
+      max-width: 120px !important;
+    }
+  }
 }

+ 30 - 6
src/teacher/live-class/live-detail.tsx

@@ -7,6 +7,7 @@ import ColShare from '@/components/col-share'
 import ColSticky from '@/components/col-sticky'
 import { postMessage } from '@/helpers/native-message'
 import request from '@/helpers/request'
+import LiveItem from '@/views/live-class/live-item'
 import dayjs from 'dayjs'
 import { Button, Popup, Sticky, Tab, Tabs, Toast } from 'vant'
 import { defineComponent } from 'vue'
@@ -29,7 +30,8 @@ export default defineComponent({
       groupId: query.groupId,
       courseId: query.classId,
       live: {} as any,
-      shareStatus: false
+      shareStatus: false,
+      shareUrl: ''
     }
   },
   computed: {
@@ -40,6 +42,7 @@ export default defineComponent({
       const endTime = planList[0]?.endTime || new Date()
       return {
         headUrl: live.avatar,
+        avatar: live.avatar,
         username: live.userName,
         id: live.teacherId,
         startTime:
@@ -48,10 +51,13 @@ export default defineComponent({
           )}~${dayjs(endTime).format('HH:mm')}` || '',
         lessonPrice: live.coursePrice,
         buyNum: live.studentCount || 0,
+        lessonId: live.courseGroupId,
         lessonNum: live.courseNum || 0, // 课时数
         lessonDesc: live.courseIntroduce,
         lessonCoverUrl: live.backgroundPic || live.backgroundPicTemplate,
-        lessonName: live.courseGroupName
+        lessonName: live.courseGroupName,
+        subjectName: live.subjectName,
+        courseStartTime: live.courseStartTime
       }
     },
     courseInfo() {
@@ -114,10 +120,10 @@ export default defineComponent({
           }
         }
       )
-      console.log(res)
       this.live = res.data || {}
 
-      console.log(this.live)
+      this.shareUrl = `${location.origin}/teacher/#/shareLive?recomUserId=${this.live.teacherId}&groupId=${this.groupId}`
+      // console.log(this.live)
     } catch {
       //
     }
@@ -182,7 +188,7 @@ export default defineComponent({
     return (
       <div class={[styles['live-detail'], 'mb12']}>
         <UserDetail userInfo={this.userInfo} />
-        <SectionDetail>
+        <SectionDetail border>
           <p class={styles.introduction}>{this.userInfo.lessonDesc}</p>
         </SectionDetail>
 
@@ -268,7 +274,25 @@ export default defineComponent({
           v-model:show={this.shareStatus}
           style={{ background: 'transparent' }}
         >
-          <ColShare teacherId={this.userInfo.id} />
+          <ColShare teacherId={this.userInfo.id} shareUrl={this.shareUrl}>
+            <LiveItem
+              class={styles.shareCourse}
+              liveInfo={{
+                backgroundPic: this.userInfo.lessonCoverUrl,
+                courseGroupId: this.userInfo.lessonId,
+                courseGroupName: this.userInfo.lessonName,
+                courseNum: this.userInfo.lessonNum,
+                coursePrice: this.userInfo.lessonPrice,
+                teacherName: this.userInfo.username,
+                teacherId: this.userInfo.id,
+                avatar: this.userInfo.avatar,
+                studentCount: this.userInfo.buyNum,
+                courseStartTime: this.userInfo.courseStartTime,
+                existBuy: 0,
+                subjectName: this.userInfo.subjectName
+              }}
+            />
+          </ColShare>
         </Popup>
       </div>
     )

+ 13 - 0
src/teacher/share-page/share-live/index.module.less

@@ -0,0 +1,13 @@
+.live-detail {
+  .introduction {
+    color: #7a7a7a;
+    line-height: 23px;
+    padding-bottom: 8px;
+  }
+
+  :global {
+    .van-tabs__wrap {
+      margin-bottom: 15px;
+    }
+  }
+}

+ 113 - 0
src/teacher/share-page/share-live/index.tsx

@@ -0,0 +1,113 @@
+import CoursePlanStep from '@/business-components/course-plan-step'
+import SectionDetail from '@/business-components/section-detail'
+import UserDetail from '@/business-components/user-detail'
+import ColSticky from '@/components/col-sticky'
+import { postMessage } from '@/helpers/native-message'
+import request from '@/helpers/request'
+import dayjs from 'dayjs'
+import { Button, Toast } from 'vant'
+import { defineComponent } from 'vue'
+import styles from './index.module.less'
+interface IProps {
+  courseTime: string
+  coursePlan: string
+  videoPosterUrl?: string
+  roomUid?: string
+  liveState?: number
+  id?: number | string
+}
+export default defineComponent({
+  name: 'LiveDetail',
+  data() {
+    const query = this.$route.query
+    return {
+      recomUserId: query.recomUserId, // 分享人编号
+      groupId: query.groupId,
+      live: {} as any
+    }
+  },
+  computed: {
+    userInfo() {
+      const live = this.live as any
+      const planList = live.planList || []
+      const startTime = planList[0]?.startTime || new Date()
+      const endTime = planList[0]?.endTime || new Date()
+      return {
+        headUrl: live.avatar,
+        username: live.userName,
+        id: live.teacherId,
+        startTime:
+          `${dayjs(startTime).format('YYYY-MM-DD')} ${dayjs(startTime).format(
+            'HH:mm'
+          )}~${dayjs(endTime).format('HH:mm')}` || '',
+        lessonPrice: live.coursePrice,
+        buyNum: live.studentCount || 0,
+        lessonNum: live.courseNum || 0, // 课时数
+        lessonDesc: live.courseIntroduce,
+        lessonCoverUrl: live.backgroundPic || live.backgroundPicTemplate,
+        lessonName: live.courseGroupName
+      }
+    },
+    courseInfo() {
+      const tempArr = [] as IProps[]
+      const coursePlanList = this.live.planList || []
+      coursePlanList.forEach((item: any) => {
+        const startTime = item.startTime || new Date()
+        const endTime = item.endTime || new Date()
+        tempArr.push({
+          courseTime: `${dayjs(startTime).format('YYYY-MM-DD')} ${dayjs(
+            startTime
+          ).format('HH:mm')}~${dayjs(endTime).format('HH:mm')}`,
+          coursePlan: item.plan,
+          roomUid: item.roomUid,
+          liveState: item.liveState,
+          id: item.courseId
+        })
+      })
+      return tempArr || []
+    }
+  },
+  async mounted() {
+    try {
+      const res = await request.get(
+        '/api-teacher/courseGroup/queryLiveCourseInfo',
+        {
+          params: {
+            groupId: this.groupId
+          }
+        }
+      )
+      this.live = res.data || {}
+    } catch {
+      //
+    }
+  },
+  methods: {},
+  render() {
+    return (
+      <div class={[styles['live-detail'], 'mb12']}>
+        <UserDetail userInfo={this.userInfo} />
+        <SectionDetail border>
+          <p class={styles.introduction}>{this.userInfo.lessonDesc}</p>
+        </SectionDetail>
+
+        <SectionDetail
+          title="课程列表"
+          icon="courseList"
+          border
+          // contentStyle={{ paddingTop: '0' }}
+        >
+          <CoursePlanStep courseInfo={this.courseInfo} />
+        </SectionDetail>
+
+        <ColSticky position="bottom">
+          <div class={['btnGroup']} style={{ paddingTop: '12px' }}>
+            <Button block round type="primary">
+              下载酷乐秀进入课程
+            </Button>
+          </div>
+        </ColSticky>
+      </div>
+    )
+  }
+})

+ 31 - 0
src/teacher/share-page/share.ts

@@ -0,0 +1,31 @@
+import { Toast } from 'vant'
+
+// share information
+export const shareCall = () => {
+  const { origin, pathname } = location
+  let str = origin + pathname + '#/'
+  let params = this.$route.query
+  // 判断是否有跳转连接, 如果连接和动作没有时, 则不跳转
+  if (!params.url && !params.action) {
+    return
+  }
+  str += params.url
+
+  const query = {
+    url: str,
+    action: params.action || 'h5', // app, h5
+    pageTag: params.pageTag || 1, // 页面标识
+    params: {}
+  }
+  const iosStr = encodeURIComponent(JSON.stringify(query))
+  if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
+    // ColexiuStudent 唤起学生端
+    window.location.href = `ColexiuStudent://linkUrl=${iosStr}`
+  } else if (/(Android)/i.test(navigator.userAgent)) {
+    window.location.href = `colexiustudent://html:8888/SplashActivity?url=${JSON.stringify(
+      query
+    )}`
+  } else {
+    Toast('请用手机或移动设备打开')
+  }
+}

+ 9 - 0
src/teacher/video-class/video-detail.module.less

@@ -10,4 +10,13 @@
       margin-bottom: 15px;
     }
   }
+
+  .shareCourse {
+    margin: 40px 0 0;
+    padding: 0;
+    background: transparent;
+    :global(.itemTitle) {
+      max-width: 120px !important;
+    }
+  }
 }

+ 23 - 3
src/teacher/video-class/video-detail.tsx

@@ -9,6 +9,7 @@ import request from '@/helpers/request'
 import ColResult from '@/components/col-result'
 import ColShare from '@/components/col-share'
 import ColSticky from '@/components/col-sticky'
+import LiveItem from '@/views/live-class/live-item'
 export default defineComponent({
   name: 'VideoDetail',
   data() {
@@ -46,11 +47,13 @@ export default defineComponent({
         username: result.lessonGroup.username,
         headUrl: result.lessonGroup.avatar,
         buyNum: result.lessonGroup.countStudent,
+        lessonId: result.lessonGroup.id,
         lessonNum: result.lessonGroup.lessonCount,
         lessonName: result.lessonGroup.lessonName,
         lessonDesc: result.lessonGroup.lessonDesc,
         lessonPrice: result.lessonGroup.lessonPrice,
-        lessonCoverUrl: result.lessonGroup.lessonCoverUrl
+        lessonCoverUrl: result.lessonGroup.lessonCoverUrl,
+        lessonSubjectName: result.lessonGroup.lessonSubjectName
       }
       this.detailList = result.detailList || []
 
@@ -167,7 +170,7 @@ export default defineComponent({
                   this.shareStatus = true
                 }}
               >
-                分享
+                分享课程
               </Button>
             </div>
           </ColSticky>
@@ -177,7 +180,24 @@ export default defineComponent({
           v-model:show={this.shareStatus}
           style={{ background: 'transparent' }}
         >
-          <ColShare teacherId={this.userInfo.id} shareUrl={this.shareUrl} />
+          <ColShare teacherId={this.userInfo.id} shareUrl={this.shareUrl}>
+            <LiveItem
+              class={styles.shareCourse}
+              liveInfo={{
+                backgroundPic: this.userInfo.lessonCoverUrl,
+                courseGroupId: this.userInfo.lessonId,
+                courseGroupName: this.userInfo.lessonName,
+                courseNum: this.userInfo.lessonNum,
+                coursePrice: this.userInfo.lessonPrice,
+                teacherName: this.userInfo.username,
+                teacherId: this.userInfo.id,
+                avatar: this.userInfo.avatar,
+                studentCount: this.userInfo.buyNum,
+                existBuy: 0,
+                subjectName: this.userInfo.lessonSubjectName
+              }}
+            />
+          </ColShare>
         </Popup>
       </div>
     )

+ 7 - 1
src/views/live-class/live-item.module.less

@@ -20,7 +20,7 @@
     font-weight: 600;
     color: #333333;
     line-height: 20px;
-    max-width: 150px;
+    max-width: 40%;
   }
 
   .liUserInfo {
@@ -96,4 +96,10 @@
     border-radius: 1px;
     background: rgba(0, 0, 0, 0.29);
   }
+
+  .iconTimer {
+    width: 17px;
+    height: 17px;
+    vertical-align: bottom;
+  }
 }

+ 37 - 11
src/views/live-class/live-item.tsx

@@ -5,13 +5,14 @@ import dayjs from 'dayjs'
 
 import iconSuccess from '@common/images/icon_success.png'
 import iconTeacher from '@common/images/icon_teacher.png'
+import iconTimer from '@common/images/icon_timer3.png'
 
 interface IProps {
   backgroundPic: string
   courseGroupId: number
   courseGroupName: string
   courseNum: string
-  courseStartTime: number
+  courseStartTime?: number
   coursePrice: number
   teacherName: string
   teacherId: number
@@ -34,7 +35,7 @@ export default defineComponent({
     }
   },
   render() {
-    console.log(this.liveInfo, 121212)
+    // console.log(this.liveInfo, 121212)
     return (
       <Cell
         center
@@ -44,10 +45,21 @@ export default defineComponent({
         v-slots={{
           icon: () => (
             <div style={{ position: 'relative' }}>
-              <Image
+              {/* <Image
                 class={styles.liCover}
                 fit="cover"
                 src={this.liveInfo.backgroundPic}
+                crossorigin="anonymous"
+              /> */}
+              <img
+                class={styles.liCover}
+                src={
+                  this.liveInfo.backgroundPic + '?time=' + new Date().valueOf()
+                }
+                crossorigin="anonymous"
+                style={{
+                  objectFit: 'cover'
+                }}
               />
               <span class={styles.subjectName}>
                 {this.liveInfo.subjectName}
@@ -56,25 +68,39 @@ export default defineComponent({
           ),
           title: () => (
             <div>
-              <div class={[styles.liTitle, 'van-ellipsis']}>
+              <div class={[styles.liTitle, 'van-ellipsis', 'itemTitle']}>
                 {this.liveInfo.courseGroupName}
               </div>
               <div class={styles.liUserInfo}>
                 <p class={styles.liteachername}>
                   {/* 老师: */}
-                  <Image
+                  {/* <Image
                     src={this.liveInfo.avatar || iconTeacher}
                     class={styles.liteacherIcon}
+                  /> */}
+                  <img
+                    src={
+                      this.liveInfo.avatar
+                        ? this.liveInfo.avatar + '?time=' + new Date().valueOf()
+                        : iconTeacher
+                    }
+                    class={styles.liteacherIcon}
+                    crossorigin="anonymous"
+                    style={{
+                      objectFit: 'cover'
+                    }}
                   />
                   {this.liveInfo.teacherName ||
                     `游客${this.liveInfo.teacherId}`}
                 </p>
-                <p>
-                  开课时间:
-                  {dayjs(this.liveInfo.courseStartTime).format(
-                    'MM月DD日 HH:mm'
-                  )}
-                </p>
+                {this.liveInfo.courseStartTime && (
+                  <p>
+                    <img src={iconTimer} class={styles.iconTimer} />
+                    {dayjs(this.liveInfo.courseStartTime).format(
+                      'MM月DD日 HH:mm'
+                    )}
+                  </p>
+                )}
               </div>
               <div class={styles.liPrice}>
                 <p>

+ 18 - 0
src/views/music/album/icon_share.svg

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>切片</title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="曲目(老师分享)" transform="translate(-295.000000, -222.000000)">
+            <g id="编组-5备份" transform="translate(14.000000, 151.000000)">
+                <g id="分享(专辑)" transform="translate(281.000000, 71.000000)">
+                    <rect id="矩形" x="0" y="0" width="18" height="18"></rect>
+                    <g id="编组-5" transform="translate(1.960261, 2.294652)" stroke="#DEDEDE" stroke-linecap="round" stroke-width="1.4">
+                        <path d="M7,0.0980762114 C3.13400675,0.0980762114 0,3.23208296 0,7.09807621 C0,10.9640695 3.13400675,14.0980762 7,14.0980762 C10.8659932,14.0980762 14,10.9640695 14,7.09807621" id="路径"></path>
+                        <path d="M13.0553063,2.25732549 C9.74159779,2.25732549 7.05530629,4.94361699 7.05530629,8.25732549" id="路径"></path>
+                        <polyline id="路径" stroke-linejoin="round" transform="translate(11.366025, 2.732051) rotate(-330.000000) translate(-11.366025, -2.732051) " points="9.3660254 0.732050808 13.3660254 0.732050808 13.3660254 4.73205081"></polyline>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 4 - 0
src/views/music/list/item.module.less

@@ -83,4 +83,8 @@
       --van-tag-text-color: #ff8c00;
     }
   }
+
+  .shareBtn:active:before {
+    opacity: 0 !important;
+  }
 }

+ 43 - 11
src/views/music/list/item.tsx

@@ -1,12 +1,15 @@
 import { defineComponent, ref } from 'vue'
-import { Button, Icon, Image, Tag } from 'vant'
+import { Button, Icon, Image, Popup, Tag, Toast } from 'vant'
 import classNames from 'classnames'
 import MusicIcon from './icons/music-icon.png'
 import InitUserIcon from './icons/init-user-icon.png'
 import FavoriteIcon from '../album/favorite.svg'
 import FavoritedIcon from '../album/favorited.svg'
+import iconShare from '../album/icon_share.svg'
 import styles from './item.module.less'
 import request from '@/helpers/request'
+import { state } from '@/state'
+import ColShare from '@/components/col-share'
 
 const chargeTypes = {
   CHARGE: '点播',
@@ -42,6 +45,18 @@ export default defineComponent({
       favoriteLoading.value = false
       emit('favorite')
     }
+
+    const shareStatus = ref(false)
+    const shareUrl = ref('')
+    console.log(data)
+    const onShare = (evt: MouseEvent) => {
+      evt.stopPropagation()
+      if (!shareStatus.value) {
+        Toast('暂无分享地址')
+        return
+      }
+      shareStatus.value = true
+    }
     return () => (
       <div
         class={styles.item}
@@ -84,18 +99,35 @@ export default defineComponent({
             </div>
           </div>
           <div class={styles.icons}>
-            <Button
-              style={{ border: 'none' }}
-              onClick={toggleFavorite}
-              loading={favoriteLoading.value}
-            >
-              <Icon
-                class={styles.favorite}
-                name={favorite.value ? FavoritedIcon : FavoriteIcon}
-              />
-            </Button>
+            {state.platformType === 'STUDENT' ? (
+              <Button
+                style={{ border: 'none' }}
+                onClick={toggleFavorite}
+                loading={favoriteLoading.value}
+              >
+                <Icon
+                  class={styles.favorite}
+                  name={favorite.value ? FavoritedIcon : FavoriteIcon}
+                />
+              </Button>
+            ) : (
+              <Button
+                style={{ border: 'none' }}
+                class={styles.shareBtn}
+                onClick={onShare}
+              >
+                <Icon class={styles.favorite} name={iconShare} />
+              </Button>
+            )}
           </div>
         </footer>
+
+        <Popup
+          v-model:show={shareStatus.value}
+          style={{ background: 'transparent' }}
+        >
+          <ColShare teacherId={data.userId} shareUrl={shareUrl.value} />
+        </Popup>
       </div>
     )
   }