| | |
| | | node_modules |
| | | *.lock |
| | | package-lock.json |
| | | |
| | | *.mp3 |
| | | # 编译文件 |
| | | dist |
| | | dist-electron |
| | |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | @import './assets/style/examination.less'; |
| | | .updateDownloadInfo { |
| | | position: fixed; |
| | | top: 2px; |
| | |
| | | // 测试 |
| | | export const requestCtx = "https://jsek.bnuic.com"; //jsek |
| | | export const appId = 3; |
| | | // export const requestCtx = "http://182.92.203.7:3007"; //jsek |
| | | // export const appId = 27 |
| | | // export const requestCtx = "https://jsek.bnuic.com"; //jsek |
| | | // export const appId = 3; |
| | | export const requestCtx = "http://182.92.203.7:3007"; //jsek |
| | | export const appId = 27 |
| | | export const requestTimeOut = 300000; // 请求超时时间 |
| | | export const tokenKey = "token"; |
| | | export const userInfoKey = "website-front-userInfo"; // 用户信息key |
| | |
| | | @import './base.css'; |
| | | |
| | | @import './style/examination.less'; |
| | | #parentApp { |
| | | width: 100%; |
| | | height: 100%; |
| | |
| | | text-indent: 0em !important; |
| | | margin-left: 20px; |
| | | |
| | | /deep/ .el-textarea__inner:focus { |
| | | .el-textarea__inner:focus { |
| | | border-color: #15c0f2; |
| | | } |
| | | } |
| | | |
| | | .input { |
| | | /deep/ .el-input__inner { |
| | | .el-input__inner { |
| | | height: 26px; |
| | | } |
| | | } |
| | |
| | | border-bottom: 1px solid #000; |
| | | } |
| | | |
| | | /deep/ .el-textarea.is-disabled .el-textarea__inner { |
| | | .el-textarea.is-disabled .el-textarea__inner { |
| | | background-color: #fff; |
| | | } |
| | | |
| | | /deep/ .el-input.is-disabled .el-input__inner { |
| | | .el-input.is-disabled .el-input__inner { |
| | | background-color: #fff; |
| | | } |
| | | |
| | |
| | | align-items: center; |
| | | } |
| | | } |
| | | |
| | | ::v-deep { |
| | | .el-input__wrapper { |
| | | border-top: 0 !important; |
| | | } |
| | | .el-input__wrapper { |
| | | border-top: 0 !important; |
| | | } |
| | | } |
| | | |
| | |
| | | white-space: pre-wrap !important; |
| | | color: #000; |
| | | |
| | | /deep/ .el-checkbox__label { |
| | | .el-checkbox__label { |
| | | line-height: 1.5; |
| | | } |
| | | } |
| | | |
| | | /deep/ .el-radio__inner { |
| | | .el-radio__inner { |
| | | border-color: #a5a3a3; |
| | | } |
| | | |
| | |
| | | |
| | | /** 解析 */ |
| | | .objective { |
| | | /deep/ .el-collapse-item__header { |
| | | .el-collapse-item__header { |
| | | min-height: 48px; |
| | | height: min-content; |
| | | padding: 0 20px; |
| | |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | |
| | | ::v-deep { |
| | | img { |
| | | max-height: 48px; |
| | | } |
| | | img { |
| | | max-height: 48px; |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | /deep/ .el-collapse-item__header:focus:not(:hover) { |
| | | .el-collapse-item__header:focus:not(:hover) { |
| | | color: #333; |
| | | } |
| | | |
| | | /deep/ .el-collapse-item__content { |
| | | .el-collapse-item__content { |
| | | width: 93%; |
| | | padding: 0 20px; |
| | | background-color: #f4f4f4; |
| | |
| | | color: #333; |
| | | } |
| | | |
| | | /deep/ .el-collapse-item__arrow { |
| | | .el-collapse-item__arrow { |
| | | display: none; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | .subjective { |
| | | /deep/ .el-collapse-item__header { |
| | | .el-collapse-item__header { |
| | | height: 80px; |
| | | background-color: #f4f4f4; |
| | | width: 100%; |
| | |
| | | height: min-content; |
| | | margin-bottom: 6px; |
| | | |
| | | /deep/ img { |
| | | img { |
| | | margin-left: 10px; |
| | | object-fit: contain; |
| | | vertical-align: middle; |
| | |
| | | } |
| | | |
| | | .titleTextArea { |
| | | ::v-deep { |
| | | img, |
| | | .el-image__inner { |
| | | max-width: 150px !important; |
| | | max-height: 100px !important; |
| | | object-fit: contain; |
| | | } |
| | | img, |
| | | .el-image__inner { |
| | | max-width: 150px !important; |
| | | max-height: 100px !important; |
| | | object-fit: contain; |
| | | } |
| | | } |
| | | |
| | |
| | | object-fit: contain; |
| | | } |
| | | |
| | | /deep/ .examination-math { |
| | | .examination-math { |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | } |
| | | } |
| | | } |
| | |
| | | entry: '//182.92.203.7:3007/books/book/botany', |
| | | container: '#container', |
| | | activeRule: '/home' //匹配所有以/subPath开头的为子应用 |
| | | }, |
| | | aurturingAndEducationAged0to3:{ |
| | | name: 'app-content', |
| | | entry: '//182.92.203.7:3007/books/book/aurturingAndEducationAged0to3', |
| | | container: '#container', |
| | | activeRule: '/home' //匹配所有以/subPath开头的为子应用 |
| | | }, |
| | | childcareInstitutionsManagement:{ |
| | | name: 'app-content', |
| | | entry: '//182.92.203.7:3007/books/book/childcareInstitutionsManagement', |
| | | container: '#container', |
| | | activeRule: '/home' //匹配所有以/subPath开头的为子应用 |
| | | }, |
| | | preschoolGameGuidance:{ |
| | | name: 'app-content', |
| | | entry: '//182.92.203.7:3007/books/book/preschoolGameGuidance', |
| | | container: '#container', |
| | | activeRule: '/home' |
| | | }, |
| | | kindergartenLanguageActivity:{ |
| | | name: 'app-content', |
| | | entry: '//182.92.203.7:3007/books/book/kindergartenLanguageActivity', |
| | | container: '#container', |
| | | activeRule: '/home' |
| | | }, |
| | | preschoolEvaluation:{ |
| | | name: 'app-content', |
| | | entry: '//182.92.203.7:3007/books/book/preschoolEvaluation', |
| | | container: '#container', |
| | | activeRule: '/home' |
| | | }, |
| | | preschoolBasicKnowledge:{ |
| | | name: 'app-content', |
| | | entry: '//182.92.203.7:3007/books/book/preschoolBasicKnowledge', |
| | | container: '#container', |
| | | activeRule: '/home' |
| | | }, |
| | | kindergartenActivitiesDesignGuidance:{ |
| | | name: 'app-content', |
| | | entry: '//182.92.203.7:3007/books/book/kindergartenActivitiesDesignGuidance', |
| | | container: '#container', |
| | | activeRule: '/home' |
| | | }, |
| | | policiesAndRegulations:{ |
| | | name: 'app-content', |
| | | entry: '//182.92.203.7:3007/books/book/policiesAndRegulations', |
| | | container: '#container', |
| | | activeRule: '/home' |
| | | }, |
| | | OralAndBroadcasting:{ |
| | | name: 'app-content', |
| | | entry: '//182.92.203.7:3007/books/book/OralAndBroadcasting', |
| | | container: '#container', |
| | | activeRule: '/home' |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | export const useFormatData = () => { |
| | | const formatTime = (time:number) => { |
| | | if(time == 0) return '00:00' |
| | | const minutes = Math.floor(time / 60) |
| | | const remainingSeconds = time % 60 |
| | | return `${String(minutes).padStart(2, '0')}:${String(remainingSeconds).padStart(2, '0')}` |
| | | } |
| | | return { |
| | | formatTime |
| | | } |
| | | } |
| | | |
| | | |
| | | export const useCoordinateData = () => { |
| | | const getPageXY = (e:MouseEvent) => { |
| | | |
| | | } |
| | | return { |
| | | getPageXY |
| | | } |
| | | } |
New file |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogVisable" title="番茄闹钟" width="500" > |
| | | <div class="ring-box"> |
| | | <span class="title-txt">响铃时长</span> |
| | | <el-switch v-model="pageData.isRing" :disabled="isRuning" /> |
| | | <el-input-number v-model="pageData.ringTime" :disabled="isRuning" :min="1" step-strictly /> |
| | | </div> |
| | | <p class="prompt-txt ring-title">以秒为单位</p> |
| | | <div class="border" ></div> |
| | | <ul class="sustain-box"> |
| | | <li> |
| | | <span class="title-txt">持续时间</span> |
| | | <span class="label-txt" >专注时间</span> |
| | | <el-input-number v-model="pageData.workTime" :disabled="isRuning" :min="1" step-strictly /> |
| | | </li> |
| | | <li> |
| | | <span class="title-txt"></span> |
| | | <span class="label-txt">短休息</span> |
| | | <el-input-number v-model="pageData.shortTime" :disabled="isRuning" :min="0" step-strictly /> |
| | | </li> |
| | | <li> |
| | | <span class="title-txt"></span> |
| | | <span class="label-txt">长休息</span> |
| | | <el-input-number v-model="pageData.longTime" :disabled="isRuning" :min="0" step-strictly /> |
| | | </li> |
| | | </ul> |
| | | <p class="prompt-txt ring-title" >以分钟为单位</p> |
| | | <div class="border" ></div> |
| | | <div> |
| | | <el-button type="primary" @click="startFun" >开始</el-button> |
| | | <el-button type="primary" @click="pauseFun" >停止</el-button> |
| | | <el-button @click="resetFun">重置</el-button> |
| | | <el-button @click="handleRestFun(false)" >长休息</el-button> |
| | | <el-button @click="handleRestFun(true)">短休息</el-button> |
| | | </div> |
| | | {{ formatTime(pageData.currentTime) }} |
| | | </el-dialog> |
| | | <!-- <video src="../../assets/audio/买辣椒也用券.mp3" ref="audioRef"></video> --> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ElMessage } from 'element-plus' |
| | | import { ref, reactive, defineExpose ,watchEffect } from 'vue' |
| | | import {useFormatData} from '@/hooks/public' |
| | | const isShow =ref<boolean>(false) // 悬浮框是否显示 |
| | | const audioRef = ref<HTMLAudioElement>() // 音频实例 |
| | | const dialogVisable = ref<boolean>(false) // 弹窗状态 |
| | | const timerInterval = ref<any>(null) // 计时器实例 |
| | | const isRuning = ref<boolean>(false) // 计时器是否运行 |
| | | const isBreak = ref<boolean>(false) // true 休息 false 工作 |
| | | const isShortTime = ref<boolean>(false) // 长短休息模式 |
| | | const pageData = reactive({ |
| | | isRing: true, // 是否响铃 |
| | | ringTime: 5, // 响铃时长 秒 |
| | | workTime: 25, // 工作时长 分钟 |
| | | saveWorkTime: 0, // 剩余工作时间 |
| | | shortTime: 5, // 短休息 |
| | | longTime: 5, // 长休息 |
| | | currentTime:0, // 显示时间 秒 |
| | | }) |
| | | const { formatTime } = useFormatData() |
| | | watchEffect(() => { |
| | | pageData.currentTime = pageData.workTime * 60 |
| | | }) |
| | | watchEffect(() => { |
| | | if(!isBreak.value) pageData.saveWorkTime = pageData.currentTime |
| | | }) |
| | | const setDialogVisable = (value: boolean) => { |
| | | dialogVisable.value = value |
| | | } |
| | | // 开始计时 |
| | | const startFun = () => { |
| | | isShow.value = true |
| | | isRuning.value = true |
| | | timerInterval.value = setInterval(() => { |
| | | if(pageData.currentTime > 0) { |
| | | pageData.currentTime-- |
| | | } else { |
| | | playAudio() |
| | | if(isBreak.value) { |
| | | // 工作时间赋值 |
| | | isBreak.value = false |
| | | if( pageData.saveWorkTime) { |
| | | pageData.currentTime = pageData.saveWorkTime |
| | | ElMessage.success('休息结束,开始学习吧!') |
| | | } else { |
| | | clearInterval(timerInterval.value) |
| | | isRuning.value = false |
| | | ElMessage.success('学习结束') |
| | | } |
| | | |
| | | } else { |
| | | // 休息时间赋值 |
| | | isBreak.value = true |
| | | pageData.currentTime = isShortTime.value ? pageData.shortTime * 60 : pageData.longTime * 60 |
| | | ElMessage.success('休息一下吧!') |
| | | } |
| | | } |
| | | |
| | | }, 1000) |
| | | dialogVisable.value = false |
| | | } |
| | | // 暂停计时 |
| | | const pauseFun = () => { |
| | | isRuning.value = false |
| | | if(timerInterval.value) { |
| | | clearInterval(timerInterval.value) |
| | | } |
| | | } |
| | | // 重置计时器 |
| | | const resetFun = () => { |
| | | isRuning.value = false |
| | | isBreak.value = false |
| | | pauseFun() |
| | | pageData.currentTime = pageData.workTime * 60 |
| | | } |
| | | // 休息按钮 |
| | | const startBreak = () => { |
| | | if(isRuning.value && !isBreak.value) { |
| | | if(pageData.shortTime || pageData.longTime) { |
| | | pageData.saveWorkTime = pageData.currentTime |
| | | isBreak.value = true |
| | | pageData.currentTime = isShortTime.value ? pageData.shortTime * 60 : pageData.longTime * 60 |
| | | ElMessage.success('开始休息') |
| | | } else { |
| | | ElMessage.warning('暂未设置休息时间') |
| | | } |
| | | } |
| | | } |
| | | // 开始响铃 |
| | | const playAudio = () => { |
| | | audioRef.value!.currentTime = 0 |
| | | audioRef.value?.play() |
| | | setTimeout(() => { |
| | | pauseAudio() |
| | | },pageData.ringTime * 1000) |
| | | } |
| | | // 暂停响铃 |
| | | const pauseAudio = () => { |
| | | audioRef.value?.pause() |
| | | } |
| | | |
| | | // 长短休息 |
| | | const handleRestFun = (value:boolean) => { |
| | | isShortTime.value = value |
| | | startBreak() |
| | | } |
| | | |
| | | defineExpose({ |
| | | isShow, |
| | | isRuning, |
| | | pageData, |
| | | setDialogVisable, |
| | | startFun, |
| | | pauseFun, |
| | | resetFun, |
| | | handleRestFun |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .prompt-txt { |
| | | margin-top: 10px; |
| | | font-size: 12px; |
| | | color: #b7b7b7; |
| | | } |
| | | .title-txt { |
| | | color: #2c2c2c; |
| | | width: 4em; |
| | | } |
| | | .label-txt { |
| | | width: 4em; |
| | | color:#707070 ; |
| | | } |
| | | .ring-box { |
| | | width: 300px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | .ring-title { |
| | | padding-left: 150px; |
| | | } |
| | | .sustain-box { |
| | | width: 300px; |
| | | li { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | .border { |
| | | height: 1px; |
| | | background-color:#cecece ; |
| | | margin: 10px 0; |
| | | } |
| | | </style> |
| | |
| | | <div class="canvas-box" v-show="canvasShow"> |
| | | <canvas id="canvasRef" :width="canvasWith" :height="canvasheight"></canvas> |
| | | </div> |
| | | <!-- 番茄闹钟组件 --> |
| | | <div |
| | | class="watch-box" |
| | | v-if="pomodoroRef && pomodoroRef.isShow" |
| | | :style="{ top:position.x + 'px', left:position.y + 'px'}" |
| | | > |
| | | <p @mousedown.native="mouseDown">{{ formatTime(pomodoroRef.pageData.currentTime) }}</p> |
| | | <span @click="()=> pomodoroRef.isRuning ? pomodoroRef.pauseFun() : pomodoroRef.startFun()">{{pomodoroRef.isRuning ? '暂停': '开始'}}</span> |
| | | <span @click="pomodoroRef.resetFun" >重置</span> |
| | | <span @click="pomodoroRef.handleRestFun(false)">长休息</span> |
| | | <span @click="pomodoroRef.handleRestFun(true)">短休息</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 画笔组件 --> |
| | |
| | | <!-- <calculatorNew></calculatorNew> --> |
| | | <iframe src="https://www.geogebra.org/scientific" frameborder="0" class="iframe-box"></iframe> |
| | | </el-dialog> |
| | | <!-- 番茄闹钟 --> |
| | | <!-- <pomodoro ref="pomodoroRef" /> --> |
| | | </template> |
| | | <script setup lang="ts"> |
| | | import examination from '@/views/examination/index.vue' |
| | | import pomodoro from '@/views/components/pomodoro.vue' |
| | | import { ref, reactive, watch, onMounted, onBeforeMount, onBeforeUnmount, inject } from 'vue' |
| | | import { useRouter, useRoute } from 'vue-router' |
| | | import { ElMessage, ElMessageBox, valueEquals } from 'element-plus' |
| | | import { useFormatData } from '@/hooks/public' |
| | | import useClipboard from 'vue-clipboard3' |
| | | const { toClipboard } = useClipboard() |
| | | const { formatTime } = useFormatData() |
| | | const MG: any = inject('MG') |
| | | const toolClass = inject('toolClass') |
| | | //获取路由器 |
| | |
| | | } |
| | | MG.store.getProductList(obj).then((res) => { |
| | | console.log(res.datas, '图书信息') |
| | | if (!res.datas.length) return |
| | | bookInfo.value = res.datas[0] |
| | | if (res.datas[0].purchasedSaleMethodIdList.indexOf(res.datas[0].defaultSaleMethodId) > -1) { |
| | | isBuy.value = true |
| | |
| | | icon: fanqiezhong, |
| | | isShow: bookConfig.value.textbookComponents.indexOf('E4DC9777') > -1 |
| | | } |
| | | // { |
| | | // name: '番茄闹钟', |
| | | // icon: fanqiezhong, |
| | | // isShow: true |
| | | // } |
| | | ] |
| | | floatingToolBox = [ |
| | | { |
| | |
| | | break |
| | | } |
| | | } |
| | | |
| | | type pomodoroType = InstanceType<typeof Pomodoro> |
| | | const baiduVisible = ref(false) |
| | | const wendaVisible = ref(false) |
| | | const cidianVisible = ref(false) |
| | |
| | | const modelTool = ref(false) |
| | | const shengciVisble = ref(false) |
| | | const calculatorVisble = ref(false) |
| | | const pomodoroRef = ref<pomodoroType>() |
| | | const activeTool = ref(0) |
| | | const toolState = reactive({ |
| | | open: true |
| | | }) |
| | | const resourceUrl = ref('') |
| | | |
| | | const selectTeachTools = (item) => { |
| | | const selectTeachTools = (item: any) => { |
| | | if (token) { |
| | | activeTool.value = item.name |
| | | switch (item.name) { |
| | |
| | | break |
| | | case '计算器': |
| | | calculatorVisble.value = true |
| | | case '番茄闹钟': |
| | | pomodoroRef.value.setDialogVisable(true) |
| | | break |
| | | } |
| | | } else { |
| | |
| | | const openFormulaDialog = () => { |
| | | formulaDialog.value = true |
| | | } |
| | | |
| | | // 番茄钟移动 |
| | | const isMove = ref<boolean>(false) |
| | | const position = reactive({x:100,y:100}) |
| | | const dragOffset = reactive({x:0,y:0}) |
| | | const mouseDown = (e: MouseEvent) => { |
| | | isMove.value = true |
| | | dragOffset.x = e.clientX - position.x |
| | | dragOffset.y = e.clientY - position.y |
| | | document.addEventListener('mousemove', mouseMove) |
| | | document.addEventListener('mouseup', mouseUp) |
| | | } |
| | | const mouseUp = (e: MouseEvent) => { |
| | | isMove.value = false |
| | | document.removeEventListener('mousemove', mouseMove) |
| | | document.removeEventListener('mouseup', mouseUp) |
| | | } |
| | | const mouseMove = (e: MouseEvent) => { |
| | | if (isMove.value) { |
| | | position.x = e.clientX - dragOffset.x |
| | | position.y = e.clientY - dragOffset.y |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | |
| | | z-index: 96; |
| | | background: rgba(255, 255, 255, 0.2); |
| | | } |
| | | .watch-box { |
| | | display: flex; |
| | | align-items: center; |
| | | position: absolute; |
| | | background-color: #555; |
| | | color: #fff; |
| | | padding: 10px; |
| | | border-radius: 5px; |
| | | width: max-content; |
| | | p { |
| | | cursor: move; |
| | | padding: 0 8px; |
| | | font-size: 18px; |
| | | border-radius: 4px; |
| | | margin-right: 10px; |
| | | background-color: #666; |
| | | } |
| | | span { |
| | | cursor: pointer; |
| | | border-right: 1px solid #fff; |
| | | padding: 0 4px; |
| | | font-size: 14px; |
| | | &:last-child { |
| | | border-right: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |