import { Ref, computed, defineComponent, reactive, ref } from 'vue'; import styles from '../index2.module.less'; import { NButton, NDataTable, NIcon, NNumberAnimation, NTooltip, useMessage } from 'naive-ui'; import { useECharts } from '@/hooks/web/useECharts'; // import Pagination from '/src/components/pagination'; import { getPracticePageStat, getTestStat } from '@/views/data-module/api'; import { formateSeconds, getHours, getLastMinutes, getMinutes, getSecend, getTimes } from '/src/utils/dateFormat'; import { api_practiceStatPage } from '../../classList/api'; import TheEmpty from '/src/components/TheEmpty'; import iconSortDefault from '@/common/images/icon-sort-default.png'; import iconSortDesc from '@/common/images/icon-sort-desc.png'; import iconSortAsc from '@/common/images/icon-sort-asc.png'; import { convertToChineseNumeral } from '/src/utils'; import { useRouter } from 'vue-router'; import { setTabsCaches } from '/src/hooks/use-async'; import iconQuestion from '/src/common/images/icon-question.png' export default defineComponent({ name: 'home-practiceData', props: { timer: { type: Array, defaut: () => [] } }, setup(props, { expose }) { const router = useRouter() const message = useMessage() const chartRef = ref(null); const { setOptions } = useECharts(chartRef as Ref); const practiceFlag = ref(true); const payForm = reactive({ height: '360px', width: '100%', practiceDuration: 0, evaluateUserCount: 0, evaluateFrequency: 0, publishUserCount: 0, publishCount: 0, practiceUserCount: 0, paymentAmount: 0, practiceDurationAvg: 0, practiceDays: 0, practiceDurationTotal: 0, dateList: [], timeList: [] }); const state = reactive({ loading: false, pagination: { page: 1, rows: 10, pageTotal: 4 }, searchForm: { orderBy: null as any, sort: null as any, }, tableList: [] as any, goCourseVisiable: false }); const currentTimer = computed(() => { return props.timer; }); const toolTitleTips = (title: string, item: any) => { return {{ trigger: () => (
{title}
), default: item.sortOrder === 'descend' ? '点击升序' : item.sortOrder === 'ascend' ? '取消排序' : '点击降序' }}
} const practiceDurationRef = reactive({ title() { return ( toolTitleTips('练习总时长', practiceDurationRef) ); }, key: 'practiceDuration', sorter: true, sortOrder: false as any, render(row: any) { return <>{formateSeconds((row.practiceDuration as any) || 0)} } }); const practiceDaysRef = reactive({ title() { return ( toolTitleTips('练习天数', practiceDaysRef) ); }, key: 'practiceDays', sorter: true, sortOrder: false as any }); const practiceDurationAvgRef = reactive({ title() { return ( toolTitleTips('平均练习时长', practiceDurationAvgRef) ); }, key: 'practiceDurationAvg', sorter: true, sortOrder: false as any, render(row: any) { return <>{formateSeconds((row.practiceDurationAvg as any) || 0)} } }); const evaluateFrequencyRef = reactive({ title() { return ( toolTitleTips('评测次数', evaluateFrequencyRef) ); }, key: 'evaluateFrequency', sorter: true, sortOrder: false as any }); const publishCountRef = reactive({ title() { return ( toolTitleTips('作品数量', publishCountRef) ); }, key: 'publishCount', sorter: true, sortOrder: false as any }); const publishScoreRef = reactive({ title() { return ( toolTitleTips('最新作品分数', publishScoreRef) ); }, key: 'publishScore', sorter: true, sortOrder: false as any }); const publishTimeRef = reactive({ title() { return ( toolTitleTips('最新作品时间', publishTimeRef) ); }, key: 'publishTime', sorter: true, sortOrder: false as any }); const copyTo = (text: string) => { const input = document.createElement('input'); input.value = text; document.body.appendChild(input); input.select(); input.setSelectionRange(0, input.value.length); document.execCommand('Copy'); document.body.removeChild(input); message.success('复制成功'); }; const columns = () => { return [ { title: '学生姓名', key: 'studentName', render: (row: any) => { return ( {{ trigger: () => (
copyTo(row.studentName)}> {row.studentName}
), default: '点击复制' }}
); } }, { title: '年级班级', key: 'date', render(row: any) { return ( <> {row.currentGradeNum && row.currentClass ? convertToChineseNumeral(row.currentGradeNum) + '年级' + row.currentClass + '班' : ''} ) } }, { title: '乐器', key: 'instrumentName' }, practiceDurationRef, practiceDaysRef, practiceDurationAvgRef, evaluateFrequencyRef, { title: () => 发布作品 {{ trigger: () => ( ), default: () => '筛选时间段内评测是否发布作品' }} , key: 'publishFlag', render: (row: any) => row.publishFlag ? '是' : '否' }, publishCountRef, publishScoreRef, publishTimeRef, { title: '操作', key: 'titleImg', render: (row: any) => ( { setTabsCaches('evaluatingRcode', 'tabName', { path: '/studentDetail' }); router.push({ path: '/studentDetail', query: { studentId: row.studentId, studentName: row.studentName, times: JSON.stringify(currentTimer.value) } }); }} > 详情 ) } ]; }; // 统计排序 const handleSorterChange = (sorter: any) => { if (!sorter.order) { state.searchForm.orderBy = '' as string state.searchForm.sort = '' as string practiceDurationRef.sortOrder = false practiceDaysRef.sortOrder = false practiceDurationAvgRef.sortOrder = false evaluateFrequencyRef.sortOrder = false publishCountRef.sortOrder = false publishScoreRef.sortOrder = false publishTimeRef.sortOrder = false } else { state.searchForm.orderBy = sorter.columnKey practiceDurationRef.sortOrder = false practiceDaysRef.sortOrder = false practiceDurationAvgRef.sortOrder = false evaluateFrequencyRef.sortOrder = false publishCountRef.sortOrder = false publishScoreRef.sortOrder = false publishTimeRef.sortOrder = false if (sorter.columnKey == 'practiceDuration') { practiceDurationRef.sortOrder = sorter.order } if (sorter.columnKey == 'practiceDays') { practiceDaysRef.sortOrder = sorter.order } if (sorter.columnKey == 'practiceDurationAvg') { practiceDurationAvgRef.sortOrder = sorter.order } if (sorter.columnKey == 'evaluateFrequency') { evaluateFrequencyRef.sortOrder = sorter.order } if (sorter.columnKey == 'publishCount') { publishCountRef.sortOrder = sorter.order } if (sorter.columnKey == 'publishScore') { publishScoreRef.sortOrder = sorter.order } if (sorter.columnKey == 'publishTime') { publishTimeRef.sortOrder = sorter.order } state.searchForm.sort = sorter.order == 'ascend' ? 'asc' : 'desc' } getList2() } const getList2 = async () => { state.loading = true try { const res = await api_practiceStatPage({ page: 1, rows: 999, ...state.searchForm, ...getTimes( currentTimer.value, ['startTime', 'endTime'], 'YYYY-MM-DD' ) }); state.tableList = res.data.rows; } catch (e) { console.log(e); } state.loading = false }; const getTestStatList = async () => { state.loading = true try { const res2 = await getTestStat({ page: 1, rows: 999, ...getTimes( currentTimer.value, ['startTime', 'endTime'], 'YYYY-MM-DD' ) }); payForm.dateList = res2.data.trainingStatDetailList.map((item: any) => { return item.date; }); payForm.timeList = res2.data.trainingStatDetailList.map((item: any) => { return item.practiceUserCount; }); setChart(); } catch { // } state.loading = false } const getPracticePageStatList = async () => { state.loading = true try { const {data} = await getPracticePageStat({ page: 1, rows: 999, ...getTimes( currentTimer.value, ['startTime', 'endTime'], 'YYYY-MM-DD' ) }); payForm.practiceDuration = data.practiceDuration; payForm.practiceDurationAvg = data.practiceDurationAvg; payForm.practiceUserCount = data.practiceUserCount; payForm.evaluateUserCount = data.evaluateUserCount payForm.evaluateFrequency = data.evaluateFrequency payForm.publishUserCount = data.publishUserCount payForm.publishCount = data.publishCount } catch { // } state.loading = false } const getList = async () => { await getPracticePageStatList() await getTestStatList() await getList2() } expose({ getList }); const setChart = () => { setOptions({ tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } }, legend: { show: false, selected: { //在这里设置默认展示就ok了 练习人数: practiceFlag.value } }, xAxis: { type: 'category', boundaryGap: true, axisLabel: { show: true // interval: 0 }, data: payForm.dateList }, yAxis: [ { type: 'value', axisLabel: { formatter: '{value}人' }, axisTick: { show: false }, splitArea: { show: false, areaStyle: { color: ['rgba(255,255,255,0.2)'] } }, minInterval: 1, splitNumber: 5 } ], grid: { left: '1%', right: '1%', top: '2%', bottom: 0, containLabel: true }, series: [ { data: payForm.timeList, type: 'bar', barWidth: '48px', itemStyle: { normal: { //这里设置柱形图圆角 [左上角,右上角,右下角,左下角] barBorderRadius: [8, 8, 0, 0], color: '#CDE5FF' }, emphasis: { focus: 'series', color: '#3583FA' //hover时改变柱子颜色 } } as any } ], formatter: (item: any) => { if (Array.isArray(item)) { return [ item[0].axisValueLabel, ...item.map((d: any) => { return `
${d.marker}练习人数: ${d.value}人 `; }) ].join(''); } else { return item; } } }); }; getList(); return () => ( <>

练习人数

{getHours(payForm.practiceDurationAvg) > 0 ? (

) : null} {getHours(payForm.practiceDurationAvg) > 0 || getLastMinutes(payForm.practiceDurationAvg) > 0 ? (
) : null}

平均每天练习时长

{getHours(payForm.practiceDuration) > 0 ? (

) : null} {getHours(payForm.practiceDuration) > 0 || getLastMinutes(payForm.practiceDuration) > 0 ? (
) : null}

练习总时长

/

评测人数/次数

/

作品人数/数量

{/*
{ practiceFlag.value = !practiceFlag.value; setChart(); }} class={[ styles.DataTopRightItem, practiceFlag.value ? '' : styles.DataTopRightItemDis ]}>

练习人数

*/}
}} class={styles.classTable} loading={state.loading} columns={columns()} onUpdate:sorter={handleSorterChange} data={state.tableList}> {/* */}
); } });