فهرست منبع

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

mo 2 سال پیش
والد
کامیت
10acbae268
39فایلهای تغییر یافته به همراه589 افزوده شده و 263 حذف شده
  1. 21 8
      src/components/o-upload-all/index.tsx
  2. 33 1
      src/router/routes-school.ts
  3. 40 0
      src/school/approval-manage/MyApproval.tsx
  4. 46 0
      src/school/approval-manage/agency/index.module.less
  5. 52 0
      src/school/approval-manage/agency/index.tsx
  6. 1 1
      src/school/approval-manage/batch-adjust.tsx
  7. 1 1
      src/school/approval-manage/components/end-approval.tsx
  8. 0 1
      src/school/approval-manage/components/wait-approval.module.less
  9. 10 10
      src/school/approval-manage/components/wait-approval.tsx
  10. 9 11
      src/school/approval-manage/course-adjust.tsx
  11. BIN
      src/school/approval-manage/images/icon-arrow.png
  12. BIN
      src/school/approval-manage/images/icon-subsidy.png
  13. 14 0
      src/school/approval-manage/index.module.less
  14. 10 12
      src/school/approval-manage/index.tsx
  15. 39 0
      src/school/companion-teacher/companion-teacher-register.module.less
  16. 22 1
      src/school/companion-teacher/companion-teacher-register.tsx
  17. 39 0
      src/school/manage-teacher/manage-teacher-register.module.less
  18. 22 1
      src/school/manage-teacher/manage-teacher-register.tsx
  19. 1 0
      src/school/orchestra-story/index.tsx
  20. 2 0
      src/school/orchestra-story/story-operation/index.tsx
  21. 2 2
      src/school/orchestra/create-orchestra/index.tsx
  22. 1 1
      src/school/orchestra/modal/student-list.tsx
  23. 1 1
      src/school/orchestra/modal/subject-list.tsx
  24. 6 2
      src/school/train-planning/component/practice-detail/index.tsx
  25. 10 0
      src/school/train-planning/component/practice/index.tsx
  26. 6 4
      src/student/music-group/goods-detail/index.tsx
  27. 7 2
      src/student/music-group/pre-apply/component/payment.tsx
  28. 7 2
      src/student/music-group/pre-apply/order-detail.tsx
  29. BIN
      src/student/payment-result/images/icon_close.png
  30. BIN
      src/student/payment-result/images/icon_refunded.png
  31. BIN
      src/student/payment-result/images/icon_refunding.png
  32. BIN
      src/student/payment-result/images/icon_success.png
  33. BIN
      src/student/payment-result/images/icon_tradeing.png
  34. 19 14
      src/student/payment-result/index.module.less
  35. 39 10
      src/student/payment-result/index.tsx
  36. 1 1
      src/views/coursewarePlay/index.module.less
  37. 1 1
      src/views/coursewarePlay/index.tsx
  38. 26 9
      src/views/exercise-after-class/index.module.less
  39. 101 167
      src/views/exercise-after-class/index.tsx

+ 21 - 8
src/components/o-upload-all/index.tsx

