|
@@ -0,0 +1,411 @@
|
|
|
+import React, { useState, useEffect, memo , useCallback } from 'react'
|
|
|
+
|
|
|
+import { View, Image } from '@tarojs/components'
|
|
|
+
|
|
|
+import Taro from '@tarojs/taro'
|
|
|
+
|
|
|
+import './index.scss'
|
|
|
+
|
|
|
+import { getQuestionCard, postQuestionCard } from '../../api/QuestionCard'
|
|
|
+
|
|
|
+import TimeCom from './component/TimeCom'
|
|
|
+
|
|
|
+import BgPanel from './component/BgPanel'
|
|
|
+
|
|
|
+import Modal from './component/Modal'
|
|
|
+
|
|
|
+import Tip from '../../utils/tip'
|
|
|
+
|
|
|
+const transferTime = (_timeStamp: number): string => {
|
|
|
+
|
|
|
+ const formatTime = ( second ) => second < 10 ? '0' + second : second
|
|
|
+
|
|
|
+ let cache = 0
|
|
|
+ if (_timeStamp < 60) {
|
|
|
+ return `0:${formatTime(_timeStamp)}`
|
|
|
+
|
|
|
+ } else if ( _timeStamp >= 60 && _timeStamp < 120 ) {
|
|
|
+
|
|
|
+ cache = _timeStamp - 60
|
|
|
+ return `1:${formatTime(cache)}`
|
|
|
+
|
|
|
+ } else if ( _timeStamp >= 120 && _timeStamp < 180) {
|
|
|
+ cache = _timeStamp - 120
|
|
|
+
|
|
|
+ return `2:${formatTime(cache)}`
|
|
|
+ }
|
|
|
+
|
|
|
+ return ''
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+type CourseType = {
|
|
|
+ fickerId: number,
|
|
|
+ content: Record<string, any>,
|
|
|
+ answerList: Record<string, any>[],
|
|
|
+ label: string,
|
|
|
+ clickAnswer: (item: any) => void,
|
|
|
+ PostQuestionCard: () => void
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+let count: number = 0
|
|
|
+
|
|
|
+interface IScreen {
|
|
|
+ WScreen: number,
|
|
|
+ HScreen: number
|
|
|
+}
|
|
|
+
|
|
|
+// 点击的过程卡片
|
|
|
+const Course: React.FC<CourseType> = ({
|
|
|
+ fickerId,
|
|
|
+ content,
|
|
|
+ answerList,
|
|
|
+ label,
|
|
|
+ clickAnswer,
|
|
|
+ PostQuestionCard
|
|
|
+}) => {
|
|
|
+
|
|
|
+ // 屏幕信息比率
|
|
|
+ const [ screen, setScreen ] = useState<IScreen>({WScreen: 0, HScreen: 0})
|
|
|
+
|
|
|
+ console.log('cccc', count += 1);
|
|
|
+
|
|
|
+ useEffect( () => {
|
|
|
+ Taro.getSystemInfo({
|
|
|
+ success: function (res) {
|
|
|
+ const {screenWidth, screenHeight} = res
|
|
|
+ setScreen({WScreen: screenWidth / 375, HScreen: screenHeight / 812})
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ // const RenderCom = memo(() => />)
|
|
|
+
|
|
|
+
|
|
|
+ return (
|
|
|
+ <View className='Course'>
|
|
|
+ <BgPanel label={label} />
|
|
|
+ {/* */}
|
|
|
+
|
|
|
+
|
|
|
+ {/* 绿色背景 */}
|
|
|
+ <Image className='Topicbg' src={require('../../assets/TopicPage/Topicbg.png')} />
|
|
|
+
|
|
|
+ {/* 左侧显示面板 */}
|
|
|
+ <View className='show-panel'>
|
|
|
+ {/* 展示图 */}
|
|
|
+ {
|
|
|
+ content.length && content?.map( item => (
|
|
|
+ <View
|
|
|
+ className='game-item'
|
|
|
+ key={item.id}
|
|
|
+ style={{
|
|
|
+ width: item.pw * screen.WScreen ,
|
|
|
+ height: item.ph * screen.HScreen ,
|
|
|
+ top: item.py * screen.HScreen,
|
|
|
+ left: item.px * screen.WScreen,
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {/* 圆 */}
|
|
|
+ {
|
|
|
+ item.bg === 'false' && <View
|
|
|
+ className={['round', item.id === fickerId? 'ficker' : ''].join(',')}
|
|
|
+ style={{
|
|
|
+ background: item.color,
|
|
|
+ width: item.iw * screen.WScreen,
|
|
|
+ height: item.ih * screen.HScreen,
|
|
|
+ top: item.iy * screen.HScreen,
|
|
|
+ left: item.ix * screen.WScreen
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ {/* 图片 */}
|
|
|
+ <Image
|
|
|
+ className={['show-image'].join(',')}
|
|
|
+ src={item.imgUrl}
|
|
|
+ mode='aspectFit'
|
|
|
+ style={{
|
|
|
+ width: item.w * screen.WScreen ,
|
|
|
+ height: item.h * screen.HScreen ,
|
|
|
+ top: item.y * screen.HScreen,
|
|
|
+ left: item.x * screen.WScreen ,
|
|
|
+ position: 'absolute'
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+
|
|
|
+ ))
|
|
|
+ }
|
|
|
+
|
|
|
+ </View>
|
|
|
+ {/* 右侧选择面板 */}
|
|
|
+ <View className='opra-panel' >
|
|
|
+ {
|
|
|
+ answerList?.map( item => (
|
|
|
+ <View className='answer-item' key={item.id} onClick={() => clickAnswer(item)}>
|
|
|
+ <View className='answer-round' style={{background: item.yourAnswer}} />
|
|
|
+ <Image mode='aspectFit' src={item.imgUrl} />
|
|
|
+ </View>
|
|
|
+ ))
|
|
|
+ }
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* ok 提交按钮 */}
|
|
|
+ <Image mode='aspectFill' onClick={() => PostQuestionCard()} className='ok' src={require('../../assets/TopicPage/ok.png')} />
|
|
|
+
|
|
|
+
|
|
|
+ </View>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+const CoursePage = memo((props: CourseType) => <Course {...props} />)
|
|
|
+
|
|
|
+
|
|
|
+let timeStamp: number = 0
|
|
|
+
|
|
|
+const TopicPage: React.FC = () => {
|
|
|
+
|
|
|
+ // 题卡id
|
|
|
+ const [ cardId, setCardId] = useState<string>('')
|
|
|
+
|
|
|
+ const [ visible, setVisible ] = useState<boolean>(false)
|
|
|
+
|
|
|
+ const [time, setTime] = useState<string>("0:00")
|
|
|
+
|
|
|
+ // 当前闪烁下标
|
|
|
+ const [ fickerId, setFickerId ] = useState<number>(0)
|
|
|
+
|
|
|
+ // 闪烁颜色
|
|
|
+ const [ fickerColor, setFickerColor ] = useState<string>('')
|
|
|
+
|
|
|
+ const [ content, setContent ] = useState<Record<string, any>>({})
|
|
|
+
|
|
|
+ const [ answerList, setAnswerList] = useState<Record<string, any>>([])
|
|
|
+
|
|
|
+ // 正确数
|
|
|
+ const [TrueQuestionNum, setTrueQuestionNum] = useState<number>(0)
|
|
|
+
|
|
|
+ // 复活次数
|
|
|
+ const [ LifeNum, setLifeNum ] = useState<number>(0)
|
|
|
+
|
|
|
+ // 题卡标题
|
|
|
+ const [ label, setLabel ] = useState<string>('')
|
|
|
+
|
|
|
+ // 时间
|
|
|
+ // const [ timeStamp, setTimeStamp ] = useState<number>(0)
|
|
|
+
|
|
|
+ // 定时器
|
|
|
+ const [timeId, setTimeId] = useState<any>('')
|
|
|
+
|
|
|
+ useEffect( () => {
|
|
|
+ const _timeId = setInterval( () => {
|
|
|
+
|
|
|
+ timeStamp += 1
|
|
|
+
|
|
|
+ setTime(transferTime(timeStamp))
|
|
|
+
|
|
|
+
|
|
|
+ }, 1000)
|
|
|
+ setTimeId(_timeId)
|
|
|
+
|
|
|
+ return () => {
|
|
|
+
|
|
|
+ stopSetinterval(_timeId)
|
|
|
+ }
|
|
|
+ // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
+ }, [])
|
|
|
+
|
|
|
+
|
|
|
+ // 获取屏幕信息及其路由参数
|
|
|
+ useEffect( () => {
|
|
|
+
|
|
|
+ const routeParams = Taro.getCurrentInstance().router?.params.pointState as string
|
|
|
+
|
|
|
+ setCardId(routeParams)
|
|
|
+
|
|
|
+ // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ useEffect( () => {
|
|
|
+ cardId && GetQuestionCard()
|
|
|
+ // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
+ }, [cardId])
|
|
|
+
|
|
|
+ useEffect( () => {
|
|
|
+ setFickerColor(content.length && content.filter( item => item.id === fickerId )[0]?.color )
|
|
|
+ }, [content, fickerId])
|
|
|
+
|
|
|
+ // 获取题卡
|
|
|
+ const GetQuestionCard = async () => {
|
|
|
+
|
|
|
+ Tip.loading()
|
|
|
+ const data = await getQuestionCard(cardId)
|
|
|
+ Tip.loaded()
|
|
|
+ setContent(data.content.map(item => {
|
|
|
+ return {...item, flag: false}
|
|
|
+ }))
|
|
|
+
|
|
|
+ setAnswerList(data.options)
|
|
|
+
|
|
|
+ if (data.lifeNum >= 6) {
|
|
|
+
|
|
|
+ openModal()
|
|
|
+ }
|
|
|
+
|
|
|
+ setLifeNum(data.lifeNum)
|
|
|
+ setLabel(data.label)
|
|
|
+
|
|
|
+ setFickerId(data.content.find( item => !item.flag && item.bg === 'false')?.id )
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提交题卡
|
|
|
+ const PostQuestionCard = useCallback( async () => {
|
|
|
+
|
|
|
+ const $par = {
|
|
|
+ cardId: cardId,
|
|
|
+ takeTime: timeStamp,
|
|
|
+ optionAnswers: answerList.map(item => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ optionId: item.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ Tip.loading()
|
|
|
+ const data = await postQuestionCard($par)
|
|
|
+ Tip.loaded()
|
|
|
+ console.log(data);
|
|
|
+
|
|
|
+ setTrueQuestionNum(data.trueQuestionNum)
|
|
|
+
|
|
|
+ // stopInterval(timer)
|
|
|
+
|
|
|
+ openModal()
|
|
|
+
|
|
|
+ let cardIdList: Record<string, any>[] = []
|
|
|
+
|
|
|
+
|
|
|
+ console.log(Taro.getStorageSync('cardIdList'), 'Taro.getStorageSync');
|
|
|
+
|
|
|
+ const getOldCardIdList = Taro.getStorageSync('cardIdList') instanceof Array ? Taro.getStorageSync('cardIdList').filter( item => item.key !== cardId) : []
|
|
|
+
|
|
|
+ console.log(getOldCardIdList, 'getOldCardIdList');
|
|
|
+
|
|
|
+ cardIdList.push({
|
|
|
+ key: cardId,
|
|
|
+ id: data.id
|
|
|
+ })
|
|
|
+
|
|
|
+ // 存储题卡Id
|
|
|
+ if (getOldCardIdList.length > 0) {
|
|
|
+ cardIdList = cardIdList.concat(getOldCardIdList)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Taro.setStorageSync('cardIdList', cardIdList)
|
|
|
+
|
|
|
+ // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
+ }, [])
|
|
|
+
|
|
|
+
|
|
|
+ // 点击选择当前答案 选择当前的颜色
|
|
|
+ const clickAnswer = useCallback( (item: Record<string, any>) => {
|
|
|
+
|
|
|
+ const deepItem = JSON.parse(JSON.stringify(item))
|
|
|
+
|
|
|
+ const deepAnswerList = JSON.parse( JSON.stringify(answerList))
|
|
|
+
|
|
|
+ const deepContent = JSON.parse(JSON.stringify(content))
|
|
|
+
|
|
|
+ // 如果存在 yourAnswer 则说明是取消选择
|
|
|
+ if (deepItem.yourAnswer) {
|
|
|
+
|
|
|
+ deepItem.yourAnswer = ''
|
|
|
+
|
|
|
+ const index = deepAnswerList.findIndex(answer => answer.id === deepItem.id)
|
|
|
+
|
|
|
+ deepAnswerList.splice(index, 1, deepItem)
|
|
|
+
|
|
|
+ deepContent.forEach( _content => {
|
|
|
+ if (_content.id === deepItem.bindId) {
|
|
|
+ _content.flag = false
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ setFickerId(deepItem.bindId)
|
|
|
+ setAnswerList(deepAnswerList)
|
|
|
+ setContent(deepContent)
|
|
|
+
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ deepItem.yourAnswer = fickerColor
|
|
|
+
|
|
|
+ deepItem.bindId = fickerId
|
|
|
+
|
|
|
+ const index = deepAnswerList.findIndex(answer => answer.id === deepItem.id)
|
|
|
+
|
|
|
+ console.log(index, 'index');
|
|
|
+
|
|
|
+
|
|
|
+ deepAnswerList.splice(index, 1, deepItem)
|
|
|
+
|
|
|
+ setAnswerList(deepAnswerList)
|
|
|
+
|
|
|
+ deepContent.forEach( _content => {
|
|
|
+ if (_content.id === fickerId) {
|
|
|
+ _content.flag = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ setContent(deepContent)
|
|
|
+
|
|
|
+ setFickerId(deepContent.find( _item => !_item.flag && _item.bg === 'false')?.id )
|
|
|
+
|
|
|
+ // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
+ },[])
|
|
|
+
|
|
|
+ // 做完题目后弹窗
|
|
|
+ const openModal = useCallback(() => {
|
|
|
+
|
|
|
+ setVisible(true)
|
|
|
+ stopSetinterval(timeId)
|
|
|
+ // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ // 关闭定时器
|
|
|
+ const stopSetinterval = (_timeId) => {
|
|
|
+ console.log('???');
|
|
|
+ clearInterval(_timeId)
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <View className='TopicPage'>
|
|
|
+ <Image className='bg' src={require('../../assets/TopicPage/bg.png')} />
|
|
|
+ <TimeCom time={time} />
|
|
|
+ <CoursePage
|
|
|
+ fickerId={fickerId}
|
|
|
+ label={label}
|
|
|
+ content={content}
|
|
|
+ answerList={answerList as Record<string, any>[]}
|
|
|
+ PostQuestionCard={PostQuestionCard}
|
|
|
+ clickAnswer={clickAnswer}
|
|
|
+ />
|
|
|
+
|
|
|
+ {/* 弹窗 */}
|
|
|
+ { visible ? <Modal
|
|
|
+ trueQuestionNum={TrueQuestionNum}
|
|
|
+ LifeNum={LifeNum}
|
|
|
+ cardId={cardId}
|
|
|
+ setLifeNum={setLifeNum}
|
|
|
+ timeStamp={timeStamp}
|
|
|
+ /> : null }
|
|
|
+ </View>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+export default TopicPage
|