app.json
@@ -57,7 +57,8 @@ "pages/personalCenter/downloads/index", "pages/personalCenter/activateProduct/index", "pages/testLogin/index", "pages/bookServices/examination/examination" "pages/bookServices/examination/examination", "pages/bookServices/webpage/index" ], "tabBar": { "custom": true, pages/bookServices/detail/components/testResource/testResource.js
@@ -12,6 +12,10 @@ bookInfo: { type: Object, value: "", }, mockData: { type: Object, value: {} } }, @@ -19,7 +23,8 @@ * 组件的初始数据 */ data: { selectBtn: 'test', // test mock radioItem: 'test', }, /** @@ -56,7 +61,6 @@ }) } else { const res = await app.MG.store.getProductDetail(query) debugger res.datas.cmsDatas[0].datas.forEach((item) => { idPathList.push({ id: item.id, @@ -79,6 +83,51 @@ wx.navigateTo({ url: `/pages/bookServices/examination/examination?bookId=${this.properties.bookInfo.id}&productLinkPath=${value.productLinkPath}&rootCmsItemId=${this.properties.bookInfo.rootCmsItemId}&idPathList=${JSON.stringify(idPathList)}&answerTitle=${value.name}&answerType=${'option'}`, }) }, goMycollect(e) { const answertype = e.currentTarget.dataset.answertype const token = wx.getStorageSync('jsek-token') if (!token) { return wx.getUserProfile({ desc: '用户登录', success: (res) => { console.log(res); } }) } wx.navigateTo({ url: `/pages/bookServices/examination/examination?bookId=${this.properties.bookInfo.id}&rootCmsItemId=${this.properties.bookInfo.rootCmsItemId}&answerTitle=${'我的收藏'}&answerType=${answertype}`, }) }, // 练习 组件切换 onRadioChange(e) { this.setData({ radioItem: e.detail.value }) }, async getMockId() { let id let query = { start: 0, size: 99, productId: this.properties.bookInfo.id } await app.MG.edu.getQuizConfigListByProduct(query).then((res) => { id = res.datas[0].id }) return id }, // 组卷跳转答题界面 async goMackPaper(e) { // const token = localStorage.getItem('jsek-token') // if (!token) { // return logIn() // } const mockid = await this.getMockId() const item = e.currentTarget.dataset.item wx.navigateTo({ url: `/pages/bookServices/examination/examination?bookId=${this.properties.bookInfo.id}&rootCmsItemId=${this.properties.bookInfo.rootCmsItemId}&answerTitle=${item.name}&answerType=${'mock'}&uuid=${item.id}&mockid=${mockid}`, }) } } }) pages/bookServices/detail/components/testResource/testResource.json
@@ -2,6 +2,8 @@ "component": true, "usingComponents": { "t-button": "tdesign-miniprogram/button/button", "t-image": "tdesign-miniprogram/image/image" "t-image": "tdesign-miniprogram/image/image", "t-radio": "tdesign-miniprogram/radio/radio", "t-radio-group": "tdesign-miniprogram/radio-group/radio-group" } } pages/bookServices/detail/components/testResource/testResource.wxml
@@ -1,39 +1,146 @@ <!--pages/bookServices/detail/components/testResource/testResource.wxml--> <view class="test-resource"> <view class="top-btn"> <t-button class="practice-btn" theme="primary" size="medium" style="width: 85px;"> <t-radio-group class="test-radio" t-class="horizontal-box" value="{{radioItem}}" bind:change="onRadioChange" style="margin: 0px" > <view class="card {{radioItem == 'test' ? 'card--active' : ''}}"> <t-radio value="test" icon="none" borderless style="height: 80rpx"> <view class="radio-content" slot="content"> <t-image src="{{ radioItem == 'test' ? '/static/images/bookService/detail/practice-icon.png' : '/static/images/bookService/detail/notest.png'}}" ></t-image> <text style="color: {{radioItem == 'test' ? '#fff':''}};" >练习</text > </view> </t-radio> </view> <view class="card {{radioItem == 'mock' ? 'card--active' : ''}}"> <t-radio value="mock" icon="none" borderless> <view class="radio-content" slot="content"> <t-image src="{{ radioItem == 'mock' ? '/static/images/bookService/detail/checkpaper.png' : '/static/images/bookService/detail/zujuan.png'}}" ></t-image> <text style="color: {{radioItem == 'mock' ? '#fff':''}};"> 组卷</text > </view> </t-radio> </view> </t-radio-group> <!-- <t-button class=" {{selectBtn == 'test' ? 'practice-btn' : 'paper-btn'}}" theme="default" size="medium" style="width: 85px" bind:tap="changeBtn" data-type="test" > <view slot="content"> <t-image src="/static/images/bookService/detail/practice-icon.png"></t-image> 练习 <t-image src="{{ selectBtn == 'test' ? '/static/images/bookService/detail/practice-icon.png' : '/static/images/bookService/detail/notest.png'}}" ></t-image> <text>练习</text> </view> </t-button> <t-button class="paper-btn" theme="default" size="medium" style="width: 85px;"> <t-button class=" {{selectBtn == 'mock' ? 'practice-btn' : 'paper-btn'}}" theme="default" size="medium" style="width: 85px" bind:tap="changeBtn" data-type="mock" > <view slot="content"> <t-image src="/static/images/bookService/detail/zujuan.png"></t-image> <t-image src="{{ selectBtn == 'mock' ? '/static/images/bookService/detail/checkpaper.png' : '/static/images/bookService/detail/zujuan.png'}}" ></t-image> 组卷 </view> </t-button> <t-button class="error-btn" theme="default" size="medium" style="padding: 0 12rpx;"> </t-button> --> <t-button class="error-btn" theme="default" size="medium" style="padding: 0 12rpx" bind:tap="goMycollect" data-answerType="errorQuestion" > <view slot="content"> <t-image src="/static/images/bookService/detail/cuoti.png"></t-image> 我的错题 </view> </t-button> <t-button class="collect-btn" theme="default" size="medium" style="padding: 0 12rpx;"> <t-button class="collect-btn" theme="default" size="medium" style="padding: 0 12rpx" bind:tap="goMycollect" data-answerType="collectQuestion" > <view slot="content"> <t-image src="/static/images/bookService/detail/wodeshoucang.png"></t-image> <t-image src="/static/images/bookService/detail/wodeshoucang.png" ></t-image> 我的收藏 </view> </t-button> </view> <view class="resource-list" wx:for="{{list}}" wx:key="item.id"> <!-- 练习列表 --> <view class="resource-list" wx:for="{{list}}" wx:key="item.id" wx:if="{{radioItem == 'test'}}" > <view class="list-title"> <t-image src="/static/images/bookService/detail/test-icon.png"></t-image> <text>{{item.name}}</text> </view> <view class="practice" bind:tap="goTest" data-value="{{item}}"> <t-image src="/static/images/bookService/detail/lianxi-icon.png"></t-image> <t-image src="/static/images/bookService/detail/lianxi-icon.png" ></t-image> </view> </view> </view> </view> <!-- 组卷列表 --> <view class="mock-data" wx:if="{{radioItem == 'mock'}}"> <view class="mack-num">已组卷{{mockData.mockList.length}}次</view> <view class="mock-list"> <view class="mock-list-box" wx:for="{{mockData.mockList}}" data-item="{{item}}" bind:tap="goMackPaper" > <view class="mock-title">{{item.name}}</view> <view class="mock-message"> <view class="message-box"> <view class="mack-state"> <text wx:if="{{item.state == '3'}}" class="complete state-pad" >已完成</text > <text wx:elif="{{item.state == '2' || item.state == '1'}}" class="Incomplete state-pad" >未完成</text > <text wx:else class="Incomplete state-pad">未开始</text> </view> <view class="mock-time">{{item.createDate}}</view></view > <view class="mock-score" wx:if="{{item.report.userScore}}" >{{item.report.userScore}}分</view > </view> </view> </view> </view> pages/bookServices/detail/components/testResource/testResource.wxss
@@ -31,6 +31,7 @@ .top-btn { display: flex; justify-content: space-evenly; padding-left: 15rpx; } .top-btn image { @@ -40,17 +41,170 @@ } .practice-btn { --td-button-primary-bg-color: #ff6c00; --td-button-primary-border-color: #ff6c00; --td-button-primary-active-bg-color: #ff984d; --td-button-primary-active-border-color: #ff984d; --td-button-default-bg-color: #ff6c00; --td-button-default-border-color: #ff6c00; --td-button-default-active-bg-color: #ff984d; --td-button-default-active-border-color: #ff984d; } .practice-btn image { margin-top: 25rpx; margin-right: 10rpx; width: 26rpx; height: 30rpx; } .practice-btn text { font-size: 28rpx; } .paper-btn, .error-btn, .collect-btn { --td-button-default-bg-color: #fff; --td-button-default-color: #ff6c00; --td-button-default-color: #0F1214; --td-button-default-active-bg-color: #fff0e6; --td-button-medium-font-size: 28rpx } .card { position: relative; margin: 32rpx; border-radius: 12rpx; overflow: hidden; box-sizing: border-box; border: 3rpx solid #ff6c00; --td-radio-content-color: #0F1214; } .card--active { border-color: #ff6c00; --td-radio-bg-color: #ff6c00; --td-radio-content-color: #fff; } /* .card--active::after { content: ''; display: block; position: absolute; left: 0; top: 0; width: 0; border: 14px solid #0052d9; border-bottom-color: transparent; border-right-color: transparent; } */ .card__icon { color: #fff; position: absolute; left: 1.5px; top: 1.5px; z-index: 1; } /* 横向布局 */ .horizontal-box { width: 350rpx; display: flex; align-items: center; margin: 32rpx; } .horizontal-box .card { flex: 1; margin: 0; } .horizontal-box .card+.card { margin-left: 24rpx; } .test-radio { --td-radio-content-font-size: 28rpx; --td-radio-vertical-padding: 0 } .radio-content { padding: 0 8rpx; display: flex; align-items: center; justify-content: center; width: 100%; height: 68rpx; } .radio-content image { margin: 0 10rpx 10rpx 0; } .mock-data { padding: 0 32rpx; } .mack-num { width: 100%; height: 100rpx; display: flex; align-items: center; color: #333; font-size: 28rpx; } .mock-list-box { padding: 32rpx; background-color: #F9F9F9; margin-bottom: 30rpx; } .mock-title { color: #333; font-size: 32rpx; font-weight: 600; } .mock-message { margin-top: 10rpx; display: flex; justify-content: space-between; } .message-box { height: 60rpx; display: flex; align-items: center; } .mack-state { width: 94rpx; height: 42rpx; } .mock-score { font-size: 28rpx; color: #ff6c00; } .mock-time { color: #333; margin-left: 20rpx; } .state-pad { width: 80rpx; border-radius: 10rpx; display: inline-block; padding: 10rpx; } .complete { background-color: #d8f0d8; color: #1FBC1F; } .Incomplete { background-color: #e9e9e9; color: #666; } pages/bookServices/detail/index.js
@@ -42,7 +42,14 @@ loading: false, isShowTeachDownload: false, // 提示PC下载弹窗状态 confirmBtn: { content: '我知道了', variant: 'base' }, mockData: { id: 0, // 销售id price: 0, // 售价 count: 0, // 组卷已购买次数 useCount: 0, // 组件已使用次数 residue: 0, // 组卷剩余次数 mockList: [] // 用户组卷提交信息 } }, resetTree: function (e) { @@ -71,10 +78,11 @@ }); this.getBookInfo(options.id); this.getResourceClass() // 获取资源所属分类 this.getApplyInfo(options.id) const token = wx.getStorageSync('jsek-token') if (token) { this.getShoppingCartProductGet() this.getApplyInfo(options.id) this.getMockData() } }, @@ -179,6 +187,11 @@ }, // 获取图书详情 getBookInfo(id) { this.setData({ "mockData'.id": 0, "mockData.price": 0, "mockData.count": 0 }) const query = { path: '*', queryType: '*', @@ -214,7 +227,7 @@ }, }; app.MG.store.getProductDetail(query).then(async (res) => { console.log(res.datas); this.setData({ bookDetail: res.datas, cmsDatas: res.datas.cmsDatas[0].datas, @@ -224,6 +237,29 @@ const iconType = JSON.parse(res.datas.bookClassification)[0][0]; const classType = JSON.parse(res.datas.bookClassification)[0][1]; const className = await this.getBookClass(iconType, classType) // 获取组卷销售id if (res.datas.saleMethod && res.datas.saleMethod.length) { res.datas.saleMethod.forEach((item) => { if (item.SaleType == 'combinationTestPaper') { this.setData({ 'mockData.id': item.Id, 'mockData.price': item.Price }) } }) } // 获取组卷已购买次数 if (res.datas.purchasedSaleMethodIdList && res.datas.purchasedSaleMethodIdList.length) { if (this.data.mockData.id) { let count = res.datas.purchasedSaleMethodIdList.filter( (item) => item == this.data.mockData.id ).length this.setData({ 'mockData.count': count }) } } console.log('组卷信息', this.data.mockData); this.setData({ 'bookDetail.publicationDate': this.formatDate(this.data.bookDetail.publicationDate), 'bookDetail.class': className, @@ -232,6 +268,7 @@ 'bookDetail.paperPrice': this.numFormat(this.data.bookDetail.paperPrice), }); }); }, // 获取图书分类 async getBookClass(iconType, classType) { @@ -298,8 +335,8 @@ goShop(e) { const { link } = e.currentTarget.dataset; wx.navigateTo({ url: link, }); url: `/pages/bookServices/webpage/index?url=${link}`, }) }, onTabsChange(e) { this.setData({ @@ -1014,5 +1051,69 @@ handleTrue() { // findAndUpdateItemsByIds(this.date.) }, // 组卷格式化日期显示 DateFormat(date, fmt) { if (date && fmt) { let _date = new Date(date) var o = { 'M+': _date.getMonth() + 1, //月份 'd+': _date.getDate(), //日 'h+': _date.getHours(), //小时 'm+': _date.getMinutes(), //分 's+': _date.getSeconds(), //秒 'q+': Math.floor((_date.getMonth() + 3) / 3), //季度 S: _date.getMilliseconds() //毫秒 } if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (_date.getFullYear() + '').substr(4 - RegExp.$1.length)) } for (var k in o) { if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace( RegExp.$1, RegExp.$1.length == 1 ? (o)[k] : ('00' + (o)[k]).substr(('' + (o)[k]).length) ) } } return fmt } else { return '' } }, // 获取组卷答题数据 getMockData() { this.setData({ 'mockData.useCount': 0, 'mockData.mockList': [] }) app.MG.identity .getUserKey({ domain: 'mockData', keys: [this.data.bookId] }) .then((res) => { console.log(JSON.parse(res[0].value)); if (res && res.length) { const mock = JSON.parse(res[0].value) mock.forEach(item => { item.createDate = this.DateFormat(item.createDate, 'yyyy-MM-dd') }) this.setData({ 'mockData.mockList': mock }) // 组卷已使用次数 res.forEach((item) => { // 已经有答题分数等数据,证明组卷已经使用完毕 if (item.resultData) { this.setData({ 'mockData.useCount': this.data.mockData.useCount + 1 }) } }) } }) } }) pages/bookServices/detail/index.wxml
@@ -84,7 +84,7 @@ </view> <!-- 网店 --> <view class="book-web"> <t-image src="/static/images/bookService/detail/jd.png" wx:if="{{bookDetail.JDLink}}" bind:tap="goShop" data-link="{{bookDetail.tmallLink}}" data-type="jd"></t-image> <t-image src="/static/images/bookService/detail/jd.png" wx:if="{{bookDetail.JDLink}}" bind:tap="goShop" data-link="{{bookDetail.JDLink}}" data-type="jd"></t-image> <t-image src="/static/images/bookService/detail/tmall.png" width="32" height="22" bind:tap="goShop" data-link="{{bookDetail.tmallLink}}" wx:if="{{bookDetail.tmallLink}}"></t-image> <t-image src="/static/images/bookService/detail/dangdang.png" bind:tap="goShop" data-link="{{bookDetail.dangdangLink}}" wx:if="{{bookDetail.dangdangLink}}"></t-image> <t-image src="/static/images/bookService/detail/jd.png" bind:tap="goShop" data-link="{{bookDetail.weidianLink}}" wx:if="{{bookDetail.weidianLink}}"></t-image> @@ -114,7 +114,7 @@ </t-tab-panel> <t-tab-panel label="云测试" value="questionBank" style="{{tabPanelstyle}}"> <view wx:if="{{!loading && test.length}}"> <test-resource list="{{test}}" bookInfo="{{bookDetail}}"></test-resource> <test-resource list="{{test}}" bookInfo="{{bookDetail}}" mockData="{{mockData}}"></test-resource> </view> </t-tab-panel> <t-tab-panel label="云笔记" value="jesk_note" style="{{tabPanelstyle}}"> pages/bookServices/examination/examination.js
@@ -1,3 +1,4 @@ import { getPublicImage } from '../../../assets/js/middleGround/tool' const app = getApp() Page({ @@ -9,20 +10,25 @@ navBarHeight: "", loading: false, answerTitle: "", // 导航栏标题 countdownInterval: null, // 计时器 isCountdownRunning: true, // 是否倒计时 countdownTime: 0, // 倒计时时间 bookId: "", productLinkPath: "", rootCmsItemId: "", idPathList: [], // 题目列表 answerType: "", // 答题类型 answerType: "", // 答题模式 submitStatus: false, // 提交状态 currentIndex: 0, // 当前答题数 currentIndex: 0, // 当前显示的题号 collectList: [], // 收藏题目列表 subjectiveNum: 0, // 主观题得分 subjectiveGrade: 0, // 主观题总分 total: 0, // 题目总数 errorList: [], // 错题列表 subjectiveTotal: 0, // 客观题总数 subjectiveNum: 0, // 客观题得分 subjectiveGrade: 0, // 客观题总分 correctNum: 0, // 正确题目数量 total: 0, // 题目总数 cardList: [], // 提交项, questionDataList: [] questionDataList: [], // 显示题目列表 }, /** @@ -37,12 +43,13 @@ navBarHeight: navBarHeight, answerTitle: options.answerTitle, bookId: options.bookId, productLinkPath: options.productLinkPath, productLinkPath: options.productLinkPath ? options.productLinkPath : '', rootCmsItemId: options.rootCmsItemId, idPathList: JSON.parse(options.idPathList), idPathList: options.idPathList ? JSON.parse(options.idPathList) : [], answerType: options.answerType }); this.init() console.log('传参', options); }, /** @@ -70,7 +77,9 @@ * 生命周期函数--监听页面卸载 */ onUnload() { if (this.data.countdownInterval !== null) { clearInterval(this.data.countdownInterval) } }, /** @@ -96,12 +105,243 @@ goBack() { wx.navigateBack(); }, // 获取保存的倒计时时间 getSavedTime() { const savedTime = wx.getStorageSync('countdownTime') return savedTime ? parseInt(savedTime) : null }, // 保存倒计时时间到本地存储 saveTime() { wx.setStorageSync('countdownTime', this.data.countdownTime.toString()) }, clearTime() { this.setData({ countdownTime: 2 * 60 * 60 * 1000 }) }, // 暂停或继续倒计时 toggleCountdown() { if (this.data.countdownInterval) { clearInterval(this.data.countdownInterval) this.setData({ countdownInterval: null, isCountdownRunning: false }) } else { this.startCountdown() this.setData({ isCountdownRunning: true }) } }, // 开始倒计时 startCountdown() { // 如果计时器已经存在,先清除之前的计时器 if (this.data.countdownInterval) { clearInterval(this.data.countdownInterval) this.setData({ countdownInterval: null }) } this.setData({ countdownInterval: setInterval(() => { this.setData({ countdownTime: this.data.countdownTime - 1000 }) if (this.data.countdownTime <= 0) { clearInterval(this.data.countdownInterval) this.setData({ countdownTime: 0, isCountdownRunning: false }) } this.saveTime() }, 1000) }) }, // 切换题目 changeSwiper(e) { this.setData({ currentIndex: e.detail.index }) let index = e.detail.index - 1 >= 0 ? e.detail.index - 1 : 0 let flag = this.isHaveAnswer(this.data.questionDataList[index].userAnswer) if (flag) this.handleQuestion(e.detail.index) }, // 点击答题卡跳转题目 goQuestion(e) { console.log(e); const id = e.detail.id this.data.questionDataList.forEach((item, index) => { if (item.id == id) { this.setData({ currentIndex: index }) } }) }, // 单选 多选 触发 onChangeRadio(e) { const radioData = e.detail.value.currentTarget.dataset.value const id = e.detail.value.currentTarget.dataset.id const radioChecked = e.detail.value.detail.value const questionList = this.data.questionDataList questionList.forEach(item => { if (item.id == id) { item.userAnswer = radioChecked } }) this.setData({ questionDataList: questionList }) console.log(this.data.questionDataList); }, // 输入框触发 onChangeInput(e) { const inputData = e.detail.value.detail.value const id = e.detail.value.currentTarget.dataset.id const index = e.detail.value.currentTarget.dataset.index const questionList = this.data.questionDataList questionList.forEach(item => { if (item.id == id) { item.userAnswer[index] = inputData } }) this.setData({ questionDataList: questionList }) console.log(this.data.questionDataList); }, // 数组转为字符串方法 arrayToString(data) { // 检查是否为数组 if (Array.isArray(data)) { // 使用 join 方法将数组转换为字符串,默认使用逗号分隔 return data.join(',').replace(/<[^>]*>/g, '') } else { // 如果不是数组,直接返回原始值 return data.replace(/<[^>]*>/g, '') } }, // 判断是否有用户答案 isHaveAnswer(data) { if (typeof data == 'string') { data = data .replace(/<[^>]*>/g, '') .replace(/ /g, '') .trim() if (data.length) { return true } else { return false } } else { const answer = data.find((item) => item.length > 0) if (answer) { return true } else { return false } } }, // 提交逻辑 submitPaper() { this.setData({ submitStatus: true }) if (this.data.answerType == 'option') { this.toggleCountdown() const child = this.selectComponent('#question-options') if (this.data.answerType == 'option' || this.data.answerType == 'errorQuestion') { // 先遍历所有题目,将未批改的题目批改 const qustionList = this.data.questionDataList for (let index = 0; index < qustionList.length; index++) { const item = qustionList[index]; if (!item.isComplete) this.handleQuestion(index + 1) } } if (this.data.answerType == 'option') { this.recordAnswerData() child.openTestReportDialog() } } else if (this.data.answerType == 'collectQuestion' || this.data.answerType == 'errorQuestion') { this.goBack() } }, // 初始化函数 async init() { this.setData({ loading: true, subjectiveTotal: 0, subjectiveNum: 0, subjectiveGrade: 0 }) if (this.data.answerType == 'option') { if (this.data) this.startCountdown() this.setData({ countdownTime: 2 * 60 * 60 * 1000 }) // 测试答题 await this.getCollectIdList() // 获取收藏id列表 // await getErrorList() // 获取错题id列表 await this.getErrorList() // 获取错题id列表 } else if (this.data.answerType == 'collectQuestion') { // 我的收藏 await this.getcollectId() // 获取收藏题目 } else if (this.data.answerType == 'errorQuestion') { // 我的错题 // loadings.value = true await this.getErrorIdList() await this.getCollectIdList() // 获取收藏id列表 } }, async restart() { const countDownRef = this.selectComponent('#countDownRef') this.setData({ loading: true, total: 0, subjectiveGrade: 0, subjectiveTotal: 0, subjectiveNum: 0, currentIndex: 0, submitStatus: false }) if (this.data.answerType == 'option') { this.setData({ countdownTime: 2 * 60 * 60 * 1000 }) this.delAnswerInfo(() => { this.getQuestionList() this.clearTime() }) if (!this.data.submitStatus) { this.startCountdown() } } else if (this.data.answerType == 'mock') { // 组卷模式 // 清空答题记录 await app.MG.identity.setUserKey({ setKeyRequests: [ { domain: 'mockAnswerData', key: route.query.uuid, value: JSON.stringify({ time: countDownRef.value.countdownTime, answerData: [] }) } ] }) this.init() } else { this.init() this.clearTime() if (submitStatus.value) { this.startCountdown() } } }, // 获取收藏题目列表id @@ -111,7 +351,7 @@ domain: 'collectData', keys: [this.data.rootCmsItemId] }) .then(async (res) => { .then((res) => { try { this.setData({ collectList: JSON.parse(res[0].value) @@ -120,16 +360,18 @@ } if (this.data.answerType == 'option') { // 先获取用户答题记录 await this.getAnswerInfo((res) => { this.getAnswerInfo(async (res) => { if (res.length) { // 有记录,不能答题,状态设为已提交 this.setData({ submitStatus: true }) let value = JSON.parse(res[0].value) // console.log('答题记录', JSON.parse(res[0].value)) // 有答题记录,得分赋值 if (value) { this.setData({ submitStatus: true }) value.dataList.forEach((item) => { if (item.name == '客观题得分' && item.path == this.data.productLinkPath) this.setData({ @@ -141,11 +383,28 @@ currentIndex: value.currentIndex }) // 携带答题记录 获取题目 this.getQuestionList(value.dataList) await this.getQuestionList(value.dataList) } else { this.getQuestionList() // 获取题库题目 await this.getQuestionList() // 获取题库题目 } }) } }) }, // 获取错题id列表 getErrorList() { app.MG.identity .getUserKey({ domain: 'errorData', keys: [this.data.rootCmsItemId] }) .then((res) => { try { this.setData({ errorList: JSON.parse(res[0].value) }) } catch (error) { } }) }, @@ -153,22 +412,21 @@ getQuestionList(oldData) { // 清空正确题数记录 this.setData({ correctNum: 0 cardList: [], correctNum: 0, }) let flag = 0 this.data.idPathList.forEach((pathitem) => { const pathList = this.data.cardList pathList.push({ name: pathitem.name, path: pathitem.productLinkPath, catalogName: pathitem.type, catalogName: pathitem.name, infoList: [] }) this.setData({ cardList: pathList }) // 获取题目 let questionArr = [] let query = { path: '*', queryType: '*', @@ -210,6 +468,7 @@ let questionObj = { // num: index, // 题号 id: item.id, type: pathitem.name, stem: item.Embedded_QuestionBank_QuestionType == 'completion' ? JSON.parse(item.Embedded_QuestionBank_Stem) @@ -249,6 +508,8 @@ questionObj.answer = item.Embedded_QuestionBank_Answer } } // questionObj.userAnswer = this.arrayToString(questionObj.userAnswer) // questionObj.isHaveAnswer = this.isHaveAnswer(questionObj.userAnswer) // 填空题改造 if (questionObj.questionType == 'completion') { let index = 0 @@ -264,7 +525,20 @@ } } } questionArr.push(questionObj) // 获取图片 if (questionObj.stemStyle == 'Image' || questionObj.stemStyle == 'TxtAndImage') { questionObj.stem.stemImage = getPublicImage(questionObj.stem.stemImage, 150) } if (questionObj.optionStyle == 'Image' || questionObj.optionStyle == 'TxtAndImage') { questionObj.option.forEach(optionItem => { if (optionItem.img) optionItem.img = getPublicImage(optionItem.img, 150) }) } // if (questionObj.optionStyle == 'RichText') { // questionObj.option.forEach(optionItem => { // optionItem.txt.replace(/<img>/g, "<img class='imgClass'>") // }) // } // 旧数据里 题目已经作答,修改已答题目数量 // if (oldObj && oldObj.userAnswer.length > 0) countDownRef.value.changeAlready() // 旧数据里 题目正确 记录正确数量 @@ -273,57 +547,240 @@ correctNum: this.data.correctNum + 1 }) } // if (pathitem.name == '判断题') { // topicList.value.judge.data = questionArr // topicList.value.judge.path = pathitem.productLinkPath // if (oldData) subjectiveTotal.value += 1 // 有旧数据,计算主观题数 // } else if (pathitem.name == '填空题') { // topicList.value.gap.data = questionArr // topicList.value.gap.path = pathitem.productLinkPath // if (oldData) subjectiveTotal.value += 1 // } else if (pathitem.name == '多选题') { // topicList.value.check.data = questionArr // topicList.value.check.path = pathitem.productLinkPath // if (oldData) subjectiveTotal.value += 1 // } else if (pathitem.name == '单选题') { // topicList.value.radio.data = questionArr // topicList.value.radio.path = pathitem.productLinkPath // if (oldData) subjectiveTotal.value += 1 // } else if (pathitem.name == '简答题') { // topicList.value.short.data = questionArr // topicList.value.short.path = pathitem.productLinkPath // } else if (pathitem.name == '翻译题') { // topicList.value.translate.data = questionArr // topicList.value.translate.path = pathitem.productLinkPath // } else if (pathitem.name == '听力题') { // topicList.value.listen.data = questionArr // topicList.value.listen.path = pathitem.productLinkPath // if (oldData) subjectiveTotal.value += 1 // } let infoList = this.data.cardList[this.data.cardList.findIndex((item) => item.path == pathitem.productLinkPath)] .infoList if (pathitem.name == '判断题' || pathitem.name == '填空题' || pathitem.name == '多选题' || pathitem.name == '单选题' || pathitem.name == '听力题') { if (oldObj) { this.setData({ subjectiveTotal: this.data.subjectiveTotal + 1 }) } } // cardList赋值 let cardIndex = this.data.cardList.findIndex((item) => item.path == pathitem.productLinkPath) let infoList = this.data.cardList[cardIndex].infoList infoList.push(questionObj) this.setData({ [`cardList[${cardIndex}].infoList`]: infoList }) // this.data.cardList[this.data.cardList.findIndex((item) => item.path == pathitem.productLinkPath)] // .infoList // infoList.push(questionObj) flag++; let questionList = [] const cardUpdatedList = this.data.cardList // if (flag == this.data.idPathList.length) { this.data.cardList.forEach(aitem => { aitem.infoList.forEach(bitem => { cardUpdatedList.forEach(aitem => { aitem.infoList.forEach((bitem, bindex) => { questionList.push(bitem) bitem.number = questionList.length bitem.number = bindex + 1 bitem.grade = 2 }) }) this.setData({ questionDataList: questionList questionDataList: questionList, cardList: cardUpdatedList }) // } }) }) }) this.setData({ loading: false, }) console.log('题目列表', this.data.questionDataList, this.data.cardList); }, // 批改题目 (练习,我的错题,我的收藏) handleQuestion(num) { const questionList = this.data.questionDataList const index = num - 1 >= 0 ? num - 1 : 0 if (questionList[index].isComplete) { // 题目已完成,跳过 return true } questionList[index].isComplete = true const item = questionList[index] // 批改题目 if (item.questionType == 'multipleChoice') { // 多选题 // subjectiveGrade.value += item.score if (item.answer.length == item.userAnswer.length) { const sortedArr1 = item.answer.slice().sort() const sortedArr2 = item.userAnswer.slice().sort() questionList[index].isRight = sortedArr1.every( (value, valueIndex) => value === sortedArr2[valueIndex] ) } else { questionList[index].isRight = false } } else if (item.questionType == 'singleChoice' || item.questionType == 'judge') { // 单选 判断 // subjectiveGrade.value += item.score questionList[index].isRight = item.answer == item.userAnswer } else if (item.questionType == 'shortAnswer') { // 简答 翻译 questionList[index].isRight = null } else if (item.questionType == 'completion') { // 填空 // subjectiveGrade.value += item.score if (typeof item.answer == 'string') { questionList[index].isRight = item.answer == item.userAnswer[0] } else { if (item.answer.length != item.userAnswer.length) { questionList[index].isRight = false } else { questionList[index].isRight = item.answer.every( (value, valueIndex) => value === item.userAnswer[valueIndex] ) } } } if (item.questionType != 'shortAnswer') { this.setData({ subjectiveTotal: this.data.subjectiveTotal + 1, subjectiveGrade: this.data.subjectiveGrade + item.grade }) } if (questionList[index].isRight && item.questionType != 'shortAnswer') { // 客观题回答正确 this.setData({ subjectiveNum: this.data.subjectiveNum + item.grade, correctNum: this.data.correctNum + 1 }) } if (!questionList[index].isRight && item.questionType != 'shortAnswer') { // 客观题回答错误 记录错题 if (this.data.errorList.findIndex((errorItem) => errorItem == item.id) == -1) { this.data.errorList.push(item.id) } } else { if (this.data.answerType == 'errorQuestion' || this.data.answerType == 'option') { // 从错题集中移除 let errorIndex = this.data.errorList.findIndex((erroritem) => erroritem == item.id) if (errorIndex > -1) { this.data.errorList.splice(errorIndex, 1) } } } if (this.data.answerType != 'collectQuestion') { // 记录错题 app.MG.identity .setUserKey({ setKeyRequests: [ { domain: 'errorData', key: this.data.rootCmsItemId, value: JSON.stringify(this.data.errorList) } ] }) .then((res) => { console.log(res) }) } this.setData({ questionDataList: questionList }) const cardUpdatedList = this.data.cardList cardUpdatedList.forEach((item) => { item.infoList.forEach((citem) => { if (citem.id == questionList[index].id) { citem = questionList[index]; } }); }); this.setData({ cardList: cardUpdatedList }) // console.log(this.data.questionDataList, this.data.cardList); }, // 题目收藏按钮,收藏和取消同一接口,取消数组减去该项id setCollect() { const citem = this.data.questionDataList[this.data.currentIndex] const questionList = this.data.questionDataList for (let index = 0; index < questionList.length; index++) { const item = questionList[index]; if (item.id == citem.id) { item.isCollect = !item.isCollect } } this.setData({ questionDataList: questionList }) if (this.data.collectList.length == 0) { this.setData({ collectList: [citem.id] }) } else { const collectItme = this.data.collectList.filter((item) => item == citem.id) if (collectItme.length) { const arr = this.data.collectList.filter((item) => item != citem.id) this.setData({ collectList: arr }) } else { const collectArr = this.data.collectList collectArr.push(citem.id) this.setData({ collectList: collectArr }) } } app.MG.identity .setUserKey({ setKeyRequests: [ { domain: 'collectData', key: this.data.rootCmsItemId, value: JSON.stringify(this.data.collectList) } ] }) .then((res) => { }) }, // 处理答题数据 recordAnswerData() { this.data.cardList.push( { name: '客观题得分', score: this.data.subjectiveNum, path: this.data.productLinkPath, // infoList: [], // catalogName: '' } ) let setInfoData = { currentIndex: this.data.currentIndex, dataList: JSON.parse(JSON.stringify(this.data.cardList)) } for (let i = 0; i < setInfoData.dataList.length; i++) { const item = setInfoData.dataList[i] if (!item.name && !item.name == '客观题得分') { for (let j = 0; j < item.infoList.length; j++) { let obj = { id: item.infoList[j].id, userAnswer: item.infoList[j].userAnswer, isComplete: item.infoList[j].isComplete, isRight: item.infoList[j].isRight, isCollect: item.infoList[j].isCollect } item.infoList[j] = obj } } } this.setAnswerInfo(setInfoData) }, // 提交答题数据 setAnswerInfo(data) { app.MG.identity .setUserKey({ setKeyRequests: [ { domain: 'answerData', key: this.data.productLinkPath, value: JSON.stringify(data) } ] }) .then((res) => { }) }, // 获取答题数据 getAnswerInfo(callback) { @@ -335,5 +792,332 @@ .then((res) => { if (callback) callback(res) }) }, // 删除答题数据 delAnswerInfo(callback) { app.MG.identity .delUserKey({ domain: 'answerData', keys: [this.data.productLinkPath] }) .then((res) => { if (callback) callback() }) }, // 我的收藏模式下获取收藏题目id async getcollectId() { app.MG.identity .getUserKey({ domain: 'collectData', keys: [this.data.rootCmsItemId] }) .then(async (res) => { try { this.setData({ collectList: JSON.parse(res[0].value) }) // total.value = collectList.value.length } catch (error) { } if (this.data.collectList && this.data.collectList.length) { await this.getCollectDataList() } else { this.setData({ loading: false }) wx.showModal({ title: '提示', content: '收藏夹暂无数据',//editable如果为true,这就是输入框的内容 editable: false,//是否显示输入框 showCancel: false, success: (res) => { if (res.confirm) { this.setData({ submitStatus: true }) this.goBack() } } }) } // console.log('收藏', collectList.value) }) }, // 获取收藏夹 async getCollectDataList() { let questionArr = [] this.setData({ cardList: [ { catalogName: '收藏夹', infoList: [] } ] }) let query = { path: '*', cmsPath: this.data.rootCmsItemId, cmsType: '*', productId: this.data.bookId, queryType: '*', itemIds: this.data.collectList.map((item) => item + ''), itemFields: { Embedded_QuestionBank_Stem: [], Embedded_QuestionBank_AnalysisCon: [], Embedded_QuestionBank_Answer: [], Embedded_QuestionBank_Option: [], Embedded_QuestionBank_QuestionType: [], Embedded_QuestionBank_StemStyle: [], Embedded_QuestionBank_OptionStyle: [], Embedded_QuestionBank_KnowledgePoint: [], Embedded_QuestionBank_Difficulty: [] } } app.MG.store.getProductDetail(query).then((res) => { let questionArr = [] res.datas.cmsDatas[0].datas.forEach((item, index) => { const questionObj = { number: index + 1, // 题号 id: item.id, stem: item.Embedded_QuestionBank_QuestionType == 'completion' ? JSON.parse(item.Embedded_QuestionBank_Stem) .stemTxt.replaceAll('<vacancy>', ',input,') .split(',') : JSON.parse(item.Embedded_QuestionBank_Stem), // 题干 answer: item.Embedded_QuestionBank_Answer, // 答案 option: item.Embedded_QuestionBank_Option ? JSON.parse(item.Embedded_QuestionBank_Option) : '', // 选择题选项 analysisCon: item.Embedded_QuestionBank_AnalysisCon, // 解析 questionType: item.Embedded_QuestionBank_QuestionType, // 题型 optionStyle: item.Embedded_QuestionBank_OptionStyle, // 选项显示类型 stemStyle: item.Embedded_QuestionBank_StemStyle, // 题干显示类型 difficulty: item.Embedded_QuestionBank_Difficulty ? 4 - item.Embedded_QuestionBank_Difficulty : 0, // 难度等级 userAnswer: item.Embedded_QuestionBank_QuestionType == 'completion' || item.Embedded_QuestionBank_QuestionType == 'multipleChoice' ? [] : '', isSubmit: false, // 查看解析 isRight: null, // 是否正确 isComplete: false, isCollect: true } // 多选和填空答案肯为数组,要转换JSON格式 if ( questionObj.questionType == 'completion' || questionObj.questionType == 'multipleChoice' ) { try { questionObj.answer = JSON.parse(questionObj.answer) } catch (error) { // } } // 填空题改造 if (questionObj.questionType == 'completion') { let index = 0 for (let i = 0; i < questionObj.stem.length; i++) { const item = questionObj.stem[i] if (item == 'input') { questionObj.stem[i] = { num: index, data: 'input' } questionObj.userAnswer[index] = '' index++ } } } // 获取图片 if (questionObj.stemStyle == 'Image' || questionObj.stemStyle == 'TxtAndImage') { questionObj.stem.stemImage = getPublicImage(questionObj.stem.stemImage, 150) } if (questionObj.optionStyle == 'Image' || questionObj.optionStyle == 'TxtAndImage') { questionObj.option.forEach(optionItem => { if (optionItem.img) optionItem.img = getPublicImage(optionItem.img, 150) }) } // if (item.Embedded_QuestionBank_QuestionType == 'judge') { // topicList.value.judge.data.push(questionObj) // } else if (item.Embedded_QuestionBank_QuestionType == 'singleChoice') { // topicList.value.radio.data.push(questionObj) // } else if (item.Embedded_QuestionBank_QuestionType == 'multipleChoice') { // topicList.value.check.data.push(questionObj) // } else if (item.Embedded_QuestionBank_QuestionType == 'completion') { // topicList.value.gap.data.push(questionObj) // } else if (item.Embedded_QuestionBank_QuestionType == 'shortAnswer') { // topicList.value.short.data.push(questionObj) // } questionArr.push(questionObj) // cardList.value[0].infoList.push(questionObj) }) // loadings.value = false this.setData({ questionDataList: questionArr, ['cardList[0].infoList']: questionArr, loading: false, }) }) }, // 我的错题模式下获取错题id列表 async getErrorIdList() { await app.MG.identity .getUserKey({ domain: 'errorData', keys: [this.data.rootCmsItemId] }) .then((res) => { try { this.setData({ errorList: JSON.parse(res[0].value) }) } catch (error) { } if (this.data.errorList && this.data.errorList.length) { this.getErrorDataList() } else { this.setData({ loading: true }) wx.showModal({ title: '提示', content: '错题集暂无数据',//editable如果为true,这就是输入框的内容 editable: false,//是否显示输入框 showCancel: false, success: (res) => { if (res.confirm) { this.setData({ submitStatus: true }) this.goBack() } } }) } }) }, // 获取错题集 async getErrorDataList() { this.setData({ cardList: [ { catalogName: '错题集', infoList: [] } ] }) let query = { path: '*', cmsPath: this.data.rootCmsItemId, cmsType: '*', productId: this.data.bookId, queryType: '*', itemIds: this.data.errorList.map((item) => item + ''), itemFields: { Embedded_QuestionBank_Stem: [], Embedded_QuestionBank_AnalysisCon: [], Embedded_QuestionBank_Answer: [], Embedded_QuestionBank_Option: [], Embedded_QuestionBank_QuestionType: [], Embedded_QuestionBank_StemStyle: [], Embedded_QuestionBank_OptionStyle: [], Embedded_QuestionBank_KnowledgePoint: [], Embedded_QuestionBank_Difficulty: [] } } await app.MG.store.getProductDetail(query).then((res) => { let questionArr = [] res.datas.cmsDatas[0].datas.forEach((item, index) => { const questionObj = { number: index + 1, // 题号 id: item.id, stem: item.Embedded_QuestionBank_QuestionType == 'completion' ? JSON.parse(item.Embedded_QuestionBank_Stem) .stemTxt.replaceAll('<vacancy>', ',input,') .split(',') : JSON.parse(item.Embedded_QuestionBank_Stem), // 题干 answer: item.Embedded_QuestionBank_Answer, // 答案 option: item.Embedded_QuestionBank_Option ? JSON.parse(item.Embedded_QuestionBank_Option) : '', // 选择题选项 analysisCon: item.Embedded_QuestionBank_AnalysisCon, // 解析 questionType: item.Embedded_QuestionBank_QuestionType, // 题型 optionStyle: item.Embedded_QuestionBank_OptionStyle, // 选项显示类型 stemStyle: item.Embedded_QuestionBank_StemStyle, // 题干显示类型 difficulty: item.Embedded_QuestionBank_Difficulty ? 4 - item.Embedded_QuestionBank_Difficulty : 0, // 难度等级 userAnswer: item.Embedded_QuestionBank_QuestionType == 'completion' || item.Embedded_QuestionBank_QuestionType == 'multipleChoice' ? [] : '', isSubmit: false, // 查看解析 isRight: null, // 是否正确 isComplete: false, isCollect: this.data.collectList.some((collectItem) => collectItem == item.id) } // 多选和填空答案肯为数组,要转换JSON格式 if ( questionObj.questionType == 'completion' || questionObj.questionType == 'multipleChoice' ) { try { questionObj.answer = JSON.parse(questionObj.answer) } catch (error) { // } } // 填空题改造 if (questionObj.questionType == 'completion') { let index = 0 for (let i = 0; i < questionObj.stem.length; i++) { const item = questionObj.stem[i] if (item == 'input') { questionObj.stem[i] = { num: index, data: 'input' } questionObj.userAnswer[index] = '' index++ } } } // 获取图片 if (questionObj.stemStyle == 'Image' || questionObj.stemStyle == 'TxtAndImage') { questionObj.stem.stemImage = getPublicImage(questionObj.stem.stemImage, 150) } if (questionObj.optionStyle == 'Image' || questionObj.optionStyle == 'TxtAndImage') { questionObj.option.forEach(optionItem => { if (optionItem.img) optionItem.img = getPublicImage(optionItem.img, 150) }) } // if (item.Embedded_QuestionBank_QuestionType == 'judge') { // topicList.value.judge.data.push(questionObj) // } else if (item.Embedded_QuestionBank_QuestionType == 'singleChoice') { // topicList.value.radio.data.push(questionObj) // } else if (item.Embedded_QuestionBank_QuestionType == 'multipleChoice') { // topicList.value.check.data.push(questionObj) // } else if (item.Embedded_QuestionBank_QuestionType == 'completion') { // topicList.value.gap.data.push(questionObj) // } else if (item.Embedded_QuestionBank_QuestionType == 'shortAnswer') { // topicList.value.short.data.push(questionObj) // } questionArr.push(questionObj) }) this.setData({ questionDataList: questionArr, ['cardList[0].infoList']: questionArr, loading: false }) }) // loadings.value = false // console.log('错题集', topicList.value) } }) pages/bookServices/examination/examination.json
@@ -5,7 +5,8 @@ "question-list": "/pages/bookServices/examination/questionList/index", "t-icon": "tdesign-miniprogram/icon/icon", "t-image": "tdesign-miniprogram/image/image", "t-button": "tdesign-miniprogram/button/button" "t-button": "tdesign-miniprogram/button/button", "t-loading": "tdesign-miniprogram/loading/loading" }, "navigationStyle": "custom" } pages/bookServices/examination/examination.wxml
@@ -12,13 +12,62 @@ </view> <view class="navbar-title">{{answerTitle}}</view> </view> <!-- <view class="lodaing-box" wx:if="{{loaidng}}"> <t-loading theme="circular" size="80rpx" class="wrapper" loading="{{loading}}" /> </view> --> <view class="page-content"> <question-schedule></question-schedule> <question-list questionList="{{questionDataList}}"></question-list> <question-schedule wx:if="{{!loading}}" id="countDownRef" answerType="{{answerType}}" countdownTime="{{countdownTime}}" currentIndex="{{currentIndex}}" questionList="{{questionDataList}}" submitStatus="{{submitStatus}}" ></question-schedule> <question-list wx:if="{{!loading}}" currentIndex="{{currentIndex}}" questionList="{{questionDataList}}" submitStatus="{{submitStatus}}" bind:onChangeRadio="onChangeRadio" bind:onChangeInput="onChangeInput" bind:changeSwiper="changeSwiper" ></question-list> <view class="lodaing-box"> <t-loading theme="circular" size="80rpx" class="wrapper" loading="{{loading}}" /></view> </view> <!-- 底部区域--> <view class="page-bottom"> <question-options></question-options> <question-options id="question-options" submitStatus="{{submitStatus}}" answerType="{{answerType}}" countdownTime="{{countdownTime}}" currentIndex="{{currentIndex}}" questionDataList="{{questionDataList}}" cardList="{{cardList}}" subjectiveTotal="{{subjectiveTotal}}" subjectiveNum="{{subjectiveNum}}" subjectiveGrade="{{subjectiveGrade}}" correctNum="{{correctNum}}" bind:setCollect="setCollect" bind:submitPaper="submitPaper" bind:restart="restart" bind:goQuestion="goQuestion" ></question-options> </view> pages/bookServices/examination/examination.wxss
@@ -14,6 +14,14 @@ font-weight: 600; } .lodaing-box { display: flex; align-items: center; justify-content: center; height: 100%; --td-loading-color: #ff6c00; } .page-content { box-sizing: border-box; width: 100%; pages/bookServices/examination/questionList/index.js
@@ -1,14 +1,4 @@ // pages/bookServices/examination/questionList/index.js const imageCdn = 'https://tdesign.gtimg.com/mobile/demos'; const swiperList = [ `${imageCdn}/swiper1.png`, `${imageCdn}/swiper2.png`, `${imageCdn}/swiper1.png`, `${imageCdn}/swiper2.png`, `${imageCdn}/swiper1.png`, ]; Component({ /** * 组件的属性列表 @@ -17,28 +7,85 @@ questionList: { type: Array, value: [] }, submitStatus: { type: Boolean, value: false }, currentIndex: { type: Number, value: 1 } }, created() { console.log('组件传参', this.properties); // console.log('组件传参', this.properties); }, /** * 组件的初始数据 */ data: { inputstyle: 'border: 2rpx solid rgba(220,220,220,1);border-radius: 12rpx;', placeholderstyle: "font-size:28rpx", current: 2, autoplay: true, duration: 500, interval: 5000, paginationPosition: 'bottom-right', swiperList, navigation: { type: 'fraction' }, showIndex: 0, }, /** * 组件的方法列表 */ methods: { // 切换题目 changeSwiper(e) { console.log(e); this.setData({ showIndex: e.detail.current }) var myEventDetail = { index: e.detail.current } // detail对象,提供给事件监听函数 var myEventOption = { bubbles: true, composed: true, } // 触发事件的选项 this.triggerEvent('changeSwiper', myEventDetail, myEventOption) }, // 单选 富文本框输入 触发 onChangeRadio(e) { var myEventDetail = { value: e } // detail对象,提供给事件监听函数 var myEventOption = { bubbles: true, composed: true, } // 触发事件的选项 this.triggerEvent('onChangeRadio', myEventDetail, myEventOption) }, // 多选触发 onChangeCheck(e) { var myEventDetail = { value: e } // detail对象,提供给事件监听函数 var myEventOption = { bubbles: true, composed: true, } // 触发事件的选项 this.triggerEvent('onChangeRadio', myEventDetail, myEventOption) }, // 输入框触发 onChangeInput(e) { var myEventDetail = { value: e } // detail对象,提供给事件监听函数 var myEventOption = { bubbles: true, composed: true, } // 触发事件的选项 this.triggerEvent('onChangeInput', myEventDetail, myEventOption) }, } }) pages/bookServices/examination/questionList/index.json
@@ -2,6 +2,13 @@ "component": true, "usingComponents": { "t-swiper": "tdesign-miniprogram/swiper/swiper", "t-swiper-nav": "tdesign-miniprogram/swiper-nav/swiper-nav" "t-swiper-nav": "tdesign-miniprogram/swiper-nav/swiper-nav", "t-image": "tdesign-miniprogram/image/image", "t-input": "tdesign-miniprogram/input/input", "t-radio": "tdesign-miniprogram/radio/radio", "t-radio-group": "tdesign-miniprogram/radio-group/radio-group", "t-checkbox": "tdesign-miniprogram/checkbox/checkbox", "t-checkbox-group": "tdesign-miniprogram/checkbox-group/checkbox-group", "t-textarea": "tdesign-miniprogram/textarea/textarea" } } pages/bookServices/examination/questionList/index.wxml
@@ -1,13 +1,217 @@ <!--pages/bookServices/examination/questionList/index.wxml--> <view class="question-list"> <!-- 题型title --> <view class="question-title"> <text class="title-name">单选题</text><text class="title-score">(每题2分)</text> <view class="question-title" wx:if="{{questionList[showIndex].type}}"> <text class="title-name">{{questionList[showIndex].type}}</text ><text class="title-score">(每题{{questionList[showIndex].grade}}分)</text> </view> <!-- 题目列表 --> <swiper> <swiper-item wx:for="{{questionList}}"> <text>{{item.stem.stemTxt}}</text> <swiper class="swiper" bind:change="changeSwiper" current="{{currentIndex}}"> <swiper-item wx:for="{{questionList}}" wx:key="{{item.id}}"> <!-- 题干 --> <view class="question-stem title-score"> <!-- 题号 --> <text>{{item.number}}.</text> <!-- 仅文字 --> <view wx:if="{{item.stemStyle == 'Txt' && item.questionType != 'completion'}}" >{{item.stem.stemTxt}}</view > <!-- 仅图片 --> <view wx:elif="{{item.stemStyle == 'Image'}}"> <t-image src="{{item.stem.stemImage}}" /> </view> <!-- 图片加文字 --> <view wx:elif="{{item.stemStyle == 'TxtAndImage'}}" class="title-TxtAndImage" > <text>{{item.stem.stemTxt}}</text> <t-image src="{{item.stem.stemImage}}"></t-image> </view> <!-- 富文本 --> <view wx:elif="{{item.stemStyle == 'RichText'}} " class="title-RichText" > <rich-text nodes="{{item.stem.stemTxt}}"></rich-text> </view> <!-- 填空题 --> <view wx:if="{{item.questionType == 'completion'}}"> <view class="completion-box" wx:for="{{item.stem}}" wx:for-item="inputItem" wx:for-index="inputIndex" wx:key="inputIndex" > <t-input disabled="{{item.isComplete}}" bind:change="onChangeInput" data-value="{{item.option}}" data-id="{{item.id}}" data-index="{{inputItem.num}}" class="title-input" style="{{inputstyle}}" placeholder-style="{{placeholderstyle}}" wx:if="{{inputItem.data == 'input'}}" placeholder="请输入文字" value="{{item.userAnswer[inputItem.num]}}" ></t-input> <text wx:else>{{inputItem}}</text> </view> </view> </view> <!-- 答题区域 --> <view class="question-answer"> <!-- 单选题 --> <t-radio-group wx:if="{{item.questionType == 'singleChoice' || item.questionType == 'judge'}}" defaultValue="{{item.userAnswer}}" disabled="{{item.isComplete}}" bind:change="onChangeRadio" class="radio-group" data-value="{{item.option}}" data-id="{{item.id}}" > <view wx:for="{{item.option}}" wx:for-item="contentItem" wx:for-index="contentIndex" wx:key="contentIndex" > <t-radio value="{{contentItem.value}}" icon="none" placement="right" borderless > <view class="radio-item {{item.answer == contentItem.value && item.answer == item.userAnswer ? 'radio-correct' : item.userAnswer == contentItem.value && item.userAnswer != item.answer ?'radio-error' :''}}" > <!-- 仅文字 --> <text wx:if="{{item.optionStyle == 'Txt'}}" >{{contentItem.value}}、{{contentItem.txt}}</text > <!-- 仅图片 --> <view wx:if="{{item.optionStyle == 'Image'}}" class="fl-center"> <text>{{contentItem.value}}、</text> <t-image src="{{contentItem.img}}"></t-image> </view> <!-- 文字加图片 --> <view wx:if="{{item.optionStyle == 'TxtAndImage'}}" class="fl-center" > <text>{{contentItem.value}}、</text> <text>{{contentItem.txt}}</text> <t-image src="{{contentItem.img}}"></t-image> </view> <!-- 富文本 --> <view wx:if="{{item.optionStyle == 'RichText'}}"> <text>{{contentItem.value}}、</text> <rich-text nodes="{{contentItem.txt}}"></rich-text> </view> <text wx:if="{{item.answer == contentItem.value && item.answer == item.userAnswer}}" >对</text > <text wx:if="{{item.userAnswer == contentItem.value && item.userAnswer != item.answer}}" >错</text > </view> </t-radio> </view> </t-radio-group> <!-- 多选题 --> <t-checkbox-group disabled="{{item.isComplete}}" class="checkbox-group" wx:elif="{{item.questionType == 'multipleChoice'}}" t-class="box" borderless bind:change="onChangeRadio" data-value="{{item.option}}" data-id="{{item.id}}" defaultValue="{{item.userAnswer}}" > <view wx:for="{{item.option}}" wx:for-item="contentItem" wx:for-index="contentIndex" wx:key="contentIndex" > <t-checkbox block="{{false}}" value="{{contentItem.value}}"> <!-- 仅文字 --> <text wx:if="{{item.optionStyle == 'Txt'}}" >{{contentItem.value}}、{{contentItem.txt}}</text > <!-- 仅图片 --> <view wx:if="{{item.optionStyle == 'Image'}}" class="fl-center"> <text>{{contentItem.value}}、</text> <t-image src="{{contentItem.img}}"></t-image> </view> <!-- 文字加图片 --> <view wx:if="{{item.optionStyle == 'TxtAndImage'}}" class="fl-center" > <text>{{contentItem.value}}、</text> <text>{{contentItem.txt}}</text> <t-image src="{{contentItem.img}}"></t-image> </view> <!-- 富文本 --> <view wx:if="{{item.optionStyle == 'RichText'}}"> <text>{{contentItem.value}}、</text> <rich-text nodes="{{contentItem.txt}}"></rich-text> </view> </t-checkbox> </view> </t-checkbox-group> <!-- 简答 翻译 --> <t-textarea disabled="{{item.isComplete}}" value="{{item.userAnswer}}" bind:change="onChangeRadio" data-value="{{item.option}}" data-id="{{item.id}}" class="option-textarea" wx:elif="{{item.questionType == 'shortAnswer'}}" t-class="external-class" placeholder="请输入文字" bordered maxlength="500" disableDefaultPadding="{{true}}" indicator style="{{style}}" /> </view> <!-- 解析 --> <view class="analysis" wx:if="{{item.isComplete}}"> <view class="analysis-answer"> <view class="answer-correct"> <text class="analysis-title-box">正确答案:</text> <rich-text nodes="{{item.answer}}" style="font-size: 40rpx" ></rich-text> </view> <view class="answer-error"> <text class="analysis-title-box">您的答案:</text ><text class="answer-text">{{item.userAnswer}}</text> </view> </view> <view class="analysis-text" wx:if="{{item.analysisCon}}"> 答案解析:<rich-text nodes="{{item.analysisCon}}" class="analysis-content" ></rich-text> </view> </view> </swiper-item> <swiper-item> <text>没有更多了。。。</text> </swiper-item> </swiper> </view> pages/bookServices/examination/questionList/index.wxss
@@ -22,4 +22,129 @@ .title-score { color: #000; } .question-stem { font-size: 32rpx; font-weight: bold; display: flex; margin-bottom: 20rpx; } .swiper { min-height: 900rpx; } /* 单选题 */ .radio-group { margin-top: 20rpx; --td-radio-vertical-padding: 12rpx } .radio-item { padding: 0 32rpx; min-height: 98rpx; display: flex; align-items: center; justify-content: space-between; background-color: #F9F9F9; } .radio-correct { background-color: #EAF7EE; } .radio-error { background-color: #FFEBEB; } .question-stem image { margin-left: 20rpx; width: 300rpx; object-fit: contain; height: 200rpx; } .title-RichText img { width: 300rpx; height: 200rpx; } .question-answer image { margin: 10rpx 0 10rpx 10rpx; width: 180rpx; height: 120rpx; } .fl-center { display: flex; align-items: center; } .checkbox-group { --td-checkbox-icon-checked-color: #ff6c00; } .t-checkbox { display: flex; align-items: center; } .completion-box { display: inline-block; } .title-input { /* display: inline-block; */ height: 40rpx; --td-input-vertical-padding: 16rpx } .option-textarea { width: 97%; } /* 解析 */ .analysis { margin-top: 40rpx; } .analysis-answer { display: flex; justify-content: space-between; } .answer-correct { color: #1FBC1F; } .answer-error { color: #EE1818; } .answer-text { font-size: 40rpx; } .answer-correct { display: flex; } .analysis-title-box { display: inline-block; width: 160rpx; height: 52rpx; white-space: nowrap; } .analysis-content { display: inline-block } .analysis-text { color: #333333; font-size: 28rpx; margin-top: 20rpx; } pages/bookServices/examination/questionOptions/index.js
@@ -1,10 +1,50 @@ // pages/bookServices/examination/questionOptions/index.js Component({ /** * 组件的属性列表 */ properties: { currentIndex: { type: Number, value: 0, }, questionDataList: { type: Array, value: [] }, cardList: { type: Array, value: [] }, subjectiveTotal: { type: Number, value: 0 }, countdownTime: { type: Number, value: 0, }, answerType: { type: String, value: '' }, subjectiveNum: { type: Number, value: 0 }, subjectiveGrade: { type: Number, value: 0 }, correctNum: { type: Number, value: 0 }, submitStatus: { type: Boolean, value: false } }, /** @@ -12,12 +52,212 @@ */ data: { btnStyle: "width:320rpx;border-radius:60rpx", noReady: 0, questionCardState: false, setUpPopup: false, testReportState: false, sliderValue: 0, useTime: '' }, observers: { "countdownTime": function (newValue, oldValue) { if (this.properties.answerType == 'option') { this.setData({ useTime: this.formatTime(2 * 60 * 60 * 1000 - this.properties.countdownTime) }) } if (newValue == 0 && (this.properties.answerType == 'option' || this.properties.answerType == 'mock')) { this.timeout() } }, }, created() { }, /** * 组件的方法列表 */ methods: { // // 格式化时间 formatTime(ms) { const hours = Math.floor((ms / (1000 * 60 * 60)) % 24) .toString() .padStart(2, '0') const minutes = Math.floor((ms / (1000 * 60)) % 60) .toString() .padStart(2, '0') const seconds = Math.floor((ms / 1000) % 60) .toString() .padStart(2, '0') return `${hours}:${minutes}:${seconds}` }, // 判断是否输入答案 isHaveAnswer(data) { if (typeof data == 'string') { data = data .replace(/<[^>]*>/g, '') .replace(/ /g, '') .trim() if (data.length) { return true } else { return false } } else { const answer = data.find((item) => item.length > 0) if (answer) { return true } else { return false } } }, setCollect() { var myEventDetail = { } var myEventOption = { bubbles: true, composed: true, } this.triggerEvent('setCollect', myEventDetail, myEventOption) }, // 答题卡按钮 handlePopup() { this.setData({ questionCardState: true }) }, // 答题卡跳转题目 goQuestion(e) { var myEventDetail = { id: e.currentTarget.dataset.id } var myEventOption = { bubbles: true, composed: true, } this.triggerEvent('goQuestion', myEventDetail, myEventOption) }, // 答题卡遮罩层点击 onVisibleChange(e) { this.setData({ questionCardState: e.detail.visible, }); }, // 设置按钮 setUpBtn() { this.setData({ setUpPopup: true }) }, // 滑块变化 onChangeSlider(e) { console.log(e); this.setData({ sliderValue: e.detail.value }) }, // 设置遮罩层点击 onSetUpChange(e) { this.setData({ setUpPopup: e.detail.visible }) }, // 重做按钮 resterBtn() { wx.showModal({ title: '提示', content: '是否重新开始答题?',//editable如果为true,这就是输入框的内容 editable: false,//是否显示输入框 success: (res) => { if (res.confirm) { this.restart() } } }) }, // 重做事件 restart() { var myEventDetail = { } var myEventOption = { bubbles: true, composed: true, } this.triggerEvent('restart', myEventDetail, myEventOption) }, // 还有N道题未做弹窗 confrimPromptDialog() { wx.showModal({ title: '提示', content: `您还有 ${this.data.noReady}道题未答,是否提交?`,//editable如果为true,这就是输入框的内容 editable: false,//是否显示输入框 success: (res) => { if (res.confirm) { this.submitPaper() } } }) }, // 底部提交按钮 submitBtn() { // 我的错题和收藏 直接走提交逻辑 if (this.properties.answerType !== 'option' || this.properties.answerType !== 'option') { return this.submitPaper() } this.properties.questionDataList.forEach(item => { if (!this.isHaveAnswer(item.userAnswer)) { this.setData({ noReady: this.data.noReady + 1 }) } }) // 未做完,打开提示弹窗 if (this.data.noReady > 0) { this.confrimPromptDialog() } else { // 做完了直接执行提交事件 this.submitPaper() } }, // 提交事件 submitPaper() { var myEventDetail = { } var myEventOption = { bubbles: true, composed: true, } this.triggerEvent('submitPaper', myEventDetail, myEventOption) }, // 打开测试报告弹窗 openTestReportDialog() { this.setData({ testReportState: true }) }, // 关闭测试报告弹窗 closeTestReportDialog(e) { this.setData({ testReportState: false }) }, // 测试报告弹窗查看答案解析按钮 viewAnswer() { this.closeTestReportDialog() }, // 答题时间到 timeout() { wx.showModal({ title: '提示', content: '答题时间已到',//editable如果为true,这就是输入框的内容 editable: false,//是否显示输入框 showCancel: false, success: (res) => { } }) this.submitPaper() } } }) pages/bookServices/examination/questionOptions/index.json
@@ -3,6 +3,9 @@ "usingComponents": { "t-icon": "tdesign-miniprogram/icon/icon", "t-image": "tdesign-miniprogram/image/image", "t-button": "tdesign-miniprogram/button/button" "t-button": "tdesign-miniprogram/button/button", "t-dialog": "tdesign-miniprogram/dialog/dialog", "t-popup": "tdesign-miniprogram/popup/popup", "t-slider": "tdesign-miniprogram/slider/slider" } } pages/bookServices/examination/questionOptions/index.wxml
@@ -1,24 +1,155 @@ <!--pages/bookServices/examination/questionOptions/index.wxml--> <view class="page-bottom"> <view class="li-option"> <t-image src="/static/images/bookService/examination/collect.png"></t-image> <view class="li-option" bind:tap="setCollect"> <t-image src="{{ questionDataList[currentIndex].isCollect ? '/static/images/bookService/detail/collecting.png' : '/static/images/bookService/examination/collect.png'}}" > </t-image> 收藏 </view> <view class="li-option"> <view class="li-option" bind:tap="handlePopup"> <t-image src="/static/images/bookService/examination/questionCard.png" ></t-image> 答题卡 </view> <view class="li-option"> <view class="li-option" bind:tap="setUpBtn"> <t-image src="/static/images/bookService/examination/setting.png"></t-image> 设置 </view> <view class="li-option"> <view class="li-option" bind:tap="resterBtn" wx:if="{{answerType == 'option' || answerType == 'mock'}}" > <t-image src="/static/images/bookService/examination/reset.png"></t-image> 重做 </view> <view class="bottom-submit"> <t-button theme="primary" size="large" style="{{btnStyle}}">提交</t-button> <t-button theme="primary" size="large" style="{{btnStyle}}" bind:tap="submitBtn" >{{(answerType == 'option' || answerType == 'mock') ? '提交' : '退出'}}</t-button > </view> </view> <!-- 答题卡 --> <t-popup visible="{{questionCardState}}" bind:visible-change="onVisibleChange" placement="bottom" > <view class="popup-block"> <view class="popup-header"> <view class="popup-title">答题卡</view> </view> <view class="question-explain"> <view class="explain-answered"> <text class="answered explain-color-box"></text> <text>已答</text> </view> <view class="explain-un-answered"> <text class="un-answered explain-color-box"></text> <text>未答</text> </view> </view> <view class="question-card-list"> <view wx:for="{{cardList}}" class="card-box"> <!-- 题型 --> <view class="question-title"> <text class="color-box"></text> <text class="title-text">{{item.catalogName}}</text> </view> <view class="question-list"> <view bind:tap="goQuestion" data-id="{{citem.id}}" wx:for="{{item.infoList}}" wx:for-item="citem" wx:for-index="cindex" class="question-box {{citem.isComplete ? 'answered' : 'un-answered'}}" > {{citem.number}} </view> </view> </view> </view> </view> </t-popup> <!-- 设置 --> <t-popup visible="{{setUpPopup}}" bind:visible-change="onSetUpChange" placement="bottom" > <view class="popup-block set-up-popup"> <view class="popup-header"> <view class="popup-title">设置</view> </view> <!-- 亮度 --> <view> <t-slider defaultValue="{{30}}" theme="capsule" /> </view> <!-- 模式 --> </view> </t-popup> <!-- 测试报告 --> <t-dialog class="test-report" visible="{{testReportState}}" cancel-btn="{{null}}" confirm-btn="{{null}}" close-btn="{{true}}" title="测试报告" bind:close="closeTestReportDialog" > <view slot="content" class="test-report"> <view class="report-content-top"> <view class="report-li"> <view class="report-li-left">题目总数:</view> <view class="report-li-right">{{questionDataList.length}}道</view> </view> <view class="report-li"> <view class="report-li-left">用时:</view> <view class="report-li-right">{{useTime}}</view> </view> <view class="report-li"> <view class="report-li-left">其中客观题:</view> <view class="report-li-right" >{{subjectiveTotal}}道,分值{{subjectiveGrade}}分</view > </view> <view class="report-li"> <view class="report-li-left">答对:</view> <view class="report-li-right" ><text class="correct-color">{{correctNum}}</text> 道</view > </view> <view class="report-li"> <view class="report-li-left">答错:</view> <view class="report-li-right" ><text class="error-color">{{subjectiveTotal - correctNum}}</text> 道</view > </view> <view class="report-li"> <view class="report-li-left">客观题得分:</view> <view class="report-li-right" ><text class="score-color">{{subjectiveNum}}</text> 分</view > </view> </view> <view class="report-content-bottom"> <t-button theme="primary" bind:tap="viewAnswer" style="width: 560rpx" >查看答案与解析</t-button > </view> </view> </t-dialog> pages/bookServices/examination/questionOptions/index.wxss
@@ -28,4 +28,160 @@ --td-button-primary-border-color: #FF6C00; --td-button-primary-active-bg-color: #ff984d; --td-button-primary-active-border-color: #ff984d; } /* 答题卡 */ .popup-block { width: 100vw; height: 700rpx; background: #fff; border-top-left-radius: 16rpx; border-top-right-radius: 16rpx; } .popup-header { display: flex; align-items: center; height: 116rpx; } .popup-title { color: #333; flex: 1; text-align: center; font-weight: 600; font-size: 36rpx; } .question-card-list { padding: 0 20rpx; height: 100%; overflow-y: auto; } .question-title { margin-top: 40rpx; display: flex; align-items: center; } .question-explain { padding-right: 40rpx; display: flex; justify-content: flex-end; } .explain-un-answered { margin-left: 80rpx; } .explain-answered, .explain-un-answered { display: flex; align-items: center; } .explain-color-box { width: 30rpx; height: 30rpx; border-radius: 5rpx; display: inline-block; margin-right: 10rpx; } .color-box { display: inline-block; width: 8rpx; height: 60rpx; background-color: #ff6c00; border-radius: 0 10rpx 10rpx 0; } .title-text { color: #333; margin-left: 10rpx; } .card-box:last-child { margin-bottom: 200rpx; } .question-list { margin: 46rpx 0 64rpx 0; display: flex; flex-wrap: wrap; } .question-box { display: flex; justify-content: center; align-items: center; margin: 38rpx 20rpx 0 0; width: 126rpx; height: 62rpx; font-size: 34rpx; } .question-box:nth-child(5n) { margin-right: 0; } .answered { background-color: #FF6C00; color: #fff; } .un-answered { background-color: #F1F3F8; color: #B4B6BD; } /* 设置 */ .set-up-popup { height: 400rpx; } /* 测试报告 */ .test-report { --td-dialog-width: 660rpx } .report-content-top { padding-top: 40rpx; } .report-li { display: flex; color: #333; margin-bottom: 44rpx; } .report-li-left { width: 192rpx; } .report-li-right { margin-left: 120rpx; } .report-content-bottom { --td-button-border-radius: 60rpx; --td-button-primary-bg-color: #fff; --td-button-primary-color: #ff6c00; --td-button-primary-border-color: #ff6c00; --td-button-primary-active-bg-color: #fff0e6; --td-button-primary-active-border-color: #ff6c00; } .correct-color { color: #1FBC1F; } .error-color { color: #EE1818; } .score-color { color: #ff6c00; } pages/bookServices/examination/questionSchedule/index.js
@@ -5,45 +5,87 @@ * 组件的属性列表 */ properties: { questionList: { type: Array, value: [] }, submitStatus: { type: Boolean, value: false }, currentIndex: { type: Number, value: 1 }, countdownTime: { type: Number, value: 0 }, answerType: { type: String, value: '' } }, created() { // if (props.answerType == 'option') { // this.startCountdown() this.setData({ countdownTime: 2 * 60 * 60 * 1000 }) // } }, detached() { if (this.data.countdownInterval !== null) { clearInterval(this.data.countdownInterval) } }, /** * 组件的初始数据 */ data: { countdownInterval: null, // 计时器 isCountdownRunning: true, // 是否倒计时 countdownTime: "", // 时间 showTime: '', showTime: '', // percentage: 0, ready: 0 }, observers: { 'countdownTime': function (newValue, oldValue) { const showTime = this.formatTime(this.data.countdownTime) 'countdownTime': function (newValue) { const showTime = this.formatTime(this.properties.countdownTime) this.setData({ showTime: showTime }) console.log(this.data.showTime); }, 'questionList': function (newValue) { this.setData({ ready: 0 }) for (let index = 0; index < newValue.length; index++) { const item = newValue[index]; if (this, this.isHaveAnswer(item.userAnswer)) { this.setData({ ready: this.data.ready + 1 }) } } } }, /** * 组件的方法列表 */ methods: { // 格式化时间 // 判断是否有用户答案 isHaveAnswer(data) { if (typeof data == 'string') { data = data .replace(/<[^>]*>/g, '') .replace(/ /g, '') .trim() if (data.length) { return true } else { return false } } else { const answer = data.find((item) => item.length > 0) if (answer) { return true } else { return false } } }, // // 格式化时间 formatTime(ms) { const hours = Math.floor((ms / (1000 * 60 * 60)) % 24) .toString() @@ -56,60 +98,60 @@ .padStart(2, '0') return `${hours}:${minutes}:${seconds}` }, // 获取保存的倒计时时间 getSavedTime() { const savedTime = wx.getStorageSync('countdownTime') return savedTime ? parseInt(savedTime) : null }, // 保存倒计时时间到本地存储 saveTime() { wx.setStorageSync('countdownTime', this.data.countdownTime.toString()) }, clearTime() { this.setData({ countdownTime: 2 * 60 * 60 * 1000 }) }, // 暂停或继续倒计时 toggleCountdown() { if (countdownInterval) { clearInterval(this.data.countdownInterval) this.setData({ countdownInterval: null, isCountdownRunning: false }) } else { this.startCountdown() this.setData({ isCountdownRunning: true }) } }, // 开始倒计时 startCountdown() { // 如果计时器已经存在,先清除之前的计时器 if (this.data.countdownInterval) { clearInterval(this.data.countdownInterval) this.setData({ countdownInterval: null }) } this.setData({ countdownInterval: setInterval(() => { this.setData({ countdownTime: this.data.countdownTime - 1000 }) if (this.data.countdownTime <= 0) { clearInterval(this.data.countdownInterval) this.setData({ countdownTime: 0, isCountdownRunning: false }) } this.saveTime() }, 1000) }) // // 获取保存的倒计时时间 // getSavedTime() { // const savedTime = wx.getStorageSync('countdownTime') // return savedTime ? parseInt(savedTime) : null // }, // // 保存倒计时时间到本地存储 // saveTime() { // wx.setStorageSync('countdownTime', this.data.countdownTime.toString()) // }, // clearTime() { // this.setData({ // countdownTime: 2 * 60 * 60 * 1000 // }) // }, // // 暂停或继续倒计时 // toggleCountdown() { // if (countdownInterval) { // clearInterval(this.data.countdownInterval) // this.setData({ // countdownInterval: null, // isCountdownRunning: false // }) // } else { // this.startCountdown() // this.setData({ // isCountdownRunning: true // }) // } // }, // // 开始倒计时 // startCountdown() { // // 如果计时器已经存在,先清除之前的计时器 // if (this.data.countdownInterval) { // clearInterval(this.data.countdownInterval) // this.setData({ // countdownInterval: null // }) // } // this.setData({ // countdownInterval: setInterval(() => { // this.setData({ // countdownTime: this.data.countdownTime - 1000 // }) // if (this.data.countdownTime <= 0) { // clearInterval(this.data.countdownInterval) // this.setData({ // countdownTime: 0, // isCountdownRunning: false // }) // } // this.saveTime() // }, 1000) // }) } // } } }) pages/bookServices/examination/questionSchedule/index.wxml
@@ -1,11 +1,17 @@ <!--pages/bookServices/examination/questionSchedule/questionSchedule.wxml--> <view class="schedule"> <view class="schedule-top"> <view class="question-schedule">答题进度<text class="parimary-color question-num">1</text> <text>/18</text></view> <view class="remainder">剩余时间 <text class="parimary-color">{{showTime}}</text></view> <view class="question-schedule" >答题进度<text class="parimary-color question-num">{{ready}}</text> <text>/{{questionList.length}}</text></view > <view class="remainder" wx:if="{{!submitStatus && (answerType == 'option' || answerType == 'mock')}}" >剩余时间 <text class="parimary-color">{{showTime}}</text></view > </view> <view class="schedule-progress"> <t-progress percentage="80" color="#ff6c00" label="" /> <t-progress percentage="{{percentage}}" color="#ff6c00" label="" /> </view> </view> </view> pages/bookServices/webpage/index.js
New file @@ -0,0 +1,69 @@ // pages/bookServices/webpage/index.js Page({ /** * 页面的初始数据 */ data: { url: '' }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { console.log(options); this.setData({ url: options.url }) }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady() { }, /** * 生命周期函数--监听页面显示 */ onShow() { }, /** * 生命周期函数--监听页面隐藏 */ onHide() { }, /** * 生命周期函数--监听页面卸载 */ onUnload() { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh() { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom() { }, /** * 用户点击右上角分享 */ onShareAppMessage() { } }) pages/bookServices/webpage/index.json
New file @@ -0,0 +1,3 @@ { "usingComponents": {} } pages/bookServices/webpage/index.wxml
New file @@ -0,0 +1,2 @@ <!--pages/bookServices/webpage/index.wxml--> <web-view src="{{url}}"></web-view> pages/bookServices/webpage/index.wxss
New file @@ -0,0 +1 @@ /* pages/bookServices/webpage/index.wxss */ static/images/bookService/detail/checkpaper.png
static/images/bookService/detail/notest.png