소스 검색

Merge branch 'master' into jenkins

mo 2 년 전
부모
커밋
28dae6cba0

+ 254 - 0
src/school/ranking-list/components/day-bang.tsx

@@ -0,0 +1,254 @@
+import OSearch from '@/components/o-search'
+import OEmpty from '@/components/o-empty'
+import dayjs from 'dayjs'
+import {
+  Icon,
+  Popover,
+  DatePicker,
+  DatePickerColumnType,
+  Popup,
+  List,
+  PullRefresh,
+  ActionSheet,
+  showToast
+} from 'vant'
+import { defineComponent, reactive, ref, onMounted } from 'vue'
+import { useRouter } from 'vue-router'
+import styles from './timer-bang.module.less'
+import request from '@/helpers/request'
+import { state as globalState } from '@/state'
+import RankItem from '../modals/rank-item'
+export default defineComponent({
+  name: 'day-bang',
+  setup(props, { slots, attrs, emit }) {
+    const router = useRouter()
+    const state = reactive({
+      showPopoverTime: false,
+      showPopoverOrchestra: false,
+      showPopoverSubject: false,
+      actions: [],
+      subjects: [] as any,
+      currentDate: [dayjs().format('YYYY'), dayjs().format('MM')]
+    })
+    const forms = reactive({
+      time: state.currentDate[0] + '' + state.currentDate[1],
+      timeName: state.currentDate[0] + '年' + state.currentDate[1] + '月',
+      orchestraId: '',
+      orchestraName: '全部乐团',
+      subjectId: '',
+      subjectName: '全部声部',
+      page: 1,
+      rows: 50,
+      sortType: 'PRACTICE_DAY'
+    })
+    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 {
+        if (refreshing.value) {
+          forms.page = 1
+          list.value = []
+          refreshing.value = false
+        }
+
+        const res = await request.post('/api-school/student/page', {
+          data: { ...forms }
+        })
+
+        if (list.value.length > 0 && res.data.pages === 1) {
+          return
+        }
+
+        forms.page = res.data.current + 1
+        // list.value = list.value.concat(res.data.rows || [])
+        list.value = res.data.rows
+        showContact.value = list.value.length > 0
+        console.log(showContact.value, ' showContact.value ')
+        loading.value = false
+        finished.value = true
+        // 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 checkTimer = (val: any) => {
+      forms.time = val.selectedValues[0] + val.selectedValues[1]
+      forms.timeName = val.selectedValues[0] + '年' + val.selectedValues[1] + '月'
+      state.showPopoverTime = false
+      emit('setTime', forms.timeName)
+      refreshing.value = true
+      getList()
+    }
+    const checkOrchestra = (val: any) => {
+      forms.orchestraId = val.value
+      forms.orchestraName = val.name
+      state.showPopoverOrchestra = false
+      refreshing.value = true
+      getList()
+    }
+
+    const checkSubject = (val: any) => {
+      forms.subjectId = val.value
+      forms.subjectName = val.name
+      console.log(val, forms)
+      refreshing.value = true
+      getList()
+    }
+    const getOrchestraList = async () => {
+      const schoolId = globalState.user.data.schoolInfos
+        .map((item) => {
+          return item.id
+        })
+        .join(',')
+      try {
+        const res = await request.post('/api-school/orchestra/page', {
+          data: { page: 1, rows: 9999, schoolId }
+        })
+        state.actions = res.data.rows.map((item) => {
+          return {
+            name: item.name,
+            value: item.id as string
+          }
+        })
+        state.actions.unshift({ name: '全部乐团', value: '' })
+      } catch (e: any) {
+        const message = e.message
+        showToast(message)
+      }
+    }
+
+    const getSubjects = async () => {
+      try {
+        const res = await request.post('/api-school/subject/page', {
+          data: { page: 1, rows: 9999 }
+        })
+        state.subjects = res.data.rows.map((item) => {
+          return {
+            name: item.name,
+            value: item.id as string
+          }
+        })
+        state.subjects.unshift({ name: '全部声部', value: '' })
+      } catch (e: any) {
+        const message = e.message
+        showToast(message)
+      }
+    }
+    onMounted(() => {
+      getSubjects()
+      getOrchestraList()
+      getList()
+      emit('setTime', forms.timeName)
+    })
+    const onRefresh = () => {
+      finished.value = false
+      // 重新加载数据
+      // 将 loading 设置为 true,表示处于加载状态
+      loading.value = true
+      getList()
+    }
+    return () => (
+      <>
+        {/* <OSticky position="top" background="#FFF"> */}
+
+        <div class={styles.chioseWrap}>
+          <div style={{ padding: '0 13px', background: '#FFF' }}>
+            <div
+              class={styles.searchBand}
+              onClick={() => {
+                state.showPopoverTime = true
+              }}
+            >
+              {forms.timeName}
+              <Icon name={state.showPopoverTime ? 'arrow-up' : 'arrow-down'} />
+            </div>
+          </div>
+
+          <div style={{ padding: '0 13px', background: '#FFF' }}>
+            <div
+              class={styles.searchBand}
+              onClick={() => {
+                state.showPopoverOrchestra = true
+              }}
+            >
+              {forms.orchestraName}
+              <Icon name={state.showPopoverOrchestra ? 'arrow-up' : 'arrow-down'} />
+            </div>
+          </div>
+          <div style={{ padding: '0 13px', background: '#FFF' }}>
+            <div
+              class={styles.searchBand}
+              onClick={() => {
+                state.showPopoverSubject = true
+              }}
+            >
+              {forms.subjectName}
+              <Icon name={state.showPopoverSubject ? 'arrow-up' : 'arrow-down'} />
+            </div>
+          </div>
+        </div>
+        {/* </OSticky> */}
+
+        {showContact.value ? (
+          <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, index: number) => (
+                <RankItem item={item} type="time" index={index + 1}></RankItem>
+              ))}
+            </List>
+          </PullRefresh>
+        ) : (
+          <OEmpty />
+        )}
+
+        <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>
+
+        <ActionSheet
+          v-model:show={state.showPopoverOrchestra}
+          title="选择乐团"
+          actions={state.actions}
+          onSelect={checkOrchestra}
+        ></ActionSheet>
+
+        <ActionSheet
+          style={{ height: '40%' }}
+          close-on-click-action
+          v-model:show={state.showPopoverSubject}
+          title="选择声部"
+          actions={state.subjects}
+          onSelect={checkSubject}
+        ></ActionSheet>
+      </>
+    )
+  }
+})

