lex-xin 3 months ago
parent
commit
41ce90cf80
29 changed files with 1135 additions and 239 deletions
  1. 2 0
      src/components/col-protocol/index.tsx
  2. 8 0
      src/router/routes-student.ts
  3. 9 0
      src/router/routes-teacher.ts
  4. 70 52
      src/student/teacher-dependent/components/live.module.less
  5. 60 58
      src/student/teacher-dependent/components/live.tsx
  6. 8 5
      src/student/teacher-dependent/components/music.tsx
  7. 39 15
      src/student/teacher-dependent/components/video-item/index.module.less
  8. 7 13
      src/student/teacher-dependent/components/video-item/index.tsx
  9. BIN
      src/student/teacher-dependent/images/icon-live.png
  10. BIN
      src/student/teacher-dependent/images/icon-small-live.png
  11. BIN
      src/student/teacher-dependent/images/icon_video.png
  12. 12 11
      src/student/teacher-dependent/model/teacher-header.module.less
  13. 5 4
      src/student/teacher-dependent/model/teacher-header.tsx
  14. 49 12
      src/student/teacher-dependent/teacher-home.tsx
  15. 217 0
      src/student/teacher-dependent/teacher-style/index.module.less
  16. 143 5
      src/student/teacher-dependent/teacher-style/index.tsx
  17. 1 1
      src/teacher/layout/auth.tsx
  18. BIN
      src/teacher/layout/image-cert/bg.png
  19. BIN
      src/teacher/layout/image-cert/top.png
  20. 99 0
      src/teacher/layout/login-cert.module.less
  21. 244 0
      src/teacher/layout/login-cert.tsx
  22. 1 0
      src/views/adapay/payment/index.tsx
  23. 19 0
      src/views/music/list/index.module.less
  24. 46 3
      src/views/music/list/index.tsx
  25. 57 47
      src/views/order-detail/index.tsx
  26. 2 1
      src/views/order-detail/order-discount/index.tsx
  27. 24 9
      src/views/order-detail/use-coupons/choice-coupon.tsx
  28. 1 1
      src/views/order-detail/use-coupons/index.module.less
  29. 12 2
      src/views/order-detail/use-coupons/index.tsx

+ 2 - 0
src/components/col-protocol/index.tsx

@@ -27,6 +27,7 @@ export default defineComponent({
       default: 'BUY_ORDER'
     }
   },
