import OSticky from '@/components/o-sticky' import { Button, closeToast, DatePicker, Grid, GridItem, Icon, Image, List, Picker, Popover, Popup, showFailToast, showLoadingToast, showSuccessToast, showToast } from 'vant' import { computed, defineComponent, nextTick, onMounted, reactive } from 'vue' import styles from './information.module.less' import iconSaveImage from '../images/icon-save-image.png' import iconWechat from '../images/icon-wechat.png' import OQrcode from '@/components/o-qrcode' import request from '@/helpers/request' import { useRoute } from 'vue-router' import { CountUp } from 'countup.js' import OEmpty from '@/components/o-empty' import dayjs from 'dayjs' import { promisefiyPostMessage, postMessage } from '@/helpers/native-message' import html2canvas from 'html2canvas' export default defineComponent({ name: 'detail-information', props: { termTimes: { type: Object, default: {} } }, setup(props) { const startTime = computed(() => props.termTimes.start) const endTime = computed(() => props.termTimes.end) const route = useRoute() const state = reactive({ timeShow: false, currentData: [dayjs().year() + ''], actionText: '上学期', actionType: 'up', actionTerm: [ { text: '上学期', color: 'var(--van-primary-color)', value: 'up' }, { text: '下学期', value: 'down' } ], oPopover: false, check: [], checkboxRefs: [] as any, showQrcode: false, qrcodeUrl: '', isLoading: false, list: [] as any, listState: { dataShow: true, // 判断是否有数据 loading: false, finished: false }, params: { startTime: dayjs(dayjs().year() + startTime.value).format('YYYY-MM-DD HH:mm:ss'), endTime: dayjs(dayjs().year() + endTime.value) .subtract(1, 'day') .format('YYYY-MM-DD HH:mm:ss'), page: 1, rows: 20 }, statistics: {} as any, orchestraInfo: {} as any // 乐团详情 }) // 选择学期 const onSelect = (val: any) => { state.actionTerm.forEach((item: any) => { item.color = null }) val.color = 'var(--van-primary-color)' state.actionText = val.text state.actionType = val.value if (val.value === 'up') { state.params.startTime = dayjs(Number(state.currentData[0]) - 1 + startTime.value).format( 'YYYY-MM-DD HH:mm:ss' ) state.params.endTime = dayjs(Number(state.currentData[0]) + endTime.value) .subtract(1, 'day') .format('YYYY-MM-DD HH:mm:ss') } else if (val.value === 'down') { state.params.startTime = dayjs(Number(state.currentData[0]) + endTime.value).format( 'YYYY-MM-DD HH:mm:ss' ) state.params.endTime = dayjs(Number(state.currentData[0]) + startTime.value) .subtract(1, 'day') .format('YYYY-MM-DD HH:mm:ss') } onSearch() } const onConfirmDate = (date: any) => { state.currentData = date.selectedValues if (state.actionType === 'up') { state.params.startTime = dayjs(Number(state.currentData[0]) - 1 + startTime.value).format( 'YYYY-MM-DD HH:mm:ss' ) state.params.endTime = dayjs(Number(state.currentData[0]) + endTime.value) .subtract(1, 'day') .format('YYYY-MM-DD HH:mm:ss') } else if (state.actionType === 'down') { state.params.startTime = dayjs(Number(state.currentData[0]) + endTime.value).format( 'YYYY-MM-DD HH:mm:ss' ) state.params.endTime = dayjs(Number(state.currentData[0]) + startTime.value) .subtract(1, 'day') .format('YYYY-MM-DD HH:mm:ss') } state.timeShow = false onSearch() } const getDetails = async () => { try { const { data } = await request.get('/api-school/orchestra/detail/' + route.query.id) state.orchestraInfo = data || {} } catch { // } } const getStatistics = async () => { try { const { data } = await request.post('/api-school/classGroup/statistics', { data: { orchestraId: route.query.id, startTime: state.params.startTime, endTime: state.params.endTime } }) state.statistics = data || {} initNumCountUp() } catch { // } } // 班级列表 const getList = async () => { try { if (state.isLoading) return state.isLoading = true const res = await request.post('/api-school/classGroup/page', { data: { ...state.params, orchestraId: route.query.id } }) state.listState.loading = false const result = res.data || {} // 处理重复请求数据 if (state.list.length > 0 && result.current === 1) { return } const rows = result.rows || [] state.list = state.list.concat(rows) state.listState.finished = result.current >= result.pages state.params.page = result.current + 1 state.listState.dataShow = state.list.length > 0 state.isLoading = false } catch { state.listState.dataShow = false state.listState.finished = true state.isLoading = false } } const onSearch = () => { state.params.page = 1 state.list = [] state.listState.dataShow = true // 判断是否有数据 state.listState.loading = false state.listState.finished = false getList() } const initNumCountUp = () => { nextTick(() => { // 在读学生 const statistics = state.statistics new CountUp('currentStudentNum', statistics.studentNum || 0).start() new CountUp('time1', statistics.attendanceRate || 0).start() new CountUp('time2', statistics.homeworkRate || 0).start() new CountUp('time3', statistics.homeworkQualifiedRate || 0).start() }) } const imgs = reactive({ saveLoading: false, image: null as any, shareLoading: false }) const onSaveImg = async () => { // 判断是否在保存中... if (imgs.saveLoading) { return } imgs.saveLoading = true // 判断是否已经生成图片 if (imgs.image) { saveImg() } else { const container: any = document.getElementById(`preview-container`) html2canvas(container, { allowTaint: true, useCORS: true, backgroundColor: null }) .then(async (canvas) => { const url = canvas.toDataURL('image/png') imgs.image = url saveImg() }) .catch(() => { closeToast() imgs.saveLoading = false }) } } const onShare = () => { if (imgs.shareLoading) { return } imgs.shareLoading = true if (imgs.image) { openShare() } else { const container: any = document.getElementById(`preview-container`) html2canvas(container, { allowTaint: true, useCORS: true, backgroundColor: null }) .then(async (canvas) => { const url = canvas.toDataURL('image/png') imgs.image = url openShare() }) .catch(() => { closeToast() imgs.shareLoading = false }) } } const openShare = () => { const image = imgs.image setTimeout(() => { imgs.shareLoading = false }, 100) if (image) { postMessage( { api: 'shareTripartite', content: { title: '', desc: '', image, video: '', type: 'image', // button: ['copy'] shareType: 'wechat' } }, (res: any) => { if (res && res.content) { showToast(res.content.message || (res.content.status ? '分享成功' : '分享失败')) } } ) } } const saveImg = async () => { showLoadingToast({ message: '图片生成中...', forbidClick: true }) setTimeout(() => { imgs.saveLoading = false }, 100) const res = await promisefiyPostMessage({ api: 'savePicture', content: { base64: imgs.image } }) if (res?.content?.status === 'success') { showSuccessToast('保存成功') state.showQrcode = false } else { showFailToast('保存失败') } } onMounted(() => { getDetails() getStatistics() getList() }) return () => ( <>
(state.timeShow = true)}> {state.currentData[0]}年
{{ reference: () => (
{state.actionText}
) }}

{state.statistics.studentNum || 0}

在读学生

{state.statistics.attendanceRate || 0}%

到课率

{state.statistics.homeworkRate || 0}%

作业提交率

{state.statistics.homeworkQualifiedRate || 0}%

练习合格率

{state.listState.dataShow ? ( {state.list.map((item: any) => (
{item.name}

{item.preStudentNum || 0}

在读学生

{item.teacherName || '-'}

伴学指导

{item.completeCourseScheduleNum || 0}/{item.courseScheduleNum || 0}

课时

))}
) : ( )} {/* */} {state.orchestraInfo.canSignUp && (
)}

乐团报名

{state.orchestraInfo.name}
扫描上方二维码完成资料填写
二维码将在两小时后失效,请及时登记
(state.showQrcode = false)} />

分享方式

{{ icon: () => , text: () =>
保存图片
}}
{{ icon: () => , text: () =>
微信
}}
(state.timeShow = false)} /> ) } })