+ 23 - 15
src/school/ranking-list/components/timer-bang.tsx

@@ -1,5 +1,5 @@
 import OSearch from '@/components/o-search'
-import oEmpty from '@/components/o-empty'
+import OEmpty from '@/components/o-empty'
 import dayjs from 'dayjs'
 import {
   Icon,
@@ -17,10 +17,10 @@ import { useRouter } from 'vue-router'
 import styles from './timer-bang.module.less'
 import request from '@/helpers/request'
 import { state as globalState } from '@/state'
-
+import RankItem from '../modals/rank-item'
 export default defineComponent({
-  name: 'attend-student',
-  setup() {
+  name: 'timer-bang',
+  setup(props, { slots, attrs, emit }) {
     const router = useRouter()
     const state = reactive({
       showPopoverTime: false,
@@ -88,7 +88,9 @@ export default defineComponent({
     const checkTimer = (val: any) => {
       forms.time = val.selectedValues[0] + val.selectedValues[1]
       forms.timeName = val.selectedValues[0] + '年' + val.selectedValues[1] + '月'
+      emit('setTime', forms.timeName)
       state.showPopoverTime = false
+      refreshing.value = true
       getList()
     }
     const checkOrchestra = (val: any) => {
@@ -150,6 +152,7 @@ export default defineComponent({
       getSubjects()
       getOrchestraList()
       getList()
+      emit('setTime', forms.timeName)
     })
     const onRefresh = () => {
       finished.value = false
@@ -200,17 +203,22 @@ export default defineComponent({
         </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) => 111)}
-          </List>
-        </PullRefresh>
+        {showContact.value ? (
+          <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, index: number) => (
+                <RankItem item={item} type="day" index={index + 1}></RankItem>
+              ))}
+            </List>
+          </PullRefresh>
+        ) : (
+          <OEmpty />
+        )}
 
         <Popup v-model:show={state.showPopoverTime} position="bottom" style="{ height: '30%' }">
           <DatePicker

BIN
src/school/ranking-list/images/first.png


BIN
src/school/ranking-list/images/second.png


BIN
src/school/ranking-list/images/third.png


+ 7 - 0
src/school/ranking-list/index.module.less

@@ -14,9 +14,16 @@
     letter-spacing: 1px;
   }
 }
+
 .rankTabs {
   position: relative;
   top: -44px;
   height: 45px;
   line-height: 45px;
+  :global {
+    .van-tabs__line {
+      bottom: 20px;
+      width: 20px;
+    }
+  }
 }

+ 8 - 4
src/school/ranking-list/index.tsx

@@ -5,15 +5,19 @@ import { defineComponent, reactive, ref } from 'vue'
 import { useRouter } from 'vue-router'
 // import linkBg from './images/ranking-bg.png'
 import TimerBang from './components/timer-bang'
+import DayBang from './components/day-bang'
 import styles from './index.module.less'
 const activeName = ref('student')
-
+const timers = ref('')
 export default defineComponent({
   name: 'ranking-list',
   setup() {
     const router = useRouter()
     const state = reactive({})
 
+    const setTime = (val: string) => {
+      timers.value = val
+    }
     return () => (
       <>
         <OSticky position="top" background="#F8F8F8">
@@ -24,7 +28,7 @@ export default defineComponent({
               background={'transparent'}
               border={false}
             ></OHeader>
-            <span class={styles.topTime}>2022年10月</span>
+            <span class={styles.topTime}>{timers.value}</span>
           </div>
           <Tabs
             v-model:active={activeName.value}
@@ -35,10 +39,10 @@ export default defineComponent({
             color={'#fff'}
           >
             <Tab name="student" title="天数榜">
-              <TimerBang></TimerBang>
+              {activeName.value == 'student' ? <TimerBang onSetTime={setTime}></TimerBang> : null}
             </Tab>
             <Tab name="teacher" title="时长榜">
-              天数榜
+              {activeName.value == 'teacher' ? <DayBang onSetTime={setTime}></DayBang> : null}
             </Tab>
           </Tabs>
         </OSticky>

+ 68 - 0
src/school/ranking-list/modals/rank-item.module.less

@@ -0,0 +1,68 @@
+.itemWrap {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  padding: 12px 18px;
+  background-color: #fff;
+  justify-content: space-between;
+  .wrapLeft {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    .numWrap {
+      width: 32px;
+      height: 32px;
+      font-size: 22px;
+      font-family: DINAlternate-Bold, DINAlternate;
+      font-weight: bold;
+      color: #aaaaaa;
+      line-height: 32px;
+      margin-right: 10px;
+      text-align: center;
+      img {
+        width: 100%;
+      }
+    }
+    .headerWrap {
+      width: 48px;
+      height: 48px;
+      overflow: hidden;
+      border-radius: 50%;
+      margin-right: 10px;
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .studentName {
+      font-size: 16px;
+      font-weight: 500;
+      color: #333333;
+      line-height: 22px;
+    }
+    .tag {
+      background: #ffe7da;
+      border-radius: 4px;
+      font-size: 12px;
+      text-align: center;
+      font-weight: 500;
+      color: #f67146;
+      line-height: 17px;
+      padding: 0 8px;
+    }
+  }
+  .wrapRight {
+    p {
+      font-size: 16px;
+      color: #777;
+      line-height: 19px;
+      span {
+        font-size: 16px;
+        font-family: DINAlternate-Bold, DINAlternate;
+        font-weight: bold;
+        color: #333333;
+        line-height: 19px;
+      }
+    }
+  }
+}

+ 21 - 16
src/school/ranking-list/modals/rank-item.tsx

@@ -1,15 +1,11 @@
 import { defineComponent, reactive, ref, watch } from 'vue'
-import styles from './student-item.module.less'
+import styles from './rank-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 { postMessage } from '@/helpers/native-message'
-import { Icon, ActionSheet, showToast } from 'vant'
-import { useRouter } from 'vue-router'
-const myForms = ref({}) as any
+import firstIcon from '../images/first.png'
+import secondIcon from '../images/second.png'
+import thirdIcon from '../images/third.png'
 export default defineComponent({
-  props: ['item', 'type'],
+  props: ['item', 'type', 'index'],
   name: 'rank-item',
   setup(props) {
     return () => (
@@ -18,20 +14,29 @@ export default defineComponent({
           <div class={styles.itemWrap}>
             <div class={styles.wrapLeft}>
               <div class={styles.numWrap}>
-                <img src="" alt="" />
+                {props.index == 1 ? <img src={firstIcon} alt="" /> : null}
+                {props.index == 2 ? <img src={secondIcon} alt="" /> : null}
+                {props.index == 3 ? <img src={thirdIcon} alt="" /> : null}
+                {props.index > 3 ? <p>{props.index}</p> : null}
               </div>
               <div class={styles.headerWrap}>
-                <img src="" alt="" />
+                <img src={props.item.avatar ? props.item.avatar : defaultIcon} alt="" />
               </div>
               <div>
-                <p class={styles.studentName}> </p>
-                <div class={styles.tag}></div>
+                <p class={styles.studentName}>{props.item.nickname}</p>
+                <div class={styles.tag}>{props.item.subjectNames}</div>
               </div>
             </div>
             <div class={styles.wrapRight}>
-              <p>
-                <span></span>
-              </p>
+              {props.type == 'day' ? (
+                <p>
+                  <span>{props.item.practiceDays ? props.item.practiceDays : 0}</span>天
+                </p>
+              ) : (
+                <p>
+                  <span>{props.item.practiceTimes ? props.item.practiceTimes : 0}</span>小时
+                </p>
+              )}
             </div>
           </div>
         </div>