+  emits: ['protocolExists', 'update:modelValue'],
   data() {
     return {
       exists: true,
@@ -51,6 +52,7 @@ export default defineComponent({
       // console.log(res)
       this.exists = res.data
       this.checked = this.checked || this.exists
+      this.$emit('protocolExists', res.data)
       this.$emit('update:modelValue', this.checked || this.exists)
     } catch {}
     this.checked = this.modelValue

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

@@ -121,6 +121,14 @@ export default [
         }
       },
       {
+        path: '/teacher-style',
+        name: 'teacher-style',
+        component: () => import('@/student/teacher-dependent/teacher-style'),
+        meta: {
+          title: '个人风采'
+        }
+      },
+      {
         path: '/music-upload',
         component: () => import('@/teacher/music/upload'),
         meta: {

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

@@ -54,6 +54,15 @@ const noLoginRouter = [
     meta: {
       title: '分享曲谱'
     }
+  },
+  {
+    path: '/login-cert',
+    name: 'login-cert',
+    component: () => import('@/teacher/layout/login-cert'),
+    meta: {
+      isRegister: false,
+      title: '老师入驻'
+    } as metaType
   }
 ]
 

+ 70 - 52
src/student/teacher-dependent/components/live.module.less

@@ -3,84 +3,79 @@
 }
 
 .liCover {
-  width: 105px;
-  height: 71px;
+  width: 100%;
   border-radius: 4px;
   overflow: hidden;
 }
 
 .liContent {
-  padding-left: 14px;
   height: 100%;
   display: flex;
   flex-direction: column;
   justify-content: space-between;
   .liTitle {
-    font-size: 15px;
-    font-weight: 500;
-    color: #1a1a1a;
-    line-height: 20px;
-    padding-top: 4px;
-    max-width: 180px;
+    font-weight: 600;
+    font-size: 16px;
+    color: #131415;
+    line-height: 22px;
   }
-  // .avatar {
-  //   width: 18px;
-  //   height: 18px;
-  //   overflow: hidden;
-  //   border-radius: 50%;
-  //   margin-right: 6px;
-  // }
+}
+
+.users {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding-top: 8px;
 
-  // .liUserInfo,
-  // .userInfo {
-  //   display: flex;
-  //   align-items: center;
-  //   font-size: 13px;
-  //   color: #999999;
-  //   line-height: 18px;
-  //   flex-wrap: wrap;
-  // }
+  .user {
+    display: flex;
+    align-items: center;
+    img {
+      width: 26px;
+      height: 26px;
+      margin-right: 6px;
+      border-radius: 50%;
+    }
+
+    span {
+      font-size: 14px;
+      color: #333333;
+      line-height: 20px;
+    }
+  }
 
-  // .userInfo {
-  //   padding-right: 10px;
-  //   margin-right: 10px;
-  // }
+  .lean {
+    background: rgba(255, 246, 240, 1);
+    border-radius: 2px;
+    padding: 3px 4px 2px;
+  }
 }
-// .num {
-//   color: #ff802c;
-//   font-size: 13px;
-// }
 
 .buyNum,
 .num {
-  color: #ff802c;
-  // display: flex;
-  // align-items: center;
-  // line-height: 1;
-  font-size: 13px;
+  color: #FF6827;
+  font-size: 12px;
 }
 
 .price {
-  // font-size: 14px;
-  // color: var(--van-primary);
-  // span {
-  //   font-weight: 600;
-  //   font-size: 16px;
-  // }
   font-size: 14px;
   color: #999;
 
   .priceNum {
     color: #ff0000;
-    font-size: 18px;
+    font-size: 22px;
+    // font-family: DINAlternate, DINAlternate;
     font-weight: bold;
     i {
-      font-size: 15px;
+      font-size: 14px;
       font-style: normal;
     }
   }
   .label {
-    padding-left: 8px;
+    // padding-left: 8px;
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
   }
 }
 
@@ -88,18 +83,41 @@
   border-radius: 10px;
   overflow: hidden;
   margin-bottom: 10px;
+  padding: 12px;
+  background: #FFFFFF;
+
+  .liveTop {
+    display: flex;
+    align-items: center;
+    .iconLive {
+      width: 20px;
+      height: 20px;
+      margin-right: 6px;
+    }
+    span {
+      font-weight: 600;
+      font-size: 14px;
+      color: #333333;
+      line-height: 20px;
+    }
+  }
+
+  .liveCenter {
+    margin: 12px 0 8px;
+    position: relative;
+  }
 }
 
 .subjectName {
   position: absolute;
-  bottom: 4px;
-  left: 0px;
+  top: 8px;
+  left: 8px;
   font-size: 12px;
-  padding: 3px 5px;
+  padding: 3px 5px 2px;
   color: #ffffff;
   line-height: 1;
-  border-radius: 1px;
-  background: rgba(0, 0, 0, 0.29);
+  background: rgba(0,0,0,0.4);
+  border-radius: 3px;
 }
 
 .timerString {

+ 60 - 58
src/student/teacher-dependent/components/live.tsx

@@ -2,10 +2,11 @@ import ColResult from '@/components/col-result'
 import { Cell, CellGroup, List, Image, Icon } from 'vant'
 import { defineComponent } from 'vue'
 import styles from './live.module.less'
-import icon3 from '../images/icon3.png'
-import iconTimer from '@common/images/icon_timer2.png'
+import iconLive from '../images/icon-live.png'
+// import icon3 from '../images/icon3.png'
+// import iconTimer from '@common/images/icon_timer2.png'
 import iconTeacher from '@common/images/icon_teacher.png'
-import iconSuccess from '@common/images/icon_success.png'
+// import iconSuccess from '@common/images/icon_success.png'
 import request from '@/helpers/request'
 import dayjs from 'dayjs'
 import { state } from '@/state'
@@ -37,7 +38,7 @@ export default defineComponent({
       const weekStr = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
       // console.log(timeStr.day())
 
-      return timeStr.format('YYYY-MM-DD') + `(${weekStr[timeStr.day()]})`
+      return timeStr.format('YYYY-MM-DD')  + `(${weekStr[timeStr.day()]})`
     },
     async getList() {
       try {
@@ -83,7 +84,12 @@ export default defineComponent({
   render() {
     return (
       <>
-        <Tips type="LIVE" class={styles.tips} title='什么是直播课?' content='直播课是现代教育领域中一种广受欢迎的课程形式,它集实时互动、多媒体展示和高度便利性于一体,为学习者带来了独特且丰富的学习体验。特别是在管乐直播课中,教师可以通过播放经典音乐作品,加深学生对音乐之美的感知与理解。对于那些需要具体操作演示的教学内容,直播课能够提供清晰直观的视角,让教师的每一个动作细节都展现在学生面前,确保学习效果。直播课程的内容围绕特定主题精心设计,旨在满足不同学习者的需求,促进知识与技能的有效传递。' />
+        <Tips
+          type="LIVE"
+          class={styles.tips}
+          title="什么是直播课?"
+          content="直播课是现代教育领域中一种广受欢迎的课程形式,它集实时互动、多媒体展示和高度便利性于一体,为学习者带来了独特且丰富的学习体验。特别是在管乐直播课中,教师可以通过播放经典音乐作品,加深学生对音乐之美的感知与理解。对于那些需要具体操作演示的教学内容,直播课能够提供清晰直观的视角,让教师的每一个动作细节都展现在学生面前,确保学习效果。直播课程的内容围绕特定主题精心设计,旨在满足不同学习者的需求,促进知识与技能的有效传递。"
+        />
         {this.dataShow ? (
           <List
             class={styles.liveList}
@@ -98,60 +104,56 @@ export default defineComponent({
                 border={false}
                 onClick={() => this.onDetail(item)}
               >
-                <Cell
-                  style={{ paddingTop: '19px', paddingBottom: '19px' }}
-                  v-slots={{
-                    icon: () => (
-                      <div style={{ position: 'relative', lineHeight: '0' }}>
-                        <Image
-                          class={styles.liCover}
-                          src={item.backgroundPic}
-                          fit="cover"
-                        />
-                        <span class={styles.subjectName}>
-                          {item?.subjectName}
+                <div class={styles.liveTop}>
+                  <img src={iconLive} class={styles.iconLive} />
+                  <span>开课时间: {this.formatTime(item.salesStartDate)} </span>
+                </div>
+                <div class={styles.liveCenter}>
+                  <Image
+                    class={styles.liCover}
+                    src={item.backgroundPic}
+                    fit="cover"
+                  />
+                  <span class={styles.subjectName}>{item?.subjectName}</span>
+                </div>
+
+                <div class={styles.liContent}>
+                  <div class={[styles.liTitle, 'van-ellipsis']}>
+                    {item.courseGroupName}
+                  </div>
+                  <div class={styles.users}>
+                    {/* <div class={styles.user}>
+                      <img src={item.avatar || iconTeacher} />
+                      <span>{item.teacherName || `游客${item.teacherId || ''}`}</span>
+                    </div> */}
+                    <div class={styles.lean}>
+                      {item.existBuy === 1 ? (
+                        <span class={styles.buyNum}>学习</span>
+                      ) : (
+                        <span class={styles.num}>
+                          {item.studentCount}人学习
                         </span>
-                      </div>
-                    ),
-                    title: () => (
-                      <div class={styles.liContent}>
-                        <div class={[styles.liTitle, 'van-ellipsis']}>
-                          {item.courseGroupName}
-                        </div>
-                        {/* <div class={styles.liUserInfo}>
-                          <div class={[styles.userInfo, 'van-hairline--right']}>
-                            <Image
-                              class={styles.avatar}
-                              fit="cover"
-                              src={item.avatar || iconTeacher}
-                            />
-                            <p>
-                              老师:
-                              {item.teacherName || `游客${item.teacherId}`}
-                            </p>
-                          </div>
-                        </div> */}
-                        <div class={styles.price}>
-                          {item.coursePrice > 0 && (
-                            <>
-                              <span class={styles.priceNum}>
-                                <i>¥</i>
-                                {(this as any).$filters.moneyFormat(
-                                  item.coursePrice
-                                )}
-                              </span>
-                            </>
-                          )}
-                          <span class={styles.label}>
-                            {item.coursePrice > 0 && '/'}
-                            {item.courseNum}课时
+                      )}
+                    </div>
+                    <div class={styles.price}>
+                      {item.coursePrice > 0 && (
+                        <>
+                          <span class={styles.priceNum}>
+                            <i>¥</i>
+                            {(this as any).$filters.moneyFormat(
+                              item.coursePrice
+                            )}
                           </span>
-                        </div>
-                      </div>
-                    )
-                  }}
-                />
-                <Cell
+                        </>
+                      )}
+                      <span class={styles.label}>
+                        {item.coursePrice > 0 && '/'}
+                        {item.courseNum}课时
+                      </span>
+                    </div>
+                  </div>
+                </div>
+                {/* <Cell
                   titleStyle={{ color: '#666666', fontSize: '13px' }}
                   v-slots={{
                     title: () => (
@@ -171,7 +173,7 @@ export default defineComponent({
                       </div>
                     )
                   }}
-                />
+                /> */}
               </CellGroup>
             ))}
           </List>

+ 8 - 5
src/student/teacher-dependent/components/music.tsx

@@ -1,13 +1,14 @@
-import ColResult from '@/components/col-result'
-import { Dialog, List } from 'vant'
 import { defineComponent } from 'vue'
-import styles from './music.module.less'
 import MusicList from '@/views/music/list'
-import { state } from '@/state'
-import { orderStatus } from '@/views/order-detail/orderStatus'
 
 export default defineComponent({
   name: 'music',
+  props: {
+    height: {
+      type: Number,
+      default: 0
+    }
+  },
   data() {
     const query = this.$route.query
     return {
@@ -37,6 +38,8 @@ export default defineComponent({
       <>
         <MusicList
           hideSearch
+          onlySearch
+          height={this.height}
           myself
           onItemClick={this.onItemClick}
           teacherId={this.teacherId}

+ 39 - 15
src/student/teacher-dependent/components/video-item/index.module.less

@@ -1,62 +1,86 @@
 .videoItem {
-  border-radius: 8px;
+  border-radius: 10px;
   background-color: #fff;
   overflow: hidden;
-  width: 168px;
+  width: 100%;
   margin-bottom: 12px;
+  padding: 12px;
+  display: flex;
+  align-items: center;
 
   .viCover {
     height: 94px;
     width: 100%;
+    border-radius: 6px;
     vertical-align: middle;
+    overflow: hidden;
   }
 
   .viSection {
-    padding: 8px 12px 13px;
+    margin-left: 10px;
+    flex: 1 auto;
   }
 
   .viTitle {
-    font-size: 14px;
-    color: #1a1a1a;
-    line-height: 20px;
+    font-weight: 600;
+    font-size: 15px;
+    color: #131415;
+    line-height: 21px;
   }
 
   .viUserNum {
     padding-top: 4px;
     color: #ff802c;
     font-size: 12px;
+    background: rgba(255, 246, 240, 1);
+    border-radius: 2px;
+    padding: 3px 4px 2px;
   }
 
   .viPrice {
-    padding-top: 10px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
     font-size: 14px;
     color: #999;
 
     .priceNum {
-      color: #ff0000;
+      color: #F44541;
       font-size: 16px;
       font-weight: bold;
 
       i {
-        font-size: 15px;
+        font-size: 14px;
         font-style: normal;
       }
     }
 
+    
+  }
+
+  .tags {
+    padding: 8px 0;
     .label {
-      padding-left: 8px;
+      margin-right: 4px;
+      background: #F5F6FA;
+      border-radius: 3px;
+      font-size: 11px;
+      color: #777777;
+      line-height: 16px;
+      padding: 1px 6px;
+      display: inline-block;
     }
   }
 
   .subjectName {
     position: absolute;
-    bottom: 6px;
-    right: 6px;
+    top: 4px;
+    left: 4px;
     font-size: 10px;
-    padding: 3px 5px;
+    padding: 3px 5px 2px;
     color: #ffffff;
     line-height: 1;
-    border-radius: 2px;
-    background: rgba(0, 0, 0, 0.29);
+    background: rgba(0,0,0,0.4);
+    border-radius: 3px;
   }
 }

+ 7 - 13
src/student/teacher-dependent/components/video-item/index.tsx

@@ -47,18 +47,12 @@ export default defineComponent({
 
         <div class={styles.viSection}>
           <div class={[styles.viTitle, 'van-ellipsis']}>{item?.lessonName}</div>
-          {/* <div class={styles.viUserInfo}>
-            <Image
-              src={item?.avatar || iconTeacher}
-              class={styles.viUserLogo}
-            />
-            <span class={[styles.viUserName, 'van-hairline--right']}>
-              {item?.userName ||
-                item?.username ||
-                `游客${item?.teacherId || ''}`}
-            </span>
-          </div> */}
+          <div class={styles.tags}>
+            {item?.musicNum > 0 ? <span class={styles.label}>{item?.musicNum}首曲目</span> : ''}
+            {item?.lessonCount > 0 ? <span class={styles.label}>{item?.lessonCount}课时</span> : ''}
+          </div>
           <div class={styles.viPrice}>
+            <div class={styles.viUserNum}>{item?.countStudent}人学习</div>
             <span class={styles.priceNum}>
               {item.payType === 'VIP' ? (
                 <span style={{ color: '#C76E21' }}>会员</span>
@@ -81,10 +75,10 @@ export default defineComponent({
                 </>
               )}
             </span>
-            <span class={styles.label}>/{item?.lessonCount}课时</span>
+            
           </div>
 
-          <div class={styles.viUserNum}>{item?.countStudent}人学习</div>
+          
         </div>
       </div>
     )

BIN
src/student/teacher-dependent/images/icon-live.png


BIN
src/student/teacher-dependent/images/icon-small-live.png


BIN
src/student/teacher-dependent/images/icon_video.png


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

@@ -1,5 +1,5 @@
 .headerContent {
-  padding-top: 12px;
+  // padding-top: 12px;
   // padding-bottom: 20px;
   min-height: 100px;
   position: relative;
@@ -285,18 +285,19 @@
 
 .liveTag {
   position: absolute;
-  bottom: 0;
+  top: -1.5px;
   left: 50%;
   transform: translateX(-50%);
-  line-height: 16px;
-  background: #ff6363;
-  border-radius: 20px;
-  text-align: center;
-  color: #fff;
-  font-size: 10px;
-  font-weight: 500;
-  padding: 2px 0;
-  width: 60%;
+  width: 34px;
+  // line-height: 16px;
+  // background: #ff6363;
+  // border-radius: 20px;
+  // text-align: center;
+  // color: #fff;
+  // font-size: 10px;
+  // font-weight: 500;
+  // padding: 2px 0;
+  // width: 60%;
   z-index: 10;
 }
 

+ 5 - 4
src/student/teacher-dependent/model/teacher-header.tsx

@@ -4,9 +4,10 @@ import styles from './teacher-header.module.less'
 import { postMessage } from '@/helpers/native-message'
 import iconTeacher from '@common/images/icon_teacher.png'
 import request from '@/helpers/request'
-import IconXueli from '@common/images/icon-xueli.png'
-import IconJiaozi from '@common/images/icon-jiaozi.png'
-import IconChat from '../images/icon-chat.png'
+// import IconXueli from '@common/images/icon-xueli.png'
+// import IconJiaozi from '@common/images/icon-jiaozi.png'
+// import IconChat from '../images/icon-chat.png'
+import iconSmallLive from '../images/icon-small-live.png'
 
 export const getAssetsHomeFile = (fileName: string) => {
   const path = `../images/${fileName}`
@@ -163,7 +164,7 @@ export default defineComponent({
                 />
 
                 {this.userInfo.liveing === 1 && (
-                  <p class={styles.liveTag}>直播中</p>
+                  <img src={iconSmallLive}  class={styles.liveTag} />
                 )}
 
                 {(this.checkBadge('SVIP') || this.checkBadge('VIP')) && (

+ 49 - 12
src/student/teacher-dependent/teacher-home.tsx

@@ -1,5 +1,5 @@
 import ColHeader from '@/components/col-header'
-import { defineComponent } from 'vue'
+import { defineComponent, provide } from 'vue'
 import styles from './teacher-home.module.less'
 import { Popup, Tab, Tabs } from 'vant'
 import Practice from './components/practice'
@@ -16,6 +16,7 @@ import Vip from './components/vip'
 import Single from './components/single'
 import JoinChat from './model/join-chat'
 import FansList from './model/fans-list'
+import MusicList from '@/views/music/list'
 
 export const getAssetsHomeFile = (fileName: string) => {
   const path = `./images/${fileName}`
@@ -36,6 +37,8 @@ export default defineComponent({
       background: 'rgba(55, 205, 177, 0)',
       headColor: '#fff',
       height: 'auto' as any,
+      tabsHeight: 0,
+      stickyHeightNum: 0,
       backIconColor: 'white',
       homeContaiterHeight: '',
       fansStatus: false,
@@ -44,8 +47,13 @@ export default defineComponent({
       chatStatus: false,
     }
   },
-  async created() {},
   async mounted() {
+    this.$nextTick(() => {
+      const { height } = useRect(document.querySelector('.van-tabs__wrap') as any)
+      this.tabsHeight = height
+      this.stickyHeight()
+    })
+
     this.getTeacherDetail()
     // 监听页面返回
     listenerMessage('webViewOnResume', () => {
@@ -53,8 +61,6 @@ export default defineComponent({
     })
     useEventListener(document, 'scroll', evt => {
       const { y } = useWindowScroll()
-      // this.background = `rgba(255, 255, 255, ${y.value / 100})`
-      // console.log(y.value) 142
       if (y.value > 52) {
         this.headColor = '#000'
         this.background = '#fff'
@@ -68,6 +74,16 @@ export default defineComponent({
     useEventTracking('达人风采')
   },
   methods: {
+    stickyHeight() {
+      let height = 0
+      if(this.height === 'auto') {
+        height = this.tabsHeight
+      } else {
+        height = this.height + this.tabsHeight
+      }
+      this.stickyHeightNum = height;
+      (this.$refs.musicListRef as any)?.updateStickyHeight(height)
+    },
     async getTeacherDetail() {
       try {
         const res = await request.get('/api-student/teacher/queryTeacherHome', {
@@ -88,6 +104,14 @@ export default defineComponent({
         })
         this.fansList = res.data || []
       } catch {}
+    },
+    onItemClick(item: any) {
+      this.$router.push({
+        path: '/music-detail',
+        query: {
+          id: item.id
+        }
+      })
     }
   },
   render() {
@@ -95,7 +119,7 @@ export default defineComponent({
       <div class={styles['teacher-record']}>
         <div ref="headers">
           <ColHeader
-            // hideHeader={false}
+            hideHeader={false}
             background={this.background}
             border={false}
             color={this.headColor}
@@ -103,7 +127,8 @@ export default defineComponent({
             onHeaderBack={() => {
               this.$nextTick(() => {
                 const { height } = useRect((this as any).$refs.headers)
-                this.height = height
+                this.height = Math.floor(height)
+                this.stickyHeight()
               })
             }}
           />
@@ -122,7 +147,14 @@ export default defineComponent({
 
           <div class={styles.singleSection}>
             <div class={styles.btnType}>
-              <div class={styles.btn1}>
+              <div class={styles.btn1} onClick={() => {
+                this.$router.push({
+                  path: '/teacher-style',
+                  query: {
+                    teacherId: this.teacherId
+                  }
+                })
+              }}>
                 <img src={getAssetsHomeFile('icon1.png')} />
                 个人风采
               </div>
@@ -180,14 +212,19 @@ export default defineComponent({
             </div>
           </Tab>
           <Tab title="视频课" name="video">
-            <div style={{ minHeight: this.homeContaiterHeight }}>
               {this.tabs === 'video' && <VideoList />}
-            </div>
           </Tab>
           <Tab title="乐谱" name="music">
-            <div style={{ minHeight: this.homeContaiterHeight }}>
-              {this.tabs === 'music' && <Music />}
-            </div>
+            {this.tabs === 'music' && <MusicList
+                hideSearch
+                onlySearch
+                myself
+                height={this.stickyHeightNum}
+                ref="musicListRef"
+                onItemClick={this.onItemClick}
+                teacherId={this.teacherId}
+              />
+            }
           </Tab>
         </Tabs>
 

+ 217 - 0
src/student/teacher-dependent/teacher-style/index.module.less

@@ -0,0 +1,217 @@
+.elegant {
+  // display: flex;
+  // flex-wrap: wrap;
+  // justify-content: space-between; /* 让元素均匀分布在容器内 */
+  column-count: 2; /* 设置列数 */
+  padding: 14px;
+}
+
+.itemBg {
+  position: absolute;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  bottom: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 89;
+}
+
+.tedeoItem {
+  border-radius: 8px;
+  background-color: #fff;
+  overflow: hidden;
+  width: 168px;
+  margin-bottom: 12px;
+  position: relative;
+  display: inline-block;
+  &:first-child {
+    .teCover {
+      height: 170px;
+    }
+  }
+  position: relative;
+  :global {
+    .van-image {
+      height: 100%;
+    }
+  }
+  .iconVideo {
+    position: absolute;
+    top: 5px;
+    right: 8px;
+    width: 24px;
+    height: 24px;
+    z-index: 1;
+  }
+
+  .teCover {
+    height: 140px;
+    width: 100%;
+    vertical-align: middle;
+    overflow: hidden;
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .teSection {
+    padding: 8px;
+    
+  }
+
+  .teTitle {
+    font-size: 14px;
+    color: #1a1a1a;
+    line-height: 20px;
+  }
+
+  .info {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+
+  .teUserInfo {
+    display: flex;
+    align-items: center;
+    font-size: 12px;
+    color: #999;
+    padding: 2px 0;
+
+    .teUserLogo {
+      width: 18px;
+      height: 18px;
+      border-radius: 50%;
+      margin-right: 5px;
+      overflow: hidden;
+    }
+
+    .teUserName {
+      padding-right: 6px;
+      margin-right: 6px;
+      max-width: 65px;
+      // &::after {
+      //   content: '|';
+      //   display: inline-block;
+      // }
+    }
+  }
+  .teUserNum {
+    color: #999999;
+  }
+}
+
+
+.videoGroup {
+  width: 90%;
+  line-height: 0;
+  overflow: inherit;
+
+  :global {
+    .colVideo {
+      border-radius: var(--van-popup-round-border-radius);
+      overflow: hidden;
+    }
+
+    .video-js {
+      border-radius: var(--van-popup-round-border-radius);
+    }
+  }
+}
+
+.searchContainer {
+  background-color: #fff;
+}
+.item {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 14px;
+
+  .searchItem {
+    width: 168px;
+    height: 56px;
+  }
+  .title {
+    font-size: 14px;
+    font-weight: 600;
+    color: #333333;
+    line-height: 20px;
+    padding-top: 10px;
+    padding-left: 75px;
+  }
+  .content {
+    padding-left: 75px;
+    font-size: 12px;
+    color: #666666;
+    line-height: 20px;
+  }
+
+  .searchFollow {
+    background: url('./images/follow_bg.png') no-repeat center;
+    background-size: 100%;
+  }
+  .active {
+    .title,
+    .content {
+      color: #ff1f95;
+    }
+  }
+  .searchLive {
+    background: url('./images/live_bg.png') no-repeat center;
+    background-size: 100%;
+  }
+  .active2 {
+    .title,
+    .content {
+      color: var(--van-primary);
+    }
+  }
+}
+.searchDefault {
+  margin: 0 0 12px 14px;
+  display: inline-flex;
+  align-items: center;
+  padding: 4px 8px;
+  border-radius: 20px;
+  color: #666666;
+  font-size: 13px;
+  background: #f7f8f9;
+  .star {
+    margin-right: 5px;
+  }
+}
+
+.video {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  min-height: 100%;
+  background-color: #ccc;
+  border-radius: 4px 4px 0 0;
+}
+
+.living {
+  position: absolute;
+  top: 0;
+  left: 0;
+  color: #fff;
+  font-weight: 500;
+  right: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 16px;
+  bottom: 0;
+  background: rgba(51, 51, 51, 0.5);
+  span {
+    padding-left: 5px;
+  }
+}
+.animation {
+  height: 18px !important;
+  width: 20px !important;
+}

+ 143 - 5
src/student/teacher-dependent/teacher-style/index.tsx

@@ -1,11 +1,149 @@
-import { defineComponent } from "vue";
+import { defineComponent, reactive } from 'vue'
 import styles from './index.module.less'
+import request from '@/helpers/request'
+import { useRoute } from 'vue-router'
+import ColHeader from '@/components/col-header'
+import ColResult from '@/components/col-result'
+import { List, Popup, Sticky, Image, Icon } from 'vant'
+
+import iconTeacher from '@common/images/icon_teacher.png'
+import iconUploadPoster from '@common/images/icon_upload_poster.png'
+import TheSticky from '@/components/the-sticky'
+import iconVideo from '../images/icon_video.png'
+import ColVideo from '@/components/col-video'
 
 export default defineComponent({
   name: 'teacher-style',
   setup() {
-    return () => <div>
-      
-    </div>
+    const route = useRoute()
+    const state = reactive({
+      videoStatus: false,
+      videoItem: {} as any,
+      isAddBrowse: false,
+      dataShow: false,
+      teacherId: route.query.teacherId,
+      list: [] as any,
+      userInfo: {} as any
+    })
+    const getTeacherDetail = async () => {
+      state.dataShow = true
+      try {
+        const { data } = await request.get(
+          '/api-student/teacher/queryTeacherHome',
+          {
+            params: {
+              userId: state.teacherId
+            }
+          }
+        )
+        state.userInfo = data
+        state.list = data.styleVideo || []
+        state.dataShow = state.list.length > 0 ? true : false
+      } catch {}
+    }
+    getTeacherDetail()
+
+    const onPlay = async () => {
+      try {
+        if (!state.isAddBrowse) {
+          return
+        }
+        await request.get('/api-student/teacher/addVideoBrowse', {
+          hideLoading: true,
+          params: {
+            videoId: state.videoItem.id
+          }
+        })
+        state.isAddBrowse = false
+      } catch {}
+    }
+    
+    return () => (
+      <div class={styles['teacher-elegant']}>
+        <TheSticky>
+          <ColHeader
+            border={false}
+            background="transparent"
+            isFixed={false}
+          />
+        </TheSticky>
+
+        {state.dataShow ? (
+          <div class={[styles.elegant]}>
+            {state.list.map((item: any) => (
+              <div class={styles.tedeoItem}>
+                <div
+                  class={styles.itemBg}
+                  onClick={() => {
+                    state.videoStatus = true
+                    state.isAddBrowse = true
+                    state.videoItem = item
+                  }}
+                ></div>
+                <img class={styles.iconVideo} src={iconVideo} />
+                <div class={styles.teCover}>
+                  <Image src={item.cover || iconUploadPoster} fit="cover" />
+                </div>
+                <div class={styles.teSection}>
+                  <div class={styles.info}>
+                    <div class={styles.teUserInfo}>
+                      <Image
+                        src={item.avatar || iconTeacher}
+                        class={styles.teUserLogo}
+                      />
+                      <span
+                        class={[
+                          styles.teUserName,
+                          'van-hairline--right van-ellipsis'
+                        ]}
+                      >
+                        {item?.username || `游客${item?.userId || ''}`}
+                      </span>
+                    </div>
+                    <span class={styles.teUserNum}>{item.browse}浏览</span>
+                  </div>
+                </div>
+              </div>
+            ))}
+          </div>
+        ) : (
+          <ColResult
+            btnStatus={false}
+            classImgSize="SMALL"
+            tips="暂无老师风采"
+          />
+        )}
+
+        <Popup
+          show={state.videoStatus}
+          round
+          class={styles.videoGroup}
+          closeable
+          onClose={() => {
+            state.videoStatus = false
+            state.isAddBrowse = false
+          }}
+        >
+          {state.videoStatus && (
+            <ColVideo
+              playsinline
+              onPlay={onPlay}
+              src={state.videoItem?.videoUrl}
+            />
+          )}
+
+          {/* <video
+            style={{ height: '210px', width: '100%' }}
+            controls
+            class={styles.video}
+          >
+            <source
+              src={this.videoItem?.videoUrl + '#t=1,4'}
+              type="video/mp4"
+            />
+          </video> */}
+        </Popup>
+      </div>
+    )
   }
-})
+})

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

@@ -17,7 +17,7 @@ export default defineComponent({
   },
   computed: {
     isNeedView() {
-      return state.user.status === 'login' || this.$route.path === '/login'
+      return state.user.status === 'login' || this.$route.path === '/login' || this.$route.path === '/login-cert'
     }
   },
   mounted() {

BIN
src/teacher/layout/image-cert/bg.png


BIN
src/teacher/layout/image-cert/top.png


+ 99 - 0
src/teacher/layout/login-cert.module.less

@@ -0,0 +1,99 @@
+.login {
+  position: relative;
+  min-height: 100vh;
+  background: url('./image-cert/bg.png') no-repeat top center;
+  background-color: #F5F5F0;
+  background-size: 100%;
+  overflow: hidden;
+
+  .topBg {
+    position: absolute;
+    top: 0;
+    width: 100%
+  }
+
+  .codeText {
+    color: var(--van-primary);
+  }
+
+  .content {
+    margin: 350px 5px 0;
+    position: relative;
+    z-index: 1;
+
+    background: rgba(45,199,170,0.15);
+    border-radius: 20px;
+    border: 2px solid #FFFFFF;
+
+    .cellGroup {
+      margin: 9px;
+      padding: 20px;
+      border-radius: 18px;
+    }
+  }
+
+  .margin34 {
+    margin: 0 34px;
+  }
+
+  .formTitle {
+    font-weight: 500;
+    font-size: 17px;
+    color: #000000;
+    line-height: 24px;
+  }
+
+  :global {
+    .van-field {
+      padding-left: 0;
+      padding-right: 0;
+    }
+    .van-button  {
+      font-size: 18px;
+      color: #FFFFFF;
+    }
+
+    .van-checkbox {
+      display: inline-block;
+      align-items: inherit;
+      overflow: inherit;
+    }
+
+    .van-checkbox__icon {
+      height: 14px;
+      line-height: 14px;
+      display: inline-block;
+      vertical-align: text-bottom;
+
+      .van-icon__image, .van-icon {
+        width: 14px;
+        height: 14px;
+      }
+    }
+
+    .van-checkbox__label {
+      line-height: 14px;
+      color: #999;
+    }
+  }
+}
+
+.protocol {
+  font-size: 12px;
+  padding: 37px 0 12px;
+  text-align: center;
+  color: #999;
+
+  .protocolText {
+    color: var(--van-primary);
+    line-height: 14px;
+  }
+
+  .boxStyle {
+    background: transparent !important;
+    width: 14px;
+    height: 14px;
+    font-size: 14px;
+    border: transparent !important;
+  }
+}

+ 244 - 0
src/teacher/layout/login-cert.tsx

@@ -0,0 +1,244 @@
+import { defineComponent } from 'vue'
+import { CellGroup, Field, Button, CountDown, Row, Col, Toast, Checkbox, Icon } from 'vant'
+import ImgCode from '@/components/col-img-code'
+import { checkPhone } from '@/helpers/validate'
+import request from '@/helpers/request'
+import { setLogin, state } from '@/state'
+import { removeAuth, setAuth } from '@/helpers/utils'
+import styles from './login-cert.module.less'
+import topBg from './image-cert/top.png'
+import activeButtonIcon from '@common/images/icon_checkbox.png'
+import inactiveButtonIcon from '@common/images/icon_checkbox_default.png'
+
+type loginType = 'PWD' | 'SMS'
+export default defineComponent({
+  name: 'login',
+  data() {
+    return {
+      checked: false,
+      loginType: 'SMS' as loginType,
+      username: '',
+      password: '',
+      smsCode: '',
+      countDownStatus: true, // 是否发送验证码
+      countDownTime: 1000 * 120, // 倒计时时间
+      countDownRef: null as any, // 倒计时实例
+      imgCodeStatus: false
+    }
+  },
+  computed: {
+    codeDisable() {
+      let status = true
+      if (this.loginType === 'PWD') {
+        this.username && this.password && (status = false)
+      } else {
+        this.username && this.smsCode && this.checked && (status = false)
+      }
+      return status
+    }
+  },
+  mounted() {
+    removeAuth()
+    this.directNext()
+  },
+  methods: {
+    previewProtocol(type: string) {
+      if (type === 'user') {
+        this.$router.push({
+          path: '/registerProtocol',
+          query: {
+            showHeader: 1
+          }
+        })
+      } else if (type === 'privacy') {
+        this.$router.push({
+          path: '/privacyProtocol',
+          query: {
+            showHeader: 1
+          }
+        })
+      }
+    },
+    directNext() {
+      if (state.user.status === 'login' || state.user.status === 'error') {
+        const { returnUrl, isRegister, ...rest } = this.$route.query
+        this.$router.replace({
+          path: '/teacherCert',
+          query: {
+            ...rest
+          }
+        })
+      }
+    },
+    async onLogin() {
+      try {
+        let res: any
+        if (this.loginType === 'PWD') {
+          res = await request.post('/api-auth/usernameLogin', {
+            requestType: 'form',
+            data: {
+              username: this.username,
+              password: this.password,
+              clientId: 'teacher',
+              clientSecret: 'teacher'
+            }
+          })
+        } else {
+          res = await request.post('/api-auth/smsLogin', {
+            requestType: 'form',
+            data: {
+              clientId: 'teacher',
+              clientSecret: 'teacher',
+              phone: this.username,
+              smsCode: this.smsCode
+            }
+          })
+        }
+
+        const { authentication } = res.data
+        setAuth(authentication.token_type + ' ' + authentication.access_token)
+
+        let userCash = await request.get('/api-teacher/teacher/queryUserInfo', {
+          initRequest: true // 初始化接口
+        })
+        setLogin(userCash.data)
+
+        this.directNext()
+      } catch {}
+    },
+    async onSendCode() {
+      // 发送验证码
+      if (!checkPhone(this.username)) {
+        return Toast('请输入正确的手机号码')
+      }
+      this.imgCodeStatus = true
+    },
+    onCodeSend() {
+      this.countDownStatus = false
+      this.countDownRef.start()
+    },
+    onFinished() {
+      this.countDownStatus = true
+      this.countDownRef.reset()
+    },
+    onChange() {
+      if (this.loginType === 'PWD') {
+        this.loginType = 'SMS'
+      } else if (this.loginType === 'SMS') {
+        this.loginType = 'PWD'
+      }
+    }
+  },
+  render() {
+    return (
+      <div class={styles.login}>
+        <img src={topBg} class={styles.topBg} />
+        <div class={styles.content}>
+          <CellGroup class={styles.cellGroup} border={false}>
+            <Row style={{ marginBottom: '16px' }}>
+              <Col span={24} class={styles.formTitle}>
+                手机号
+              </Col>
+              <Col span={24} class="van-hairline--bottom">
+                <Field
+                  v-model={this.username}
+                  name="手机号"
+                  placeholder="请输入您的手机号"
+                  type="tel"
+                  maxlength={11}
+                />
+              </Col>
+            </Row>
+
+            <Row>
+              <Col span={24} class={styles.formTitle}>
+                验证码
+              </Col>
+              <Col span={24} class="van-hairline--bottom">
+                <Field
+                  v-model={this.smsCode}
+                  name="验证码"
+                  placeholder="请输入验证码"
+                  type="tel"
+                  maxlength={6}
+                  // @ts-ignore
+                  vSlots={{
+                    button: () =>
+                      this.countDownStatus ? (
+                        <span class={styles.codeText} onClick={this.onSendCode}>
+                          发送验证码
+                        </span>
+                      ) : (
+                        <CountDown
+                          ref={this.countDownRef}
+                          auto-start={false}
+                          time={this.countDownTime}
+                          onFinish={this.onFinished}
+                          format="ss秒"
+                        />
+                      )
+                  }}
+                />
+              </Col>
+            </Row>
+          </CellGroup>
+        </div>
+        <div class={styles.margin34}>
+          <div class={styles.protocol}>
+            <Checkbox
+              v-model={this.checked}
+              v-slots={{
+                icon: (props: any) => (
+                  <Icon
+                    class={styles.boxStyle}
+                    name={props.checked ? activeButtonIcon : inactiveButtonIcon}
+                    size="15"
+                  />
+                )
+              }}
+            >
+              我已阅读并同意
+            </Checkbox>
+            <span
+              class={styles.protocolText}
+              onClick={() => {
+                this.previewProtocol('user')
+              }}
+            >
+              《用户注册协议》
+            </span>
+            和
+            <span
+              class={styles.protocolText}
+              onClick={() => {
+                this.previewProtocol('privacy')
+              }}
+            >
+              《隐私政策》
+            </span>
+          </div>
+          <Button
+            round
+            block
+            type="primary"
+            disabled={this.codeDisable}
+            onClick={this.onLogin}
+          >
+            确认
+          </Button>
+        </div>
+
+        {this.imgCodeStatus ? (
+          <ImgCode
+            v-model:value={this.imgCodeStatus}
+            phone={this.username}
+            onClose={() => {
+              this.imgCodeStatus = false
+            }}
+            onSendCode={this.onCodeSend}
+          />
+        ) : null}
+      </div>
+    )
+  }
+})

+ 1 - 0
src/views/adapay/payment/index.tsx

@@ -131,6 +131,7 @@ export default defineComponent({
       emit('backOut')
     }
     const onSubmit = async () => {
+      console.log(props.paymentVendor,'props.paymentVendor')
       if (
         props.paymentVendor &&
         (props.paymentVendor.indexOf('wxpay') > -1 ||

+ 19 - 0
src/views/music/list/index.module.less

@@ -35,11 +35,26 @@
   }
 }
 
+.searchGroup {
+  background-color: #F8F9FC;
+  :global {
+    .van-search {
+      padding-top: 0;
+      // padding-bottom: 0;
+      padding-bottom: 12px;
+    }
+  }
+}
+
 .label {
   margin-right: 8px;
   font-size: 14px;
   color: #fff;
 
+  &.searchs {
+    color: #131415;
+  }
+
   :global {
 
     .van-list__loading,
@@ -59,6 +74,10 @@
   border-radius: 18px;
   background-color: #fff;
   margin: 14px;
+
+  &.alumnListOnly {
+    margin-top: 0;
+  }
 }
 
 .bgImg {

+ 46 - 3
src/views/music/list/index.tsx

@@ -1,4 +1,4 @@
-import { defineComponent, nextTick, onMounted, reactive, ref } from 'vue'
+import { computed, defineComponent,  nextTick, onMounted, reactive, ref, watch } from 'vue'
 import { Sticky, List, Popup, Icon, Switch, Tabs, Tab } from 'vant'
 import Search from '@/components/col-search'
 import request from '@/helpers/request'
@@ -31,6 +31,14 @@ export default defineComponent({
       type: Boolean,
       default: false
     },
+    onlySearch: {
+      type: Boolean,
+      default: false
+    },
+    height: {
+      type: Boolean,
+      default: 0
+    },
     defauleParams: {
       type: Object,
       default: () => ({})
@@ -49,7 +57,7 @@ export default defineComponent({
     }
   },
   setup(
-    { hideSearch, defauleParams, onItemClick, teacherId, myself },
+    { hideSearch, onlySearch, height, defauleParams, onItemClick, teacherId, myself },
     { expose }
   ) {
     const { isLoading, state } = useAsyncState(
@@ -61,6 +69,13 @@ export default defineComponent({
       null
     )
 
+    const stickyHeight = ref(height || 0)
+
+    const updateStickyHeight = (height: number) => {
+      stickyHeight.value = height
+    }
+
+
     const teacherDetaultSubject = ref({
       id: '',
       name: ''
@@ -278,6 +293,7 @@ export default defineComponent({
     expose({
       onSearch,
       onComfirm,
+      updateStickyHeight,
       onComfirmSubject
     })
 
@@ -365,7 +381,34 @@ export default defineComponent({
               <img class={styles.bgImg} src={bgImg} />
             </>
           )}
-          <div class={styles.alumnList}>
+          {onlySearch ? <Sticky position='top' offsetTop={stickyHeight.value as any}><Search
+                  onSearch={onSearch}
+                  background="transparent"
+                  inputBackground='white'
+                  // leftIcon={iconSearch}
+                  class={styles.searchGroup}
+                  v-slots={{
+                    left: () => (
+                      <div
+                        class={[styles.label, styles.searchs]}
+                        onClick={() => (subject.show = true)}
+                      >
+                        {baseState.platformType === 'TEACHER'
+                          ? teacherDetaultSubject.value.name
+                          : subject.name}
+
+                        <Icon
+                          classPrefix="iconfont"
+                          name="down"
+                          size={12}
+                          color="#949597"
+                        />
+                      </div>
+                    )
+                  }}
+                /></Sticky> : ''}
+
+          <div class={[styles.alumnList, onlySearch && styles.alumnListOnly]}>
             <List
               loading={loading.value}
               finished={finished.value}

+ 57 - 47
src/views/order-detail/index.tsx

@@ -45,6 +45,13 @@ import OrderDiscount from './order-discount'
 import OrderVipCourse from './order-vip-course'
 import AddDiscount from './add-discount'
 
+/** 保留两位小数向上取整 */
+export const numberToTwoUp = (num: number | string) => {
+  num = Number(num)
+
+  return Math.ceil(num * 100) / 100
+}
+
 export default defineComponent({
   name: 'order-detail',
   data() {
@@ -110,11 +117,11 @@ export default defineComponent({
     },
     countDiscountPrice() {
       const orderObject = orderStatus.orderObject
-      return orderObject.couponAmount || (orderObject.couponDiscountPrice + orderObject.discountCardPrice + orderObject.discountCardPrice).toFixed(2)
+      return orderObject.couponAmount || numberToTwoUp(orderObject.couponDiscountPrice + orderObject.discountCardPrice + orderObject.discountCardPrice)
     }
   },
   async mounted() {
-    await this.getUserRegisterProtocol()
+    // await this.getUserRegisterProtocol()
     // 判断是否是曲目购买(只有智能陪练才会有入口),其它地方不会有入口
     this.dataLoading = true
     if (this.orderType == 'MUSIC' && this.id) {
@@ -155,9 +162,6 @@ export default defineComponent({
     })
     this.orderGoodsType = tempGoodsType
 
-    console.log(this.orderGoodsType, 'orderGoodsType')
-
-
     await this.getOrderPayType()
 
     this.orderAmount = orderStatus.orderObject.actualPrice || 0
@@ -278,10 +282,9 @@ export default defineComponent({
         if (this.paymentVersion === 'V1') {
           this.paymentStatus = true
         } else {
-          this.orderInfo = orderStatus.orderObject.paymentConfig || {}
+          this.orderInfo = orderStatus.orderObject || {}
           this.orderNo = orderStatus.orderObject.orderNo
-          const paymentChannel = this.orderInfo.paymentConfig.paymentChannel
-
+          const paymentChannel =  this.orderInfo.paymentConfig.paymentChannel
           // 判断是否为原生支付
           if (
             this.orderInfo.paymentVendor?.indexOf('wxpay') > -1 ||
@@ -357,7 +360,7 @@ export default defineComponent({
 
           const res = await request.post(url, {
             data: {
-              activityId: orderObject.activityId || null,
+              activityId: orderObject.activityId > 0 ? orderObject.activityId : null,
               couponIds: orderObject.couponId,
               goodsInfos: goods,
               orderDesc: orderObject.orderDesc,
@@ -437,11 +440,11 @@ export default defineComponent({
       })
 
       const lastAmount = Number(
-        (
+        numberToTwoUp(
           Number(this.orderAmount) -
           orderStatus.orderObject.discountCardPrice -
           Number(discountCount)
-        ).toFixed(2)
+        )
       )
       this.orderPrice = lastAmount >= 0 ? lastAmount : 0
       // 设置优惠券编号
@@ -452,34 +455,33 @@ export default defineComponent({
       orderStatus.orderObject.couponDiscountPrice = discountCount
     },
     onConfirm(val: any) {
-      const config: any = this.orderInfo.paymentConfig || {}
-      orderStatus.orderObject.paymentConfig.paymentConfig.paymentChannel =
-        val.pay_channel
-      this.pay_channel = val.pay_channel
-
-      const params = qs.stringify({
-        pay_channel: val.pay_channel,
-        wxAppId: config.wxAppId,
-        alipayAppId: config.alipayAppId,
-        paymentType: this.orderInfo.paymentType,
-        body: config.body,
-        price: config.price,
-        orderNo: config.merOrderNo,
-        userId: config.userId
-      })
-      if (val.payCode === 'payResult') {
-        window.location.href =
-          window.location.origin + state.payBackPath + '#/payResult?' + params
-      } else {
-        this.qrCodeUrl =
-          window.location.origin + state.payBackPath + '#/payDefine?' + params
-        this.showQrcode = true
-        this.paymentStatus = false
-
-        setTimeout(() => {
-          this.getPaymentOrderStatus()
-        }, 300)
-      }
+        // debugger
+        const config: any = this.orderInfo.paymentConfig || {}
+        this.pay_channel = val.pay_channel
+        const params = qs.stringify({
+          pay_channel: val.pay_channel,
+          wxAppId: config.wxAppId,
+          alipayAppId: config.alipayAppId,
+          paymentType: this.orderInfo.paymentType,
+          body: config.body,
+          price: config.price,
+          orderNo: config.merOrderNo,
+          userId: config.userId
+        })
+        orderStatus.orderObject.paymentConfig.paymentChannel = val.pay_channel
+        if (val.payCode === 'payResult') {
+          window.location.href =
+            window.location.origin + state.payBackPath + '#/payResult?' + params
+        } else {
+          this.qrCodeUrl =
+            window.location.origin + state.payBackPath + '#/payDefine?' + params
+          this.showQrcode = true
+          this.paymentStatus = false
+
+          setTimeout(() => {
+            this.getPaymentOrderStatus()
+          }, 300)
+        }
     },
     // 轮询查询订单状态
     async getPaymentOrderStatus() {
@@ -559,10 +561,10 @@ export default defineComponent({
                       // 重置金额
                       this.orderAmount = Number(price)
                       const lastAmount = Number(
-                        (
+                        numberToTwoUp(
                           Number(this.orderAmount) -
                           Number(orderStatus.orderObject.couponDiscountPrice)
-                        ).toFixed(2)
+                        )
                       )
                       this.orderPrice = lastAmount >= 0 ? lastAmount : 0
                     }}
@@ -587,10 +589,10 @@ export default defineComponent({
                       // 重置金额
                       this.orderAmount = Number(price)
                       const lastAmount = Number(
-                        (
+                        numberToTwoUp(
                           Number(this.orderAmount) -
                           Number(orderStatus.orderObject.couponDiscountPrice)
-                        ).toFixed(2)
+                        )
                       )
                       this.orderPrice = lastAmount >= 0 ? lastAmount : 0
                     }}
@@ -615,12 +617,15 @@ export default defineComponent({
                   discountPrice: number | string
                   vipType: string
                 }) => {
+                  orderStatus.orderObject.discountCardPrice = Number(
+                    item.discountPrice
+                  )
                   this.orderPrice = Number(
-                    (
+                    numberToTwoUp(
                       Number(this.orderAmount) -
                       Number(item.discountPrice) -
                       Number(orderStatus.orderObject.couponDiscountPrice)
-                    ).toFixed(2)
+                    )
                   )
                 }}
                 onConfirm={(item: {
@@ -660,11 +665,11 @@ export default defineComponent({
                   }
 
                   this.orderPrice = Number(
-                    (
+                    numberToTwoUp(
                       Number(this.orderAmount) -
                       Number(item.discountPrice) -
                       Number(orderStatus.orderObject.couponDiscountPrice)
-                    ).toFixed(2)
+                    )
                   )
                 }}
               />
@@ -698,6 +703,7 @@ export default defineComponent({
                 couponId={orderStatus.orderObject.couponId}
                 discountPrice={orderStatus.orderObject.discountPrice}
                 orderType={this.orderType}
+                orderGoodsType={this.orderGoodsType}
                 orderAmount={
                   this.orderAmount - orderStatus.orderObject.discountCardPrice
                 }
@@ -718,6 +724,10 @@ export default defineComponent({
                     v-model={this.agreeStatus}
                     showHeader
                     style={{ paddingLeft: 0, paddingRight: 0 }}
+                    onProtocolExists={(val: any) => {
+                      console.log(val, 'al')
+                      this.exists = val
+                    }}
                   />
                 </div>
               )}

+ 2 - 1
src/views/order-detail/order-discount/index.tsx

@@ -5,6 +5,7 @@ import styles from './index.module.less'
 
 import iconDiscount from '@common/images/icon_discount.png'
 import dayjs from 'dayjs'
+import { numberToTwoUp } from '..'
 
 export default defineComponent({
   name: 'OrderVideo',
@@ -79,7 +80,7 @@ export default defineComponent({
                         // 价格变化
                         this.$emit(
                           'priceChange',
-                          (item.price * item.num).toFixed(2)
+                          numberToTwoUp(item.price * item.num)
                         )
                       }}
                     ></Stepper>

+ 24 - 9
src/views/order-detail/use-coupons/choice-coupon.tsx

@@ -4,7 +4,7 @@ import request from '@/helpers/request'
 import { state } from '@/state'
 import Item from '@/views/coupons/item'
 import { Button, Loading } from 'vant'
-import { defineComponent } from 'vue'
+import { defineComponent, PropType } from 'vue'
 import styles from './index.module.less'
 
 export default defineComponent({
@@ -25,6 +25,10 @@ export default defineComponent({
     couponList: {
       type: Array,
       default: () => []
+    },
+    usedLength: {
+      type: String as PropType<'SINGLE' | 'MULTIPLE'>,
+      default: 'MULTIPLE'
     }
   },
   emits: ['close', 'submit'],
@@ -135,14 +139,25 @@ export default defineComponent({
           : 0
       // 使用优惠券后,可判断的金额
       const useLastAmount = this.orderAmount - usePrice
-      // 判断使用优惠券之后还有没有其它优惠券可用
-      this.list.forEach((item: any) => {
-        if (Number(item.useLimit) > useLastAmount && !item.checked) {
-          item.disabled = true
-        } else {
-          item.disabled = false
-        }
-      })
+      if(this.usedLength === 'SINGLE') {
+        // 判断使用优惠券之后还有没有其它优惠券可用
+        this.list.forEach((item: any) => {
+          if (!item.checked && useList.length > 0) {
+            item.disabled = true
+          } else {
+            item.disabled = false
+          }
+        })
+      } else {
+        // 判断使用优惠券之后还有没有其它优惠券可用
+        this.list.forEach((item: any) => {
+          if (Number(item.useLimit) > useLastAmount && !item.checked) {
+            item.disabled = true
+          } else {
+            item.disabled = false
+          }
+        })
+      }
     }
   },
   render() {

+ 1 - 1
src/views/order-detail/use-coupons/index.module.less

@@ -5,7 +5,7 @@
   .couponCount {
     color: #ff3535;
     font-size: 14px;
-    font-weight: 600;
+    font-weight: 500;
 
     i {
       font-style: normal;

+ 12 - 2
src/views/order-detail/use-coupons/index.tsx

@@ -1,7 +1,7 @@
 import request from '@/helpers/request'
 import { state } from '@/state'
 import { Cell, Popup } from 'vant'
-import { defineComponent } from 'vue'
+import { defineComponent, PropType } from 'vue'
 import ChoiceCoupon from './choice-coupon'
 import styles from './index.module.less'
 
@@ -38,6 +38,10 @@ export default defineComponent({
       type: String,
       default: ''
     },
+    orderGoodsType: {
+      type: Array,
+      default: () => []
+    },
     discountPrice: {
       // 优惠券使用金额
       type: Number,
@@ -47,6 +51,10 @@ export default defineComponent({
     couponId: {
       type: String,
       default: ''
+    },
+    usedLength: {
+      type: String as PropType<'SINGLE' | 'MULTIPLE'>,
+      default: 'SINGLE'
     }
   },
   emits: ['couponSelect'],
@@ -81,7 +89,8 @@ export default defineComponent({
     },
     couponCategory() {
       // 如果订单类型不在优惠券类型里面,则默认查询通用券
-      return couponEnum[this.orderType] || 'UNIVERSAL'
+      const temp = this.orderGoodsType.map((item: any)=> couponEnum[item])
+      return temp.join(',') + ',UNIVERSAL'
     }
   },
   watch: {
@@ -219,6 +228,7 @@ export default defineComponent({
           {/* 优化体验 */}
           {this.popupLoading && (
             <ChoiceCoupon
+              usedLength={this.usedLength}
               couponCategory={this.couponCategory}
               useCoupon={this.useCouponList}
               orderAmount={this.orderAmount}