|
@@ -4,7 +4,15 @@ dayjs.extend(isBetween)
|
|
import { List, Image, Calendar, Cell } from 'vant'
|
|
import { List, Image, Calendar, Cell } from 'vant'
|
|
import OFullRefresh from '@/components/the-full-refresh'
|
|
import OFullRefresh from '@/components/the-full-refresh'
|
|
import DetailItem from './modals/detail-item'
|
|
import DetailItem from './modals/detail-item'
|
|
-import { defineComponent, onMounted, reactive, ref, computed } from 'vue'
|
|
|
|
|
|
+import {
|
|
|
|
+ defineComponent,
|
|
|
|
+ onMounted,
|
|
|
|
+ reactive,
|
|
|
|
+ ref,
|
|
|
|
+ computed,
|
|
|
|
+ markRaw,
|
|
|
|
+ nextTick
|
|
|
|
+} from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import { useRoute } from 'vue-router'
|
|
import styles from './exercis-detail.module.less'
|
|
import styles from './exercis-detail.module.less'
|
|
import request from '@/helpers/request'
|
|
import request from '@/helpers/request'
|
|
@@ -16,6 +24,66 @@ import bgImg from '../images/bg-image.png'
|
|
import iconStudent from '@common/images/icon_student.png'
|
|
import iconStudent from '@common/images/icon_student.png'
|
|
import iconLogo from '../member-center/images/icon-logo-default.png'
|
|
import iconLogo from '../member-center/images/icon-logo-default.png'
|
|
import iconLogoActive from '../member-center/images/icon-logo.png'
|
|
import iconLogoActive from '../member-center/images/icon-logo.png'
|
|
|
|
+import iconSubject from './images/icon-subject.png'
|
|
|
|
+import iconTrainTitle from './images/train-title.png'
|
|
|
|
+
|
|
|
|
+import * as echarts from 'echarts/core'
|
|
|
|
+import {
|
|
|
|
+ BarChart,
|
|
|
|
+ // 系列类型的定义后缀都为 SeriesOption
|
|
|
|
+ BarSeriesOption,
|
|
|
|
+ LineChart,
|
|
|
|
+ LineSeriesOption
|
|
|
|
+} from 'echarts/charts'
|
|
|
|
+import { PieChart } from 'echarts/charts'
|
|
|
|
+import {
|
|
|
|
+ TitleComponent,
|
|
|
|
+ // 组件类型的定义后缀都为 ComponentOption
|
|
|
|
+ TitleComponentOption,
|
|
|
|
+ TooltipComponent,
|
|
|
|
+ TooltipComponentOption,
|
|
|
|
+ GridComponent,
|
|
|
|
+ GridComponentOption,
|
|
|
|
+ // 数据集组件
|
|
|
|
+ DatasetComponent,
|
|
|
|
+ DatasetComponentOption,
|
|
|
|
+ // 内置数据转换器组件 (filter, sort)
|
|
|
|
+ TransformComponent,
|
|
|
|
+ LegendComponent,
|
|
|
|
+ ToolboxComponent,
|
|
|
|
+ DataZoomComponent
|
|
|
|
+} from 'echarts/components'
|
|
|
|
+import { LabelLayout, UniversalTransition } from 'echarts/features'
|
|
|
|
+import { CanvasRenderer } from 'echarts/renderers'
|
|
|
|
+import { lineChartOption } from './echats'
|
|
|
|
+
|
|
|
|
+// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
|
|
|
|
+type ECOption = echarts.ComposeOption<
|
|
|
|
+ | BarSeriesOption
|
|
|
|
+ | LineSeriesOption
|
|
|
|
+ | TitleComponentOption
|
|
|
|
+ | TooltipComponentOption
|
|
|
|
+ | GridComponentOption
|
|
|
|
+ | DatasetComponentOption
|
|
|
|
+>
|
|
|
|
+
|
|
|
|
+// 注册必须的组件
|
|
|
|
+echarts.use([
|
|
|
|
+ TitleComponent,
|
|
|
|
+ TooltipComponent,
|
|
|
|
+ GridComponent,
|
|
|
|
+ DatasetComponent,
|
|
|
|
+ TransformComponent,
|
|
|
|
+ BarChart,
|
|
|
|
+ LabelLayout,
|
|
|
|
+ UniversalTransition,
|
|
|
|
+ CanvasRenderer,
|
|
|
|
+ PieChart,
|
|
|
|
+ ToolboxComponent,
|
|
|
|
+ LegendComponent,
|
|
|
|
+ DataZoomComponent,
|
|
|
|
+ LineChart
|
|
|
|
+])
|
|
|
|
|
|
export default defineComponent({
|
|
export default defineComponent({
|
|
name: 'exercis-detail',
|
|
name: 'exercis-detail',
|
|
@@ -32,8 +100,15 @@ export default defineComponent({
|
|
trainDays: 0,
|
|
trainDays: 0,
|
|
trainNum: 0,
|
|
trainNum: 0,
|
|
trainTime: 0
|
|
trainTime: 0
|
|
- }
|
|
|
|
|
|
+ },
|
|
|
|
+ userTrainChartData: [] as any,
|
|
|
|
+ myChart: null as any
|
|
})
|
|
})
|
|
|
|
+ const qualifiedFlag = ref(true)
|
|
|
|
+ const unqualifiedFlag = ref(true)
|
|
|
|
+
|
|
|
|
+ // const chartRef = ref<HTMLDivElement | null>(null)
|
|
|
|
+ // const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
|
|
|
|
|
|
const userInfo = computed(() => {
|
|
const userInfo = computed(() => {
|
|
const users = baseState.user.data
|
|
const users = baseState.user.data
|
|
@@ -50,7 +125,8 @@ export default defineComponent({
|
|
})
|
|
})
|
|
const forms = reactive({
|
|
const forms = reactive({
|
|
practiceMonth: dayjs().day(1).format('YYYYMMDD'),
|
|
practiceMonth: dayjs().day(1).format('YYYYMMDD'),
|
|
- startTime: '2023-09',
|
|
|
|
|
|
+ // startTime: dayjs().day(1).format('YYYYMMDD'),
|
|
|
|
+ startTime: dayjs().day(1).format('YYYY-MM'),
|
|
endTime: dayjs().day(7).format('YYYY-MM-DD'),
|
|
endTime: dayjs().day(7).format('YYYY-MM-DD'),
|
|
page: 1,
|
|
page: 1,
|
|
rows: 20
|
|
rows: 20
|
|
@@ -85,7 +161,7 @@ export default defineComponent({
|
|
if (list.value.length > 0 && data.detail.pageNo === 1) {
|
|
if (list.value.length > 0 && data.detail.pageNo === 1) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ state.userTrainChartData = data.userTrainChartData || []
|
|
list.value = list.value.concat(data.detail.rows || [])
|
|
list.value = list.value.concat(data.detail.rows || [])
|
|
forms.page = data.detail.pageNo + 1
|
|
forms.page = data.detail.pageNo + 1
|
|
showContact.value = list.value.length > 0
|
|
showContact.value = list.value.length > 0
|
|
@@ -96,21 +172,39 @@ export default defineComponent({
|
|
finished.value = true
|
|
finished.value = true
|
|
}
|
|
}
|
|
state.isClick = false
|
|
state.isClick = false
|
|
- }
|
|
|
|
|
|
|
|
- onMounted(async () => {
|
|
|
|
- await getList()
|
|
|
|
- })
|
|
|
|
|
|
+ if (showContact.value) {
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ if (document.getElementById('exerciseWeek')) {
|
|
|
|
+ state.myChart = markRaw(
|
|
|
|
+ echarts.init(
|
|
|
|
+ document.getElementById('exerciseWeek') as HTMLDivElement
|
|
|
|
+ )
|
|
|
|
+ )
|
|
|
|
|
|
- const checkTimer = (val: any) => {
|
|
|
|
- // forms.practiceMonth = val.selectedValues[0] + val.selectedValues[1]
|
|
|
|
- // state.practiceMonthName =
|
|
|
|
- // val.selectedValues[0] + '年' + val.selectedValues[1] + '月'
|
|
|
|
- state.showPopoverTime = false
|
|
|
|
- refreshing.value = true
|
|
|
|
- getList()
|
|
|
|
- }
|
|
|
|
|
|
+ const cloudTime: any = []
|
|
|
|
+ const cloudNum: any = []
|
|
|
|
+ state.userTrainChartData.forEach((data: any) => {
|
|
|
|
+ const indexData = data.indexMonthData || []
|
|
|
|
+ if (data.dataType === 'CLOUD_STUDY_TRAIN_TIME') {
|
|
|
|
+ indexData.forEach((d: any) => {
|
|
|
|
+ cloudTime.push(d.totalNum)
|
|
|
|
+ })
|
|
|
|
+ } else if (data.dataType === 'CLOUD_STUDY_TRAIN_NUM') {
|
|
|
|
+ indexData.forEach((d: any) => {
|
|
|
|
+ cloudNum.push(d.totalNum)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ lineChartOption.series[0].data = cloudTime
|
|
|
|
+ lineChartOption.series[1].data = cloudNum
|
|
|
|
|
|
|
|
+ state.myChart.clear()
|
|
|
|
+ state.myChart.setOption(lineChartOption)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
const onRefresh = () => {
|
|
const onRefresh = () => {
|
|
finished.value = false
|
|
finished.value = false
|
|
// 重新加载数据
|
|
// 重新加载数据
|
|
@@ -119,6 +213,10 @@ export default defineComponent({
|
|
getList()
|
|
getList()
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ onMounted(async () => {
|
|
|
|
+ await getList()
|
|
|
|
+ })
|
|
|
|
+
|
|
return () => (
|
|
return () => (
|
|
<div class={[styles.exercisContainer]}>
|
|
<div class={[styles.exercisContainer]}>
|
|
<div class={styles.topWrap}>
|
|
<div class={styles.topWrap}>
|
|
@@ -131,6 +229,7 @@ export default defineComponent({
|
|
<Cell
|
|
<Cell
|
|
class={styles.userMember}
|
|
class={styles.userMember}
|
|
labelClass={styles.timeRemaining}
|
|
labelClass={styles.timeRemaining}
|
|
|
|
+ border={false}
|
|
v-slots={{
|
|
v-slots={{
|
|
icon: () => (
|
|
icon: () => (
|
|
<div class={styles.userImgSection}>
|
|
<div class={styles.userImgSection}>
|
|
@@ -150,64 +249,115 @@ export default defineComponent({
|
|
/>
|
|
/>
|
|
</div>
|
|
</div>
|
|
),
|
|
),
|
|
- label: () => <div class={styles.subjectName}></div>
|
|
|
|
|
|
+ label: () => (
|
|
|
|
+ <div class={styles.subjectName}>
|
|
|
|
+ <span class={styles.subjectTag}>
|
|
|
|
+ <img src={iconSubject} class={styles.iconSubject} />
|
|
|
|
+ 口风琴
|
|
|
|
+ </span>
|
|
|
|
+ </div>
|
|
|
|
+ )
|
|
}}
|
|
}}
|
|
></Cell>
|
|
></Cell>
|
|
|
|
+
|
|
|
|
+ <div class={styles.itemBottom}>
|
|
|
|
+ <div class={styles.itemBottomDot}>
|
|
|
|
+ <p class={styles.dotMain}>
|
|
|
|
+ {state.userTrainOverView.trainTime || 0}
|
|
|
|
+ <span>分钟</span>{' '}
|
|
|
|
+ </p>
|
|
|
|
+ <p class={styles.dotSub}> 累计练习时长</p>
|
|
|
|
+ </div>
|
|
|
|
+ <div class={styles.itemBottomDot}>
|
|
|
|
+ <p class={styles.dotMain}>
|
|
|
|
+ {state.userTrainOverView.trainDays || 0}
|
|
|
|
+ <span>天</span>{' '}
|
|
|
|
+ </p>
|
|
|
|
+ <p class={styles.dotSub}>累计练习天数 </p>
|
|
|
|
+ </div>
|
|
|
|
+ <div class={styles.itemBottomDot}>
|
|
|
|
+ <p class={styles.dotMain}>
|
|
|
|
+ {state.userTrainOverView.trainTime || 0}
|
|
|
|
+ <span>分钟</span>{' '}
|
|
|
|
+ </p>
|
|
|
|
+ <p class={styles.dotSub}>平均训练时长 </p>
|
|
|
|
+ </div>
|
|
|
|
+ <div class={styles.itemBottomDot}>
|
|
|
|
+ <p class={styles.dotMain}>
|
|
|
|
+ {state.userTrainOverView.trainNum || 0}
|
|
|
|
+ <span>次</span>{' '}
|
|
|
|
+ </p>
|
|
|
|
+ <p class={styles.dotSub}>平均训练次数 </p>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
</TheSticky>
|
|
</TheSticky>
|
|
</div>
|
|
</div>
|
|
<img class={styles.bgImg} src={bgImg} />
|
|
<img class={styles.bgImg} src={bgImg} />
|
|
- {/* <div class={styles.topInfoRight}>
|
|
|
|
- <div class={styles.infoDay}>
|
|
|
|
- <p class={styles.infoDayMain}>
|
|
|
|
- {infoDetail.value.practiceDays
|
|
|
|
- ? infoDetail.value.practiceDays
|
|
|
|
- : 0}
|
|
|
|
- </p>
|
|
|
|
- <p class={styles.infoDaysub}>
|
|
|
|
- <img src={iconDays} />
|
|
|
|
- 练习天数(天)
|
|
|
|
- </p>
|
|
|
|
- </div>
|
|
|
|
- <div class={styles.infoTime}>
|
|
|
|
- <p class={styles.infoDayMain}>
|
|
|
|
- {infoDetail.value.practiceTimes
|
|
|
|
- ? Math.floor(infoDetail.value.practiceTimes / 60)
|
|
|
|
- : 0}
|
|
|
|
|
|
|
|
- </p>
|
|
|
|
- <p class={styles.infoDaysub}>
|
|
|
|
- <img src={iconClock} />
|
|
|
|
- 练习时长(分钟)
|
|
|
|
- </p>
|
|
|
|
- </div>
|
|
|
|
- </div> */}
|
|
|
|
- {/* <CellGroup inset>
|
|
|
|
- <Cell
|
|
|
|
- class={styles.select}
|
|
|
|
- center
|
|
|
|
- isLink
|
|
|
|
- onClick={() => (state.showPopoverTime = true)}
|
|
|
|
- >
|
|
|
|
- {{
|
|
|
|
- // icon: () => <img class={styles.icon} src={iconData} />,
|
|
|
|
- title: () => (
|
|
|
|
- <div class="van-ellipsis">{state.practiceMonthName}</div>
|
|
|
|
- )
|
|
|
|
- }}
|
|
|
|
- </Cell>
|
|
|
|
- </CellGroup>
|
|
|
|
- */}
|
|
|
|
{showContact.value ? (
|
|
{showContact.value ? (
|
|
<OFullRefresh
|
|
<OFullRefresh
|
|
v-model:modelValue={refreshing.value}
|
|
v-model:modelValue={refreshing.value}
|
|
onRefresh={onRefresh}
|
|
onRefresh={onRefresh}
|
|
style={{ minHeight: `calc(100vh - var(--header-height))` }}
|
|
style={{ minHeight: `calc(100vh - var(--header-height))` }}
|
|
>
|
|
>
|
|
|
|
+ <div class={styles.trainWeek}>
|
|
|
|
+ <div class={styles.trainTitle}>
|
|
|
|
+ <img src={iconTrainTitle} />
|
|
|
|
+
|
|
|
|
+ <span
|
|
|
|
+ class={styles.timeRange}
|
|
|
|
+ onClick={() => (state.showPopoverTime = true)}
|
|
|
|
+ >
|
|
|
|
+ {dayjs(forms.practiceMonth).format('YYYY-MM-DD')}至
|
|
|
|
+ {dayjs(forms.endTime).format('YYYY-MM-DD')}
|
|
|
|
+ <i class={styles.iconArrow}></i>
|
|
|
|
+ </span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class={styles.TrainDataTopRight}>
|
|
|
|
+ <div
|
|
|
|
+ onClick={() => {
|
|
|
|
+ qualifiedFlag.value = !qualifiedFlag.value
|
|
|
|
+ lineChartOption.legend.selected['训练时长'] =
|
|
|
|
+ qualifiedFlag.value
|
|
|
|
+ state.myChart.setOption(lineChartOption)
|
|
|
|
+ }}
|
|
|
|
+ class={[
|
|
|
|
+ styles.DataTopRightItem,
|
|
|
|
+ qualifiedFlag.value ? '' : styles.DataTopRightItemDis
|
|
|
|
+ ]}
|
|
|
|
+ >
|
|
|
|
+ <div class={styles.DataTopRightDot}></div>
|
|
|
|
+ <p>训练时长</p>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ onClick={() => {
|
|
|
|
+ unqualifiedFlag.value = !unqualifiedFlag.value
|
|
|
|
+ lineChartOption.legend.selected['使用次数'] =
|
|
|
|
+ unqualifiedFlag.value
|
|
|
|
+ state.myChart.setOption(lineChartOption)
|
|
|
|
+ }}
|
|
|
|
+ class={[
|
|
|
|
+ styles.DataTopRightItem,
|
|
|
|
+ unqualifiedFlag.value ? '' : styles.DataTopRightItemDis
|
|
|
|
+ ]}
|
|
|
|
+ >
|
|
|
|
+ <div class={[styles.DataTopRightDot, styles.red]}></div>
|
|
|
|
+ <p>使用次数</p>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ id="exerciseWeek"
|
|
|
|
+ class={styles.exerciseWeek}
|
|
|
|
+ // style={{ height: payForm.height, width: payForm.width }}
|
|
|
|
+ ></div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
<List
|
|
<List
|
|
loading-text=" "
|
|
loading-text=" "
|
|
finished={finished.value}
|
|
finished={finished.value}
|
|
finished-text=" "
|
|
finished-text=" "
|
|
onLoad={getList}
|
|
onLoad={getList}
|
|
|
|
+ style={{ overflow: 'hidden' }}
|
|
>
|
|
>
|
|
{list.value.map((item: any) => (
|
|
{list.value.map((item: any) => (
|
|
<DetailItem item={item} />
|
|
<DetailItem item={item} />
|
|
@@ -273,6 +423,8 @@ export default defineComponent({
|
|
}
|
|
}
|
|
}
|
|
}
|
|
state.showPopoverTime = false
|
|
state.showPopoverTime = false
|
|
|
|
+ refreshing.value = true
|
|
|
|
+ getList()
|
|
}}
|
|
}}
|
|
/>
|
|
/>
|
|
</div>
|
|
</div>
|