@@ -68,14 +68,22 @@ export default defineComponent({
       if (this.disabled) {
         return
       }
+      const type = this.uploadType === 'VIDEO' ? 'video' : 'img'
       postMessage(
         {
           api: 'chooseFile',
-          content: { type: 'img', max: 1, bucket: this.bucket }
+          content: { type: type, max: 1, bucket: this.bucket }
         },
         (res: any) => {
           console.log(res, 'fileUrl')
-          this.$emit('update:modelValue', [...this.modelValue, res.fileUrl])
+          // 判断是否是多选
+          if (this.maxCount > 1) {
+            this.$emit('update:modelValue', [...this.modelValue, res.fileUrl])
+            this.onUploadChange([...this.modelValue, res.fileUrl])
+          } else {
+            this.$emit('update:modelValue', [res.fileUrl])
+            this.onUploadChange([res.fileUrl])
+          }
         }
       )
     },
@@ -175,8 +183,13 @@ export default defineComponent({
         const uploadUrl = getOssUploadUrl(this.bucket) + key
         closeToast()
         // 判断是否是多选
-        this.$emit('update:modelValue', [...this.modelValue, uploadUrl])
-        this.onUploadChange([...this.modelValue, uploadUrl])
+        if (this.maxCount > 1) {
+          this.$emit('update:modelValue', [...this.modelValue, uploadUrl])
+          this.onUploadChange([...this.modelValue, uploadUrl])
+        } else {
+          this.$emit('update:modelValue', [uploadUrl])
+          this.onUploadChange([uploadUrl])
+        }
       } catch (error) {
         console.log(error, 'uploadFile')
       }
@@ -217,6 +230,10 @@ export default defineComponent({
         {this.native ? (
           this.maxCount > 1 ? (
             <div class={[styles.uploader, styles[this.size]]} onClick={this.nativeUpload}>
+              <Icon name={this.uploadIcon} class={['van-uploader__upload']} size="32" />
+            </div>
+          ) : (
+            <div class={[styles.uploader, styles[this.size]]} onClick={this.nativeUpload}>
               {this.modelValue.length > 0 ? (
                 <div class={['van-uploader__upload']}>
                   {this.modelValue.map((item: any) => (
@@ -246,10 +263,6 @@ export default defineComponent({
                 <Icon name={this.uploadIcon} class={['van-uploader__upload']} size="32" />
               )}
             </div>
-          ) : (
-            <div class={[styles.uploader, styles[this.size]]} onClick={this.nativeUpload}>
-              <Icon name={this.uploadIcon} class={['van-uploader__upload']} size="32" />
-            </div>
           )
         ) : this.maxCount > 1 ? (
           <Uploader

+ 33 - 1
src/router/routes-school.ts

@@ -301,7 +301,39 @@ export default [
         meta: {
           title: '添加事迹'
         }
-      }
+      },
+      {
+        path: '/approval-manage-subsidy',
+        name: 'approval-manage-subsidy',
+        component: () => import('@/school/approval-manage/subsidy/index'),
+        meta: {
+          title: '补助确认'
+        }
+      },
+      {
+        path: '/subsidy-exercise-detail',
+        name: 'subsidy-exercise-detail',
+        component: () => import('@/school/approval-manage/subsidy/exercise-detail'),
+        meta: {
+          title: '训练补助详情'
+        }
+      },
+      {
+        path: '/subsidy-grant-detail',
+        name: 'subsidy-grant-detail',
+        component: () => import('@/school/approval-manage/subsidy/grant-detail'),
+        meta: {
+          title: '管理补助详情'
+        }
+      },
+      {
+        path: '/subsidy-reward-detail',
+        name: 'subsidy-reward-detail',
+        component: () => import('@/school/approval-manage/subsidy/reward-detail'),
+        meta: {
+          title: '练习奖励详情'
+        }
+      },
 
       //
     ]

+ 40 - 0
src/school/approval-manage/MyApproval.tsx

@@ -0,0 +1,40 @@
+import { ActionSheet, ActionSheetAction } from 'vant'
+import { computed, defineComponent, ref } from 'vue'
+import EndApproval from './components/end-approval'
+import WaitApproval from './components/wait-approval'
+import iconArrow from './images/icon-arrow.png'
+import styles from './index.module.less'
+
+export default defineComponent({
+  name: 'MyApproval',
+  setup(props, ctx) {
+    const actions = computed(() => {
+      return [
+        { name: '待审批', color: activeName.value == '待审批' ? 'var(--van-primary-color)' : '' },
+        { name: '已完成', color: activeName.value == '已完成' ? 'var(--van-primary-color)' : '' }
+      ]
+    })
+    const activeName = ref('待审批')
+    const show = ref(false)
+    return () => (
+      <div class={styles.MyApproval}>
+        <div class={styles.select} onClick={() => (show.value = true)}>
+          <span>{activeName.value}</span>
+          <img src={iconArrow} />
+        </div>
+        <ActionSheet
+          teleport="body"
+          cancelText="取消"
+          v-model:show={show.value}
+          actions={actions.value}
+          onSelect={(action: ActionSheetAction, index: number) => {
+            activeName.value = action.name || '待审批'
+            show.value = false
+          }}
+        ></ActionSheet>
+
+        {activeName.value == '待审批' ? <WaitApproval /> : <EndApproval />}
+      </div>
+    )
+  }
+})

+ 46 - 0
src/school/approval-manage/agency/index.module.less

@@ -0,0 +1,46 @@
+.item {
+  border-radius: 10px;
+  margin: 12px 13px;
+  overflow: hidden;
+  :global {
+    .van-cell::after {
+      left: 0;
+      right: 0;
+    }
+    .van-cell__label {
+      font-size: 13px;
+      color: #777;
+    }
+  }
+  .itemTitle {
+    display: flex;
+    align-items: center;
+    font-size: 16px;
+    .titleIcon {
+      width: 18px;
+      height: 18px;
+      margin-right: 6px;
+    }
+  }
+}
+
+.grid {
+  :global {
+    .van-grid-item__content {
+      padding: 15px 5px 20px 5px;
+    }
+  }
+  .gridItem{
+    text-align: center;
+    font-size: 12px;
+    color: #777;
+    .gridItemTop{
+        margin-bottom: 6px;
+    }
+    .topNum{
+        color: #F67146;
+        font-size: 22px;
+        margin-right: 2px;
+    }
+  }
+}

+ 52 - 0
src/school/approval-manage/agency/index.tsx

@@ -0,0 +1,52 @@
+import { Cell, Grid, GridItem } from 'vant'
+import { defineComponent } from 'vue'
+import styles from './index.module.less'
+import iconSubsidy from '../images/icon-subsidy.png'
+
+export default defineComponent({
+  name: 'approval-manage-agency',
+  setup() {
+    return () => (
+      <div>
+        <div class={styles.item}>
+          <Cell center label="2023-1-16 至 2023-1-2" isLink>
+            {{
+              title: () => (
+                <div class={styles.itemTitle}>
+                  <img class={styles.titleIcon} src={iconSubsidy} />
+                  <span>补助确认</span>
+                </div>
+              )
+            }}
+          </Cell>
+          <Grid class={styles.grid} columnNum={3} border={false}>
+            <GridItem>
+              <div class={styles.gridItem}>
+                <div class={styles.gridItemTop}>
+                  <span class={styles.topNum}>240</span>元
+                </div>
+                <div>管理补助</div>
+              </div>
+            </GridItem>
+            <GridItem>
+              <div class={styles.gridItem}>
+                <div class={styles.gridItemTop}>
+                  <span class={styles.topNum}>240</span>元
+                </div>
+                <div>管理补助</div>
+              </div>
+            </GridItem>
+            <GridItem>
+              <div class={styles.gridItem}>
+                <div class={styles.gridItemTop}>
+                  <span class={styles.topNum}>240</span>元
+                </div>
+                <div>管理补助</div>
+              </div>
+            </GridItem>
+          </Grid>
+        </div>
+      </div>
+    )
+  }
+})

+ 1 - 1
src/school/approval-manage/batch-adjust.tsx

@@ -167,7 +167,7 @@ export default defineComponent({
             type="number"
             v-model={forms.adjustDay}
             placeholder="请输入调整天数"
-            v-slots={{ extra: () => '天' }}
+            v-slots={{ extra: () => <span style={{ paddingLeft: '6px' }}>天</span> }}
           />
         </CellGroup>
 

+ 1 - 1
src/school/approval-manage/components/end-approval.tsx

@@ -74,7 +74,7 @@ export default defineComponent({
             <OFullRefresh
               v-model:modelValue={refreshing.value}
               onRefresh={onRefresh}
-              style="min-height: 100vh;"
+              style="min-height: calc(100vh - 2.50666rem);"
             >
               <List
                 loading-text=" "

+ 0 - 1
src/school/approval-manage/components/wait-approval.module.less

@@ -1,3 +1,2 @@
 .approvalWrap {
-  margin-top: 12px;
 }

+ 10 - 10
src/school/approval-manage/components/wait-approval.tsx

@@ -71,12 +71,12 @@ export default defineComponent({
     return () => (
       <>
         <div class={styles.approvalWrap}>
-          {showContact.value ? (
-            <OFullRefresh
-              v-model:modelValue={refreshing.value}
-              onRefresh={onRefresh}
-              style="min-height: 100vh;"
-            >
+          <OFullRefresh
+            v-model:modelValue={refreshing.value}
+            onRefresh={onRefresh}
+            style="min-height: calc(100vh - 2.50666rem);"
+          >
+            {showContact.value ? (
               <List
                 v-model:loading={loading.value}
                 finished={finished.value}
@@ -95,10 +95,10 @@ export default defineComponent({
                   </div>
                 ))}
               </List>
-            </OFullRefresh>
-          ) : (
-            <OEmpty />
-          )}
+            ) : (
+              <OEmpty />
+            )}
+          </OFullRefresh>
         </div>
       </>
     )

+ 9 - 11
src/school/approval-manage/course-adjust.tsx

@@ -1,5 +1,5 @@
 import OHeader from '@/components/o-header'
-import { CellGroup, Cell, Button, showToast, Field, Tag } from 'vant'
+import { CellGroup, Cell, Button, showToast, Field, Tag, showSuccessToast } from 'vant'
 import { defineComponent, reactive, ref, onMounted } from 'vue'
 import { postMessage } from '@/helpers/native-message'
 import styles from './course-adjust.module.less'
@@ -115,9 +115,9 @@ export default defineComponent({
       // await getDetail()
       // await getList()
       if (browser().iPhone && !state.cacheId && state.isBack != 'true') {
-        setTimeout(() => {
-          postMessage({ api: 'back' })
-        }, 1000)
+        // setTimeout(() => {
+        postMessage({ api: 'back' })
+        // }, 1000)
       } else {
         router.back()
       }
@@ -142,15 +142,13 @@ export default defineComponent({
             cacheId: state.cacheId
           }
         })
-        reset()
+
         setTimeout(() => {
-          showToast('调整成功')
-          if (browser().isApp) {
-            postMessage({ api: 'back' })
-          } else {
-            router.back()
-          }
+          showSuccessToast('调整成功')
         }, 100)
+        setTimeout(() => {
+          reset()
+        }, 1100)
       } catch (e: any) {
         showToast(e.message)
       }

BIN
src/school/approval-manage/images/icon-arrow.png


BIN
src/school/approval-manage/images/icon-subsidy.png


+ 14 - 0
src/school/approval-manage/index.module.less

@@ -6,3 +6,17 @@
     }
   }
 }
+.MyApproval{
+  .select{
+    display: flex;
+    align-items: center;
+    padding: 0 15px;
+    height: 50px;
+    font-size: 14px;
+    & > img{
+      width: 11px;
+      height: 6px;
+      margin-left: 4px;
+    }
+  }
+}

+ 10 - 12
src/school/approval-manage/index.tsx

@@ -1,11 +1,9 @@
-import OHeader from '@/components/o-header'
-import OSticky from '@/components/o-sticky'
 import { Tabs, Tab } from 'vant'
 import { defineComponent, reactive, ref } from 'vue'
 import styles from './index.module.less'
 import { useRouter } from 'vue-router'
-import WaitApproval from './components/wait-approval'
-import EndApproval from './components/end-approval'
+import MyApproval from './MyApproval'
+import Agency from './agency'
 const activeName = ref('wait')
 export default defineComponent({
   name: 'approval-manage',
@@ -15,14 +13,14 @@ export default defineComponent({
 
     return () => (
       <>
-        <OSticky position="top" background="#F8F8F8">
-          <OHeader></OHeader>
-          <Tabs v-model:active={activeName.value} class={styles.approvalTab}>
-            <Tab name="wait" title="待审批"></Tab>
-            <Tab name="end" title="已完成"></Tab>
-          </Tabs>
-        </OSticky>
-        {activeName.value == 'wait' ? <WaitApproval></WaitApproval> : <EndApproval></EndApproval>}
+        <Tabs v-model:active={activeName.value} class={styles.approvalTab} animated sticky>
+          <Tab name="wait" title="处理事项">
+            <Agency />
+          </Tab>
+          <Tab name="end" title="我的审批">
+            <MyApproval />
+          </Tab>
+        </Tabs>
       </>
     )
   }

+ 39 - 0
src/school/companion-teacher/companion-teacher-register.module.less

@@ -238,3 +238,42 @@ span {
   color: #f67146;
   padding: 9px 10px;
 }
+
+.wxPopupDialog {
+  // position: relative;
+  overflow: initial;
+  // margin-top: -160px;
+  &::before {
+    position: absolute;
+    content: ' ';
+    top: -73px;
+    left: 50%;
+    margin-left: -86px;
+    display: inline-block;
+    background: url('../../student/music-group/pre-apply/images/wx-no-top.png') no-repeat top center;
+    background-size: contain;
+    width: 172px;
+    height: 154px;
+  }
+}
+.popupContainer {
+  background: url('../../student/music-group/pre-apply/images/wx-no-bg.png') no-repeat top center !important;
+  background-size: cover;
+  border-radius: 20px;
+  overflow: hidden;
+  .title1 {
+    padding-top: 57px;
+    text-align: center;
+    font-size: 18px;
+    font-weight: 500;
+    color: #3b2300;
+  }
+  .popupTips {
+    padding-top: 12px;
+    padding-bottom: 47px;
+    text-align: center;
+    font-size: 15px;
+    color: #777777;
+    line-height: 21px;
+  }
+}

+ 22 - 1
src/school/companion-teacher/companion-teacher-register.tsx

@@ -29,6 +29,7 @@ import { checkPhone } from '@/helpers/validate'
 import OUpload from '@/components/o-upload'
 import router from '@/router'
 import dayjs from 'dayjs'
+import { browser } from '@/helpers/utils'
 
 export default defineComponent({
   name: 'companion-teacher-register',
@@ -71,7 +72,8 @@ export default defineComponent({
       countDownStatus: true, // 是否发送验证码
       countDownTime: 120, // 倒计时时间
       countDownRef: null as any, // 倒计时实例
-      imgCodeStatus: false
+      imgCodeStatus: false,
+      showPopup: false
     })
 
     const onSubmit = async () => {
@@ -190,6 +192,12 @@ export default defineComponent({
         showToast('信息获取失败,请联系老师')
       }
 
+      // 判断是否是微信,只能微信中打开
+      // if (!browser().weixin) {
+      //   state.showPopup = true
+      //   return
+      // }
+
       // t: route.query.t, // 过期时间
       try {
         if (state.t) {
@@ -624,6 +632,19 @@ export default defineComponent({
             onSendCode={onCodeSend}
           />
         ) : null}
+
+        <Popup
+          v-model:show={state.showPopup}
+          round
+          style={{ width: '88%' }}
+          closeOnClickOverlay={false}
+          class={styles.wxPopupDialog}
+        >
+          <div class={styles.popupContainer}>
+            <p class={styles.title1}>温馨提示</p>
+            <p class={styles.popupTips}>请使用微信打开</p>
+          </div>
+        </Popup>
       </div>
     )
   }

+ 39 - 0
src/school/manage-teacher/manage-teacher-register.module.less

@@ -239,3 +239,42 @@ span {
   color: #f67146;
   padding: 9px 10px;
 }
+
+.wxPopupDialog {
+  // position: relative;
+  overflow: initial;
+  // margin-top: -160px;
+  &::before {
+    position: absolute;
+    content: ' ';
+    top: -73px;
+    left: 50%;
+    margin-left: -86px;
+    display: inline-block;
+    background: url('../../student/music-group/pre-apply/images/wx-no-top.png') no-repeat top center;
+    background-size: contain;
+    width: 172px;
+    height: 154px;
+  }
+}
+.popupContainer {
+  background: url('../../student/music-group/pre-apply/images/wx-no-bg.png') no-repeat top center !important;
+  background-size: cover;
+  border-radius: 20px;
+  overflow: hidden;
+  .title1 {
+    padding-top: 57px;
+    text-align: center;
+    font-size: 18px;
+    font-weight: 500;
+    color: #3b2300;
+  }
+  .popupTips {
+    padding-top: 12px;
+    padding-bottom: 47px;
+    text-align: center;
+    font-size: 15px;
+    color: #777777;
+    line-height: 21px;
+  }
+}

+ 22 - 1
src/school/manage-teacher/manage-teacher-register.tsx

@@ -27,6 +27,7 @@ import iconClose from './images/icon-close.png'
 import topBanner1 from './images/top-banner.png'
 import { checkPhone } from '@/helpers/validate'
 import dayjs from 'dayjs'
+import { browser } from '@/helpers/utils'
 
 export default defineComponent({
   name: 'companion-teacher-register',
@@ -58,7 +59,8 @@ export default defineComponent({
       countDownStatus: true, // 是否发送验证码
       countDownTime: 120, // 倒计时时间
       // countDownRef: null as any, // 倒计时实例
-      imgCodeStatus: false
+      imgCodeStatus: false,
+      showPopup: false
     })
 
     const onSubmit = async () => {
@@ -119,6 +121,12 @@ export default defineComponent({
         showToast('信息获取失败,请联系老师')
       }
 
+      // 判断是否是微信,只能微信中打开
+      // if (!browser().weixin) {
+      //   state.showPopup = true
+      //   return
+      // }
+
       try {
         if (state.t) {
           const { data } = await request.get('/api-school/open/paramConfig/queryByParamName', {
@@ -396,6 +404,19 @@ export default defineComponent({
             onSendCode={onCodeSend}
           />
         ) : null}
+
+        <Popup
+          v-model:show={state.showPopup}
+          round
+          style={{ width: '88%' }}
+          closeOnClickOverlay={false}
+          class={styles.wxPopupDialog}
+        >
+          <div class={styles.popupContainer}>
+            <p class={styles.title1}>温馨提示</p>
+            <p class={styles.popupTips}>请使用微信打开</p>
+          </div>
+        </Popup>
       </div>
     )
   }

+ 1 - 0
src/school/orchestra-story/index.tsx

@@ -204,6 +204,7 @@ export default defineComponent({
                           {item.type === 'VIDEO' && (
                             <OVideo
                               src={child.url}
+                              height={'100%'}
                               poster={child.coverImage}
                               class={styles.swipeImg}
                             />

+ 2 - 0
src/school/orchestra-story/story-operation/index.tsx

@@ -23,6 +23,7 @@ import OUploadAll from '@/components/o-upload-all'
 import OHeader from '@/components/o-header'
 import ODialog from '@/components/o-dialog'
 import { useRoute, useRouter } from 'vue-router'
+import { browser } from '@/helpers/utils'
 
 export default defineComponent({
   name: 'story-operation',
@@ -334,6 +335,7 @@ export default defineComponent({
                       style={{ marginBottom: '12px' }}
                       v-model:modelValue={forms.video}
                       accept="video/*"
+                      native={browser().isApp}
                       uploadType="VIDEO"
                       uploadIcon={iconUploadVideo}
                       deletable={false}

+ 2 - 2
src/school/orchestra/create-orchestra/index.tsx

@@ -78,7 +78,7 @@ export default defineComponent({
             temps.push({
               id: item.subjectId,
               name: item.subjectName,
-              code: item.code,
+              subjectCode: item.subjectCode,
               type: null,
               teacher: {}, // 老师信息
               students: [] as any // 选中的数据数
@@ -121,7 +121,7 @@ export default defineComponent({
       state.selectSubjects.forEach((item: any) => {
         console.log(item, 'item.name')
         tempStudents.push(...item.students)
-        if (item.code !== 'BARITONE' && item.code !== 'TUBA') {
+        if (item.subjectCode !== 'BARITONE' && item.subjectCode !== 'TUBA') {
           tempSelect.push(item)
         } else {
           // 获取学生

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

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

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

@@ -47,7 +47,7 @@ export default defineComponent({
 
     return () => (
       <div style={{ minHeight: '100vh' }}>
-        <OHeader title="选择声部" />
+        <OHeader title="选择声部" desotry={false} />
 
         <CheckboxGroup
           class={styles.subjectList}

+ 6 - 2
src/school/train-planning/component/practice-detail/index.tsx

@@ -201,8 +201,12 @@ export default defineComponent({
                 formatter={onFormatterInt}
                 maxlength={3}
                 type="tel"
+                onUpdate:modelValue={(val: any) => {
+                  console.log(val)
+                  item.startTime = null
+                }}
               >
-                {{ extra: () => '分钟' }}
+                {{ extra: () => <span style={{ paddingLeft: '6px' }}>分钟</span> }}
               </Field>
               <Field
                 label="开始时间"
@@ -229,7 +233,7 @@ export default defineComponent({
                 maxlength={2}
                 type="tel"
               >
-                {{ extra: () => '课时' }}
+                {{ extra: () => <span style={{ paddingLeft: '6px' }}>课时</span> }}
               </Field>
               <Cell
                 title="训练班级"

+ 10 - 0
src/school/train-planning/component/practice/index.tsx

@@ -12,6 +12,7 @@ import {
   Popup,
   Radio,
   RadioGroup,
+  showLoadingToast,
   showToast,
   Sticky,
   Tag
@@ -63,6 +64,15 @@ export default defineComponent({
     // }
 
     const onSubmit = () => {
+      // showLoadingToast({
+      //   message: '加载中...',
+      //   forbidClick: true,
+      //   loadingType: 'spinner'
+      // })
+      // setTimeout(() => {
+      //   showToast('请选择课程类型请选择课程类型')
+      // }, 1000)
+      // return
       // 判断是否有班级没有设置伴学指导
       if (forms.classList.length > 0) {
         forms.status = true

+ 6 - 4
src/student/music-group/goods-detail/index.tsx

@@ -7,6 +7,10 @@ import styles from './index.module.less'
 export default defineComponent({
   name: 'goods-detail',
   props: {
+    groupPrice: {
+      type: Number,
+      default: 0
+    },
     id: {
       type: String,
       defualt: ''
@@ -182,11 +186,9 @@ export default defineComponent({
                 <div class={styles.priceGroup}>
                   <span class={styles.price}>
                     <i>¥</i>
-                    {moneyFormat(this.getPrice)}
+                    {moneyFormat(this.groupPrice)}
                   </span>
-                  {/* <del class={styles.delPrice}>
-                    ¥{moneyFormat(product.originalPrice)}
-                  </del> */}
+                  <del class={styles.delPrice}>¥{moneyFormat(product.originalPrice)}</del>
                 </div>
               )
               // default: () => <div class={styles.stock}>销量4件</div>

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

@@ -45,7 +45,8 @@ export default defineComponent({
       },
       memberBaoStatus: false, // 团练宝详情状态
       goodsStatus: false, //
-      selectGoodsId: null as any
+      selectGoodsId: null as any,
+      currentPrice: 0
     })
 
     // 查询未支付订单
@@ -329,6 +330,7 @@ export default defineComponent({
                           onClick={(e: any) => {
                             e.stopPropagation()
                             state.selectGoodsId = state.goodsInfo.goodsId
+                            state.currentPrice = state.goodsInfo.currentPrice
                             state.goodsStatus = true
                           }}
                         />
@@ -425,6 +427,7 @@ export default defineComponent({
                           onClick={(e: any) => {
                             e.stopPropagation()
                             state.selectGoodsId = state.textBookInfo.goodsId
+                            state.currentPrice = state.textBookInfo.currentPrice
                             state.goodsStatus = true
                           }}
                         />
@@ -593,7 +596,9 @@ export default defineComponent({
         </OPopup>
 
         <OPopup v-model:modelValue={state.goodsStatus} position="right" destroy>
-          {state.goodsStatus && <GoodsDetail id={state.selectGoodsId} />}
+          {state.goodsStatus && (
+            <GoodsDetail id={state.selectGoodsId} groupPrice={state.currentPrice} />
+          )}
         </OPopup>
       </>
     )

+ 7 - 2
src/student/music-group/pre-apply/order-detail.tsx

@@ -39,7 +39,8 @@ export default defineComponent({
       authShow: false, // 是否进行实名认证
       memberBaoStatus: false, // 团练宝详情状态
       goodsStatus: false, //
-      selectGoodsId: null as any
+      selectGoodsId: null as any,
+      currentPrice: 0
     })
 
     const orderType = computed(() => {
@@ -391,7 +392,9 @@ export default defineComponent({
                   center
                   onClick={() => {
                     if (goods.goodsType === 'INSTRUMENTS' || goods.goodsType === 'TEXTBOOK') {
+                      console.log(goods)
                       state.selectGoodsId = goods.goodsId
+                      state.currentPrice = goods.currentPrice
                       state.goodsStatus = true
                     } else if (goods.goodsType === 'VIP') {
                       state.memberBaoStatus = true
@@ -552,7 +555,9 @@ export default defineComponent({
         </OPopup>
 
         <OPopup v-model:modelValue={state.goodsStatus} position="right" destroy>
-          {state.goodsStatus && <GoodsDetail id={state.selectGoodsId} />}
+          {state.goodsStatus && (
+            <GoodsDetail id={state.selectGoodsId} groupPrice={state.currentPrice} />
+          )}
         </OPopup>
       </>
     )

BIN
src/student/payment-result/images/icon_close.png


BIN
src/student/payment-result/images/icon_refunded.png


BIN
src/student/payment-result/images/icon_refunding.png


BIN
src/student/payment-result/images/icon_success.png


BIN
src/student/payment-result/images/icon_tradeing.png


+ 19 - 14
src/student/payment-result/index.module.less

@@ -1,43 +1,48 @@
 .paymentTitle {
-  min-height: 136px;
-  background: linear-gradient(180deg, #ffe4d4 0%, #ffffff 100%);
+  min-height: 177px;
+  background: linear-gradient(180deg, #f67146 0%, #ff8057 100%);
+  border-radius: 0px 0px 8px 8px;
 
   .orderType {
     padding-top: 35px;
     display: flex;
     align-items: center;
     justify-content: center;
+    color: #fff;
     .img {
-      width: 36px;
-      height: 36px;
-      margin-right: 10px;
+      width: 52px;
+      height: 52px;
+      margin-right: 14px;
     }
 
     span {
       font-size: 22px;
       font-weight: 500;
-      color: #1a1a1a;
       line-height: 30px;
     }
   }
 
   .orderPrice {
-    padding-bottom: 22px;
-    padding-top: 15px;
-    color: #333333;
+    padding-top: 2px;
     font-size: 22px;
     text-align: center;
-
-    span {
-      font-size: 16px;
-      line-height: 22px;
-    }
+    font-size: 14px;
   }
 }
 
+.mTop {
+  margin-top: -52px !important;
+}
+
 .cellGroup {
   margin: 10px 13px;
 
+  .brandName {
+    line-height: 18px;
+    font-size: 12px;
+    padding: 0 6px;
+    border-radius: 4px;
+  }
   :global {
     .van-cell {
       padding: 16px 17px;

+ 39 - 10
src/student/payment-result/index.tsx

@@ -2,7 +2,6 @@ import OHeader from '@/components/o-header'
 import { defineComponent, onMounted, reactive } from 'vue'
 import { Button, Cell, CellGroup, Image, showConfirmDialog, Tag } from 'vant'
 import styles from './index.module.less'
-import iconRefunded from './images/icon_refunded.png'
 import iconRefunding from './images/icon_refunding.png'
 import icon_success from './images/icon_success.png'
 import iconClose from './images/icon_close.png'
@@ -30,6 +29,7 @@ export default defineComponent({
         )
 
         state.orders = data || {}
+        // state.orders.status = 'REFUNDED'
         const tempGoods = data.goodsInfos || []
         tempGoods.forEach((item: any) => {
           const img = item.goodsUrl ? item.goodsUrl.split(',')[0] : ''
@@ -63,11 +63,25 @@ export default defineComponent({
         FAIL: iconClose,
         CLOSED: iconClose,
         REFUNDING: iconRefunding,
-        REFUNDED: iconRefunded
+        REFUNDED: icon_success
       }
       return template[type] || icon_success
     }
 
+    const formatOrderStatus = (status: string) => {
+      const temp = {
+        WAIT_PAY: '支付中',
+        PAYING: '支付中',
+        PAID: '支付成功',
+        TIMEOUT: '订单超时',
+        FAIL: '支付失败',
+        CLOSED: '订单关闭',
+        REFUNDING: '退款中',
+        REFUNDED: '已退款'
+      }
+      return temp[status]
+    }
+
     onMounted(() => {
       getDetails()
       useEventListener(document, 'scroll', () => {
@@ -88,17 +102,28 @@ export default defineComponent({
             <>
               <div class={styles.orderType}>
                 <Image class={styles.img} src={formatImg(state.orders.status)} />
-                <span>{orderStatus[state.orders.status]}</span>
-              </div>
-              <div class={styles.orderPrice}>
-                <span>¥</span>
-                {moneyFormat(state.orders.paymentCashAmount)}
+                <div class={styles.orderInfo}>
+                  <span>{formatOrderStatus(state.orders.status)}</span>
+                  {state.orders.status === 'PAID' || state.orders.status === 'REFUNDING' ? (
+                    <div class={styles.orderPrice}>
+                      实付金额:¥{moneyFormat(state.orders.paymentCashAmount)}
+                    </div>
+                  ) : (
+                    ''
+                  )}
+
+                  {state.orders.status === 'REFUNDED' && (
+                    <div class={styles.orderPrice}>
+                      退款金额:¥{moneyFormat(state.orders.paymentCashAmount)}
+                    </div>
+                  )}
+                </div>
               </div>
             </>
           )}
         </div>
 
-        <CellGroup inset class={styles.cellGroup}>
+        <CellGroup inset class={[styles.cellGroup, styles.mTop]}>
           <Cell>
             {{ title: () => '付款时间', value: () => <span>{state.orders.payTime || '--'}</span> }}
           </Cell>
@@ -112,13 +137,17 @@ export default defineComponent({
             <i></i> 购买详情
           </div>
           {state.goodsInfos.map((goods: any) => (
-            <Cell center>
+            <Cell>
               {{
                 icon: () => <Image class={styles.buyImg} src={goods.goodsUrl} />,
                 title: () => (
                   <div class={styles.buyContent}>
                     <p class={styles.goodsTitle}>{goods.goodsName}</p>
-                    <Tag color="#EEEEEE" textColor="#666666">
+                    <Tag
+                      color="linear-gradient(135deg, #FF8C4A 0%, #FF531C 100%)"
+                      textColor="#fff"
+                      class={styles.brandName}
+                    >
                       {goods.brandName}
                     </Tag>
                   </div>

+ 1 - 1
src/views/coursewarePlay/index.module.less

@@ -100,7 +100,7 @@
 .fullBtn {
   width: 38px;
   height: 55px;
-  background: rgba(51, 51, 51, 0.15);
+  background: rgba(51, 51, 51, 0.4);
   border-radius: 8px;
   display: flex;
   flex-direction: column;

+ 1 - 1
src/views/coursewarePlay/index.tsx

@@ -117,7 +117,7 @@ export default defineComponent({
           `${state.platformApi}/courseSchedule/detail/${route.query.courseId}`
         )
         if (res?.data) {
-          data.isCourse = res.data.status === 'COMPLETE' ? false : true
+          data.isCourse = res.data.status === 'ING' ? true : false
         }
       } catch (e) {
         console.log(e)

+ 26 - 9
src/views/exercise-after-class/index.module.less

@@ -18,7 +18,7 @@
     left: 0;
     right: 0;
     z-index: 1;
-    padding: 10px;
+    padding: 10px 24px;
     display: flex;
     align-items: center;
     color: #fff;
@@ -68,6 +68,20 @@
       object-fit: contain;
     }
   }
+  .videoModel{
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    & > img{
+      width: 50px;
+      height: 50px;
+    }
+  }
   .rightFixedBtns {
     position: fixed;
     top: 50%;
@@ -113,28 +127,31 @@
     bottom: 0;
     z-index: 10;
     background: linear-gradient(0deg, rgba(0, 0, 0, 0.5), transparent);
+    padding: 0 30px;
     .time {
       display: flex;
       justify-content: space-between;
       color: #fff;
       font-size: 10px;
-      padding: 4px 10px;
+      padding: 4px 0;
     }
     .slider {
-      padding: 8px 10px;
+      padding: 10px 0;
     }
     .actions {
       display: flex;
       justify-content: space-between;
       color: #fff;
       font-size: 12px;
-      padding: 8px 10px;
       align-items: center;
-      :global {
-        .van-icon {
-          font-size: 20px;
-          margin-right: 14px;
-        }
+      .actionBtn{
+        display: flex;
+      }
+      .actionBtn > img {
+        width: 26px;
+        height: 26px;
+        display: block;
+        padding: 8px 8px 14px 8px;
       }
     }
   }

+ 101 - 167
src/views/exercise-after-class/index.tsx

@@ -1,9 +1,6 @@
 import {
-  closeToast,
   Icon,
-  Popup,
   showConfirmDialog,
-  showToast,
   Slider,
   Swipe,
   SwipeItem
@@ -12,12 +9,10 @@ import {
   defineComponent,
   onMounted,
   reactive,
-  nextTick,
   onUnmounted,
   ref,
   watch,
   Transition,
-  computed
 } from 'vue'
 import styles from './index.module.less'
 import 'plyr/dist/plyr.css'
@@ -72,10 +67,13 @@ export default defineComponent({
     })
 
     const route = useRoute()
-    watch(() => route.query, () => {
-      getDetail()
-      trainingRecord()
-    })
+    watch(
+      () => route.query,
+      () => {
+        getDetail()
+        trainingRecord()
+      }
+    )
     const router = useRouter()
     const query = route.query
     const browserInfo = browser()
@@ -95,21 +93,8 @@ export default defineComponent({
       timer: null as any,
       item: null as any
     })
-    // 获取缓存路径
-    const getCacheFilePath = async (material: any) => {
-      const res = await promisefiyPostMessage({
-        api: 'getCourseFilePath',
-        content: {
-          url: material.content,
-          localPath: '',
-          materialId: material.id,
-          updateTime: material.updateTime,
-          type: material.type
-        }
-      })
-      return res
-    }
     const getDetail = async () => {
+      data.itemList = []
       let details = []
       try {
         const res: any = await request.get(
@@ -129,16 +114,6 @@ export default defineComponent({
         try {
           videoData.training = JSON.parse(videoData?.lessonTrainingTemp?.trainingConfigJson)
         } catch (error) {}
-        //请求本地缓存
-        if (browserInfo.isApp && videoData.updateTime && ['VIDEO'].includes(videoData.type)) {
-          console.log('开始检查本地缓存')
-          const localData = await getCacheFilePath(videoData)
-          console.log("🚀 ~ 本地缓存数据", localData)
-          if (localData?.content?.localPath) {
-            videoData.url = videoData.content
-            videoData.content = localData.content.localPath
-          }
-        }
         data.itemList.push({
           ...videoData,
           id: videoData.materialId,
@@ -148,7 +123,8 @@ export default defineComponent({
           loop: false,
           videoEle: null,
           timer: null,
-          playModel: true
+          muted: true, // 静音
+          autoplay: true, //自动播放
         })
         popupData.itemActive = videoData.id
         popupData.tabName = videoData.materialName
@@ -199,27 +175,10 @@ export default defineComponent({
       itemName: ''
     })
 
-    // 双击
-    const handleDbClick = (item: any) => {
-      if (item && item.type === 'VIDEO') {
-        const videoEle: HTMLVideoElement = document.querySelector(`[data-vid='${item.id}']`)!
-        if (videoEle) {
-          if (videoEle.paused) {
-            closeToast()
-            videoEle.play()
-          } else {
-            showToast('已暂停')
-            videoEle.pause()
-          }
-        }
-        item.timer = setTimeout(() => {
-          activeData.model = false
-        }, 3000)
-      }
-    }
-
     // 达到指标,记录
     const addTrainingRecord = async (m: any) => {
+      if (data.recordLoading) return
+      console.log('记录观看次数')
       data.recordLoading = true
       const query = route.query
       const body = {
@@ -243,9 +202,7 @@ export default defineComponent({
         )
         trainingRecord()
       } catch (error) {}
-      setTimeout(() => {
-        data.recordLoading = false
-      }, 2000)
+      data.recordLoading = false
     }
     // 停止所有的播放
     const handleStopVideo = () => {
@@ -271,45 +228,50 @@ export default defineComponent({
           confirmButtonColor: 'var(--van-primary)',
           confirmButtonText: isLastIndex ? '完成' : '下一题',
           cancelButtonText: '继续'
-        }).then(() => {
-          if (!isLastIndex) {
-            const nextItem = data.details[itemIndex + 1]
-            if (nextItem?.type === materialType.视频) {
-              console.log('下一题视频',data.details[itemIndex].materialId, nextItem.materialId)
-              router.replace({
-                path: '/exerciseAfterClass',
-                query: {
-                  ...query,
+        })
+          .then(() => {
+            if (!isLastIndex) {
+              const nextItem = data.details[itemIndex + 1]
+              if (nextItem?.type === materialType.视频) {
+                // console.log('下一题视频', data.details[itemIndex].materialId, nextItem.materialId)
+                router.replace({
+                  path: '/exerciseAfterClass',
+                  query: {
+                    ...query,
+                    materialId: nextItem.materialId
+                  }
+                })
+              }
+              if (nextItem?.type === materialType.曲目) {
+                handleInit(1)
+                goback()
+                const parmas = qs.stringify({
+                  id: nextItem.content,
+                  courseScheduleId: query.courseScheduleId,
+                  lessonTrainingId: query.lessonTrainingId,
                   materialId: nextItem.materialId
-                }
-              })
+                })
+                let src = `${location.origin}/orchestra-music-score/?` + parmas
+                // console.log("🚀 ~ src", src)
+                postMessage({
+                  api: 'openAccompanyWebView',
+                  content: {
+                    url: src,
+                    orientation: 0,
+                    isHideTitle: true,
+                    statusBarTextColor: false,
+                    isOpenLight: true
+                  }
+                })
+              }
             }
-            if (nextItem?.type === materialType.曲目) {
-              handleInit(1)
-              goback()
-              const parmas = qs.stringify({
-                id: nextItem.content,
-                courseScheduleId: query.courseScheduleId,
-                lessonTrainingId: query.lessonTrainingId,
-                materialId: nextItem.materialId
-              })
-              let src = `${location.origin}/orchestra-music-score/?` + parmas
-              // console.log("🚀 ~ src", src)
-              postMessage({
-                api: 'openAccompanyWebView',
-                content: {
-                  url: src,
-                  orientation: 0,
-                  isHideTitle: true,
-                  statusBarTextColor: false,
-                  isOpenLight: true
-                }
-              })
-            }
-          }
-        })
+          })
+          .catch(() => {
+            data.details[itemIndex].currentTime = 0
+          })
       }
     }
+
     return () => (
       <div class={styles.coursewarePlay}>
         <Swipe
@@ -328,16 +290,8 @@ export default defineComponent({
                   <div
                     class={styles.itemDiv}
                     onClick={() => {
-                      clearTimeout(activeData.timer)
                       clearTimeout(m.timer)
-                      if (Date.now() - activeData.nowTime < 300) {
-                        handleDbClick(m)
-                        return
-                      }
-                      activeData.nowTime = Date.now()
-                      activeData.timer = setTimeout(() => {
-                        activeData.model = !activeData.model
-                      }, 300)
+                      activeData.model = !activeData.model
                     }}
                   >
                     <video
@@ -348,101 +302,81 @@ export default defineComponent({
                       data-vid={m.id}
                       src={m.content}
                       loop={m.loop}
-                      onLoadedmetadata={(e: Event) => {
+                      autoplay={m.autoplay}
+                      muted={m.muted}
+                      onLoadedmetadata={async (e: Event) => {
                         const videoEle = e.target as unknown as HTMLVideoElement
-                        m.currentTime = videoEle.currentTime
                         m.duration = videoEle.duration
                         m.videoEle = videoEle
                       }}
                       onTimeupdate={(e: Event) => {
                         const videoEle = e.target as unknown as HTMLVideoElement
                         m.currentTime = videoEle.currentTime
-                        if (m.duration - m.currentTime < 1) {
-                          if (data.recordLoading) return
-                          console.log('完成观看次数')
-                          addTrainingRecord(m)
-                        }
                       }}
                       onPlay={() => {
                         // 播放
                         m.paused = false
+                        if (m.muted){
+                          m.muted = false
+                          m.videoEle.pause()
+                        }
                       }}
                       onPause={() => {
                         //暂停
-                        clearTimeout(m.timer)
                         m.paused = true
                       }}
+                      onEnded={() => addTrainingRecord(m)}
                     >
                       <source src={m.content} type="video/mp4" />
                     </video>
-                    <Transition name="bottom">
-                      {activeData.model && (
-                        <div class={styles.bottomFixedContainer}>
-                          <div class={styles.time}>
-                            <span>{getSecondRPM(m.currentTime)}</span>
-                            <span>{getSecondRPM(m.duration)}</span>
-                          </div>
-                          <div class={styles.slider}>
+                  </div>
+                  <Transition name="bottom">
+                    {activeData.model && (
+                      <div class={styles.bottomFixedContainer}>
+                        <div class={styles.time}>
+                          <span>{getSecondRPM(m.currentTime)}</span>
+                          <span>{getSecondRPM(m.duration)}</span>
+                        </div>
+                        <div class={styles.slider}>
+                          {m.duration && (
                             <Slider
                               buttonSize={16}
-                              step={0.01}
                               modelValue={m.currentTime}
                               min={0}
                               max={m.duration}
                             />
-                          </div>
+                          )}
+                        </div>
 
-                          <div class={styles.actions}>
-                            <div>
-                              {m.paused ? (
-                                <Icon
-                                  name={iconplay}
-                                  onClick={(e: Event) => {
-                                    e.stopPropagation()
-                                    clearTimeout(m.timer)
-                                    closeToast()
-                                    m.videoEle?.play()
-                                    m.paused = false
-                                    m.timer = setTimeout(() => {
-                                      activeData.model = false
-                                    }, 3000)
-                                  }}
-                                />
-                              ) : (
-                                <Icon
-                                  name={iconpause}
-                                  onClick={(e: Event) => {
-                                    e.stopPropagation()
-                                    console.log('点击暂停')
-                                    m.videoEle?.pause()
-                                    m.paused = true
-                                  }}
-                                />
-                              )}
-                              {m.loop ? (
-                                <Icon
-                                  name={iconLoopActive}
-                                  onClick={(e: Event) => {
-                                    e.stopPropagation()
-                                    m.loop = false
-                                  }}
-                                />
-                              ) : (
-                                <Icon
-                                  name={iconLoop}
-                                  onClick={(e: Event) => {
-                                    e.stopPropagation()
-                                    m.loop = true
-                                  }}
-                                />
-                              )}
-                            </div>
-                            <div>{m.name}</div>
+                        <div class={styles.actions}>
+                          <div class={styles.actionBtn}>
+                            {m.paused ? (
+                              <img
+                                src={iconplay}
+                                onClick={(e: Event) => {
+                                  clearTimeout(m.timer)
+                                  m.videoEle?.play()
+                                  m.paused = false
+                                  m.timer = setTimeout(() => {
+                                    activeData.model = false
+                                  }, 4000)
+                                }}
+                              />
+                            ) : (
+                              <img
+                                src={iconpause}
+                                onClick={(e: Event) => {
+                                  clearTimeout(m.timer)
+                                  m.videoEle?.pause()
+                                  m.paused = true
+                                }}
+                              />
+                            )}
                           </div>
                         </div>
-                      )}
-                    </Transition>
-                  </div>
+                      </div>
+                    )}
+                  </Transition>
                 </>
               </SwipeItem>
             )