Jelajahi Sumber

到评测详情

1
mo 2 tahun lalu
induk
melakukan
b0c3bd1ff0

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

@@ -74,6 +74,14 @@ export default [
         meta: {
           title: '练习记录'
         }
+      },
+      {
+        path: '/exercis-detail',
+        name: 'exercis-detail',
+        component: () => import('@/school/exercise-record/exercis-detail'),
+        meta: {
+          title: '测评详情'
+        }
       }
     ]
   },

+ 126 - 0
src/school/exercise-record/exercis-detail.module.less

@@ -0,0 +1,126 @@
+@img: '../images';
+
+.topWrap {
+  height: 316px;
+  background: url('@{img}/detail-bg.png') center center/ cover;
+  margin-bottom: -90px;
+  .topInfo {
+    padding: 34px 15px 30px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: space-between;
+    .topInfoLeft {
+      width: 50%;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      .headWrap {
+        border-radius: 50%;
+        overflow: hidden;
+        border: 2px solid #fff;
+        width: 68px;
+        height: 68px;
+        margin-right: 15px;
+        img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+      .infoMsg {
+        p {
+          font-size: 20px;
+          font-weight: 600;
+          color: #000000;
+          line-height: 28px;
+          margin-bottom: 6px;
+        }
+        .tag {
+          padding: 2px 11px;
+          // min-width: 50px;
+          background: #ff8057;
+          border-radius: 12px;
+          height: 24px;
+          font-size: 14px;
+          font-family: PingFangSC-Medium, PingFang SC;
+          font-weight: 500;
+          color: #ffffff;
+          line-height: 20px;
+          text-align: center;
+        }
+      }
+    }
+    .topInfoRight {
+      width: 50%;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      justify-content: flex-end;
+      .infoDay {
+        margin-right: 30px;
+      }
+      .infoDayMain {
+        font-size: 24px;
+        font-weight: bold;
+        color: #333333;
+        line-height: 28px;
+        margin-bottom: 7px;
+        span {
+          font-size: 12px;
+          font-weight: 400;
+          color: #333333;
+          line-height: 17px;
+        }
+      }
+      .infoDaysub {
+        font-size: 12px;
+        font-weight: 400;
+        color: #333333;
+        line-height: 17px;
+      }
+    }
+  }
+  .chioseWrap {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    // justify-content: space-around;
+    background-color: transparent;
+  }
+}
+
+.DialogTitle {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  padding: 20px 25px;
+  span {
+    width: 4px;
+    height: 14px;
+    background: #ff8057;
+    border-radius: 2px;
+    margin-right: 6px;
+  }
+  p {
+    height: 25px;
+    font-size: 18px;
+    font-weight: 500;
+    color: #333333;
+    line-height: 25px;
+  }
+}
+.DialogConent {
+  padding: 0 25px 20px;
+  p {
+    font-size: 16px;
+    line-height: 22px;
+    color: #333;
+  }
+}
+:global {
+  .exercisDetailDialog {
+    .van-dialog__header {
+      padding-top: 0px !important;
+    }
+  }
+}

+ 228 - 0
src/school/exercise-record/exercis-detail.tsx

@@ -0,0 +1,228 @@
+import OHeader from '@/components/o-header'
+import OSticky from '@/components/o-sticky'
+import dayjs from 'dayjs'
+import {
+  Icon,
+  Popover,
+  DatePicker,
+  DatePickerColumnType,
+  Popup,
+  List,
+  PullRefresh,
+  showToast,
+  Dialog
+} from 'vant'
+import DetailItem from './modals/detail-item'
+import { defineComponent, reactive, ref } from 'vue'
+import { useRouter } from 'vue-router'
+import styles from './exercis-detail.module.less'
+import request from '@/helpers/request'
+import questIcon from '../images/quest-icon.png'
+import defaultIcon from '@/school/images/default-icon.jpg'
+export default defineComponent({
+  name: 'exercis-detail',
+  setup() {
+    const router = useRouter()
+    const state = reactive({
+      showPopoverTime: false,
+      showPopoverOrchestra: false,
+      currentDate: [dayjs().format('YYYY'), dayjs().format('MM')],
+      actions: [
+        { text: '全部乐团', color: 'var(--van-primary-color)' },
+        { text: '交付团' },
+        { text: '晋升团' }
+      ]
+    })
+    const forms = reactive({
+      practiceMonth: state.currentDate[0] + '' + state.currentDate[1],
+      practiceMonthName: state.currentDate[0] + '年' + state.currentDate[1] + '月',
+      orchestraId: '',
+      orchestraName: '',
+      page: 1,
+      rows: 20
+    })
+    const showTip = ref(false)
+    const minDate = ref(new Date(dayjs().subtract(5, 'year').format('YYYY-MM-DD')))
+    const maxDate = ref(new Date(dayjs().add(5, 'year').format('YYYY-MM-DD')))
+    const columnsType = ref<DatePickerColumnType[]>(['year', 'month'])
+    const refreshing = ref(false)
+    const loading = ref(false)
+    const finished = ref(false)
+    const showContact = ref(false)
+    const list = ref([])
+    const getList = async () => {
+      loading.value = true
+      try {
+        const res = await request.post('/api-school/student/page', {
+          data: { ...forms }
+        })
+        if (refreshing.value) {
+          // list.value = []
+          refreshing.value = false
+        }
+        if (list.value.length > 0 && res.data.pageNo === 1) {
+          return
+        }
+
+        showContact.value = list.value.length > 0
+        forms.page = res.data.current + 1
+        list.value = list.value.concat(res.data.rows || [])
+        loading.value = false
+
+        finished.value = res.data.current >= res.data.pages
+      } catch (e: any) {
+        // console.log(e, 'e')
+        const message = e.message
+        showToast(message)
+        showContact.value = false
+        finished.value = true
+      }
+    }
+    const onBack = () => {
+      console.log('返回')
+    }
+
+    const checkTimer = (val: any) => {
+      forms.practiceMonth = val.selectedValues[0] + val.selectedValues[1]
+      forms.practiceMonthName = val.selectedValues[0] + '年' + val.selectedValues[1] + '月'
+      state.showPopoverTime = false
+      getList()
+    }
+
+    const onRefresh = () => {
+      finished.value = false
+      // 重新加载数据
+      // 将 loading 设置为 true,表示处于加载状态
+      loading.value = true
+      getList()
+    }
+    return () => (
+      <>
+        <OSticky position="top" background="#F8F8F8">
+          <div class={styles.topWrap}>
+            <OHeader isBack={true} onHeaderBack={onBack} border={false} background={'transparent'}>
+              {{
+                right: () => (
+                  <Icon
+                    name={questIcon}
+                    size={22}
+                    color="#333"
+                    onClick={() => {
+                      showTip.value = true
+                    }}
+                  />
+                )
+              }}
+            </OHeader>
+            <div class={styles.topInfo}>
+              <div class={styles.topInfoLeft}>
+                <div class={styles.headWrap}>
+                  <img src={defaultIcon} alt="" />
+                </div>
+                <div class={styles.infoMsg}>
+                  <p>邓同学</p>
+                  <div class={styles.tag}>长笛</div>
+                </div>
+              </div>
+              <div class={styles.topInfoRight}>
+                <div class={styles.infoDay}>
+                  <p class={styles.infoDayMain}>
+                    10 <span>天</span>
+                  </p>
+                  <p class={styles.infoDaysub}>练习天数</p>
+                </div>
+                <div class={styles.infoTime}>
+                  <p class={styles.infoDayMain}>
+                    260 <span>分钟</span>
+                  </p>
+                  <p class={styles.infoDaysub}>练习天数</p>
+                </div>
+              </div>
+            </div>
+            <div class={styles.chioseWrap}>
+              <div style={{ padding: '12px 13px', background: 'transparent' }}>
+                <div
+                  class={styles.searchBand}
+                  onClick={() => {
+                    state.showPopoverTime = true
+                  }}
+                >
+                  {forms.practiceMonthName}
+                  <Icon name={state.showPopoverTime ? 'arrow-up' : 'arrow-down'} />
+                </div>
+              </div>
+
+              <div style={{ padding: '12px 13px', background: 'transparent' }}>
+                <Popover
+                  v-model:show={state.showPopoverOrchestra}
+                  actions={state.actions}
+                  showArrow={false}
+                  placement="bottom-start"
+                  offset={[0, 12]}
+                >
+                  {{
+                    reference: () => (
+                      <div class={styles.searchBand}>
+                        全部乐团
+                        <Icon name={state.showPopoverOrchestra ? 'arrow-up' : 'arrow-down'} />
+                      </div>
+                    )
+                  }}
+                </Popover>
+              </div>
+            </div>
+          </div>
+        </OSticky>
+        <PullRefresh v-model={refreshing.value} onRefresh={onRefresh}>
+          <List
+            v-model:loading={loading.value}
+            finished={finished.value}
+            finished-text="没有更多了"
+            onLoad={getList}
+          >
+            {list.value.map((item: any) => (
+              <DetailItem item={item} />
+            ))}
+          </List>
+        </PullRefresh>
+
+        <Popup v-model:show={state.showPopoverTime} position="bottom" style="{ height: '30%' }">
+          <DatePicker
+            onCancel={() => {
+              state.showPopoverTime = false
+            }}
+            onConfirm={checkTimer}
+            v-model={state.currentDate}
+            title="选择年月"
+            minDate={minDate.value}
+            maxDate={maxDate.value}
+            columnsType={columnsType.value}
+          />
+        </Popup>
+        <Dialog
+          class="exercisDetailDialog"
+          v-model:show={showTip.value}
+          title="提示框"
+          confirmButtonText="我知道了"
+          vSlots={{
+            title: () => (
+              <div class={styles.DialogTitle}>
+                <span></span>
+                <p>什么是练习数据</p>
+              </div>
+            ),
+            default: () => (
+              <div class={styles.DialogConent}>
+                <p>
+                  练习数据是学生通过云教练自主练习的数据统计,可根据时间段查询学生的练习天数和练习时长{' '}
+                </p>
+                <p>练习天数:当天又曲目播放或测评记录即算练习</p>
+                <p>练习时长:曲目播放和曲目测评的时长总和</p>
+              </div>
+            )
+          }}
+        ></Dialog>
+      </>
+    )
+  }
+})

+ 30 - 14
src/school/exercise-record/index.tsx

@@ -12,12 +12,14 @@ import {
   Popup,
   List,
   PullRefresh,
-  ActionSheet
+  ActionSheet,
+  showToast
 } from 'vant'
 import StudentItem from './modals/student-item'
 import { defineComponent, reactive, ref } from 'vue'
 import { useRouter } from 'vue-router'
 import styles from './index.module.less'
+import request from '@/helpers/request'
 
 export default defineComponent({
   name: 'exercise-record',
@@ -47,7 +49,9 @@ export default defineComponent({
       subjectId: '',
       subjectName: '',
       sortType: '',
-      sortTypeName: ''
+      sortTypeName: '',
+      page: 1,
+      rows: 20
     })
     const minDate = ref(new Date(dayjs().subtract(5, 'year').format('YYYY-MM-DD')))
     const maxDate = ref(new Date(dayjs().add(5, 'year').format('YYYY-MM-DD')))
@@ -66,19 +70,31 @@ export default defineComponent({
         }
       })
     }
-    const getList = () => {
-      console.log('getList')
-      if (refreshing.value) {
-        list.value = []
-        refreshing.value = false
-      }
+    const getList = async () => {
+      loading.value = true
+      try {
+        const res = await request.post('/api-school/student/page', {
+          data: { ...forms }
+        })
+        if (refreshing.value) {
+          list.value = []
+          refreshing.value = false
+        }
+        if (list.value.length > 0 && res.data.pageNo === 1) {
+          return
+        }
 
-      for (let i = 0; i < 10; i++) {
-        // list.value.push(list.value.length + 1)
-      }
-      loading.value = false
+        showContact.value = list.value.length > 0
+        forms.page = res.data.current + 1
+        list.value = list.value.concat(res.data.rows || [])
+        loading.value = false
 
-      if (list.value.length >= 40) {
+        finished.value = res.data.current >= res.data.pages
+      } catch (e: any) {
+        // console.log(e, 'e')
+        const message = e.message
+        showToast(message)
+        showContact.value = false
         finished.value = true
       }
     }
@@ -188,7 +204,7 @@ export default defineComponent({
             finished-text="没有更多了"
             onLoad={getList}
           >
-            {[1, 2, 3, 4, 5, 6].map((item: any) => (
+            {list.value.map((item: any) => (
               <StudentItem item={item} />
             ))}
           </List>

+ 71 - 0
src/school/exercise-record/modals/detail-item.module.less

@@ -0,0 +1,71 @@
+.itemWrap {
+  background: #ffffff;
+  border-radius: 10px;
+  padding: 12px 15px 20px;
+  margin: 0 13px;
+  .itemTop {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    border-bottom: 1px solid #f2f2f2;
+    padding-bottom: 12px;
+    .itemTopLeft {
+      .itemTopMain {
+        height: 22px;
+        font-size: 16px;
+        font-weight: 500;
+        color: #333333;
+        line-height: 22px;
+        margin-bottom: 6px;
+      }
+      .itemTopSub {
+        font-weight: 400;
+        color: #777777;
+        line-height: 17px;
+      }
+    }
+    .itemTopRight {
+      .imgWrap {
+        width: 87px;
+        height: 33px;
+        background: #e9e3ff;
+        border-radius: 19px;
+        img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+    }
+  }
+  .itemBottom {
+    margin-top: 15px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: space-around;
+    text-align: center;
+    .itemBottomDot {
+      width: 25%;
+      .dotMain {
+        font-size: 26px;
+        font-weight: bold;
+        color: #333333;
+        line-height: 30px;
+        margin-bottom: 4px;
+        span {
+          font-size: 12px;
+          font-weight: 400;
+          color: #333333;
+          line-height: 17px;
+        }
+      }
+      .dotSub {
+        font-size: 12px;
+        font-weight: 400;
+        color: #777777;
+        line-height: 17px;
+      }
+    }
+  }
+}

+ 58 - 0
src/school/exercise-record/modals/detail-item.tsx

@@ -0,0 +1,58 @@
+import { defineComponent, reactive, ref } from 'vue'
+import styles from './detail-item.module.less'
+import defaultIcon from '@/school/images/default-icon.jpg'
+import msgIcon from '@/school/images/msg-icon.png'
+import sendmsgIcon from '@/school/images/sendmsg-icon.png'
+import phoneIcon from '@/school/images/phone-icon.png'
+import { Icon, ActionSheet } from 'vant'
+export default defineComponent({
+  props: ['item'],
+  name: 'detail-item',
+  setup(props) {
+    return () => (
+      <>
+        <div>
+          <div class={styles.itemWrap}>
+            <div class={styles.itemTop}>
+              <div class={styles.itemTopLeft}>
+                <p class={styles.itemTopMain}>洋娃娃和小熊跳舞</p>
+                <p class={styles.itemTopSub}>2022-07-07 10:20:36</p>
+              </div>
+              <div class={styles.itemTopRight}>
+                <div class={styles.imgWrap}>
+                  <img src="" alt="" />
+                </div>
+              </div>
+            </div>
+            <div class={styles.itemBottom}>
+              <div class={styles.itemBottomDot}>
+                <p class={styles.dotMain} style={{ color: '#F67146' }}>
+                  38 <span>分</span>{' '}
+                </p>
+                <p class={styles.dotSub}> 综合得分</p>
+              </div>
+              <div class={styles.itemBottomDot}>
+                <p class={styles.dotMain}>
+                  40 <span>分</span>{' '}
+                </p>
+                <p class={styles.dotSub}>音准 </p>
+              </div>
+              <div class={styles.itemBottomDot}>
+                <p class={styles.dotMain}>
+                  40 <span>分</span>{' '}
+                </p>
+                <p class={styles.dotSub}>节奏 </p>
+              </div>
+              <div class={styles.itemBottomDot}>
+                <p class={styles.dotMain}>
+                  40 <span>分</span>{' '}
+                </p>
+                <p class={styles.dotSub}>完成度 </p>
+              </div>
+            </div>
+          </div>
+        </div>
+      </>
+    )
+  }
+})

TEMPAT SAMPAH
src/school/images/detail-bg.png


TEMPAT SAMPAH
src/school/images/quest-icon.png