feat: 我的练习接口对接

This commit is contained in:
cgd_mac 2022-01-12 21:52:13 +08:00
parent ad203421ef
commit 5bd40a4317
8 changed files with 512 additions and 17 deletions

View File

@ -0,0 +1,73 @@
import request from '@/utils/request'
const practiceApi = {
get: 'practice/get',
add: 'practice/add',
del: 'practice/del',
list: 'practice/list',
collectionList: 'practice/collection/pageList', // 我的收藏列表
recordList: 'practice/record/pageList', // 错题集
wrongList: 'practice/wrong/pageList', // 答题记录
startAnswer: 'practice/startAnswer', // 开始答题
}
export function practiceStartAnswer(params) {
return request({
url: practiceApi.startAnswer,
method: 'post',
data: params
})
}
export function practiceCollectionPageList(params) {
return request({
url: practiceApi.collectionList,
method: 'get',
params: params
})
}
export function practiceRecordPageList(params) {
return request({
url: practiceApi.recordList,
method: 'get',
params: params
})
}
export function practiceWrongPageList(params) {
return request({
url: practiceApi.wrongList,
method: 'get',
params: params
})
}
export function practiceAdd(params) {
return request({
url: practiceApi.add,
method: 'post',
data: params
})
}
export function practiceGet(params) {
return request({
url: practiceApi.getDict,
method: 'get',
params: params
})
}
export function practiceDel (params) {
return request({
url: practiceApi.del,
method: 'delete',
params: params
})
}
export function practiceList(params) {
return request({
url: practiceApi.list,
method: 'get',
params: params
})
}

View File

@ -0,0 +1,143 @@
<template>
<div class="exam-detail">
<div class="answer-card">
<a-card :bordered="false">
<div @click="handlerBack" class="answer-card-title"><a-icon type="arrow-left" style="margin-right: 6px;" />答题卡</div>
<div class="answer-cart-time">
倒计时:
<b style="margin-left: 5px;"><a-statistic-countdown :value="deadline" :valueStyle="{ fontSize: '16px' }" @finish="onFinish"/></b>
</div>
<DbAnswerCard :pref="$refs"></DbAnswerCard>
<div class="answer-cart-footer flex-center">
<a-button type="primary" size="large">交卷</a-button>
</div>
</a-card>
</div>
<div class="exam-line"></div>
<div class="exam-box">
<a-card :bordered="false" ref="question">
<div class="exam-title">建筑施工安全培训第一期课程学习(模拟考试)</div>
<div class="exam-main">
<template>
<div class="sub-title">单选题共30题每题1.5共45分</div>
<DbQuestionItem
:id="`type1-${index}`"
:index="index + 1"
:type="1"
v-for="(item, index) in 5"
:key="`type1-${index}`"
></DbQuestionItem>
</template>
<template>
<div class="sub-title">多选题共10题每题1.5共15分</div>
<DbQuestionItem
:id="`type2-${index}`"
:index="index + 1"
:type="2"
v-for="(item, index) in 5"
:key="`type2-${index}`"
></DbQuestionItem>
</template>
<template>
<div class="sub-title">判断题共10题每题1.5共15分</div>
<DbQuestionItem
:id="`type3-${index}`"
:index="index + 1"
:type="3"
v-for="(item, index) in 5"
:key="`type3-${index}`"
></DbQuestionItem>
</template>
<template>
<div class="sub-title">填空题共10题每题1.5共15分</div>
<DbQuestionItem :index="index + 1" :type="4" v-for="(item, index) in 5" :key="`type4-${index}`"></DbQuestionItem>
</template>
<template>
<div class="sub-title">简答题共10题每题1.5共15分</div>
<DbQuestionItem :index="index + 1" :type="5" v-for="(item, index) in 5" :key="`type5-${index}`"></DbQuestionItem>
</template>
</div>
</a-card>
</div>
</div>
</template>
<script>
import DbQuestionItem from '@/components/DbQuestionItem/index'
import DbAnswerCard from '@/components/DbAnswerCard/index'
export default {
components: {
DbQuestionItem,
DbAnswerCard
},
data() {
return {
deadline: Date.now() + 1000 * 60 * 60 * 1.5
}
},
methods: {
//
onFinish() {},
handlerBack(){
this.$router.go(-1)
}
}
}
</script>
<style lang="less" scoped>
.exam-detail {
display: flex;
max-height: 100%;
.exam-box {
flex: 1;
}
.exam-line {
flex: 0 0 10px;
}
.answer-card {
flex: 0 0 400px;
}
}
.exam-title {
font-size: 20px;
font-weight: bold;
padding: 10px 0;
border-bottom: 1px solid #c3c3c3;
text-align: center;
}
.exam-main {
padding-right: 50px;
}
.sub-title {
font-size: 16px;
font-weight: bold;
color: #333;
margin-top: 10px;
}
.answer-card-title {
font-size: 16px;
font-weight: bold;
display: flex;
align-items: center;
// justify-content: space-between;
border-bottom: 1px solid #c3c3c3;
padding-bottom: 10px;
cursor: pointer;
}
.answer-cart-time {
font-size: 14px;
color: #333;
padding: 10px 0;
text-align: right;
display: flex;
align-items: center;
justify-content: flex-end;
}
</style>

View File

@ -0,0 +1,104 @@
<template>
<div class="report-box">
<a-row :gutter="30">
<a-col :span="12">
<a-card title="得分统计" :bordered="false">
<a-row :gutter="30" style="margin: 15px 0;">
<a-col :span="12" class="flex-center">
<a-progress type="circle" :percent="75" :format="percent => `${percent} 分`" />
</a-col>
<a-col class="count-info" :span="12">
<div>共30道题答对15道总用时30分钟</div>
<div>已击败考生10%的考生</div>
<div>全站平均得分70分</div>
</a-col>
</a-row>
</a-card>
</a-col>
<!-- <a-divider type="vertical" /> -->
<a-col :span="12">
<a-card title="答题分析" :bordered="false">
<a-table :columns="columns" :data-source="dataList" size="small" :pagination="false" :bordered="false">
<span slot="action" slot-scope="text, record">
<a-button type="primary" size="small">我要练习</a-button>
</span>
</a-table>
</a-card>
</a-col>
<a-col :span="24" style="margin-top: 15px;">
<a-card title="答题卡" :bordered="false">
<ul class="answer-box">
<li class="flex-center" v-for="(item, index) in 50" :key="index">{{item+1}}</li>
</ul>
</a-card>
</a-col>
</a-row>
</div>
</template>
<script>
export default {
data () {
return {
columns: [
{
key: 'name',
dataIndex: 'name',
title: '题目类型'
},
{
key: '正确率',
dataIndex: 'percent',
title: 'percent'
},
{
title: '答题情况',
dataIndex: 'info',
key: 'info'
},
{
key: 'action',
align: 'center',
scopedSlots: { customRender: 'action' }
}
],
dataList: [
{ id: 1, name: '单选题', percent: '30.33%', info: '3/10' },
{ id: 2, name: '判断题', percent: '30.33%', info: '3/10' },
{ id: 3, name: '多选题', percent: '30.33%', info: '3/10' }
]
}
}
}
</script>
<style lang="less" scoped>
::v-deep .ant-card-head{
padding-left: 0 !important;
}
.count-info{
font-weight: bold;
color: #333;
line-height: 2;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 112px;
}
.answer-box{
display: grid;
grid-template-columns: repeat(18, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
padding: 0;
li{
background: red;
color: #fff;
height: 60px;
}
}
</style>

View File

@ -1,6 +1,6 @@
<template> <template>
<a-card :bordered="false"> <a-card :bordered="false">
<a-tabs :default-active-key="activeTab"> <a-tabs v-if="activeTab" :default-active-key="activeTab">
<a-tab-pane key="1" tab="我的收藏"> <a-tab-pane key="1" tab="我的收藏">
<a-card title="我的收藏题目(共5题)" :bordered="false" :bodyStyle="{padding: '0px !important'}" :headStyle="{paddingLeft: '0px !important'}"> <a-card title="我的收藏题目(共5题)" :bordered="false" :bodyStyle="{padding: '0px !important'}" :headStyle="{paddingLeft: '0px !important'}">
<template v-for="(item, index) in 10" > <template v-for="(item, index) in 10" >
@ -9,6 +9,7 @@
<a-divider></a-divider> <a-divider></a-divider>
</div> </div>
</template> </template>
<a-pagination :default-current="6" :total="500" />
</a-card> </a-card>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="错题集"> <a-tab-pane key="2" tab="错题集">
@ -30,7 +31,7 @@
</div> </div>
<div style="flex: 0 0 200px; text-align: right;"> <div style="flex: 0 0 200px; text-align: right;">
<div :span="24" style="margin-bottom: 10px;"><a-button type="primary" size="small" >查看报告</a-button></div> <div :span="24" style="margin-bottom: 10px;"><a-button type="primary" size="small" >查看报告</a-button></div>
<div :span="24"><a-button type="primary" size="small">查看报告</a-button></div> <div :span="24"><a-button type="primary" size="small">查看解析</a-button></div>
</div> </div>
</div> </div>
</a-card> </a-card>
@ -41,12 +42,43 @@
<script> <script>
import DbQuestionInfoItem from '@/components/DbQuestionInfoItem/index.vue' import DbQuestionInfoItem from '@/components/DbQuestionInfoItem/index.vue'
import { practiceCollectionPageList, practiceRecordPageList, practiceWrongPageList } from '@/api/practice/practice'
export default { export default {
components: { DbQuestionInfoItem }, components: { DbQuestionInfoItem },
data () { data () {
return { return {
activeTab: '1' activeTab: '',
collectionInfo: {
list: [],
size: 10,
pageIndex: 1
},
recordInfo: {
list: [],
size: 10,
pageIndex: 1
},
wrongInfo: {
list: [],
size: 10,
pageIndex: 1
}
}
},
mounted () {
this.activeTab = this.$route.query.type || '1',
this.initData()
},
methods: {
initData () {
this.getPracticeCollectionPageList()
this.getPracticeRecordPageList()
this.getPracticeWrongPageList()
},
getPracticeCollectionPageList () {
practiceCollectionPageList().then(res => {
})
} }
} }
} }

View File

@ -0,0 +1,44 @@
<template>
<div>
<DbExam></DbExam>
</div>
</template>
<script>
import DbExam from '@/components/DbExam/index'
import { practiceStartAnswer } from '@/api/practice/practice'
export default {
components: { DbExam },
data () {
return {
query: {}
}
},
mounted () {
this.query = this.$route.query
this.$nextTick(() => {
this.initData()
})
},
methods: {
initData () {
const { type } = this.query
if (type === 'practice') {
console.log('练习')
this.getPracticeDetail()
}
},
//
getPracticeDetail () {
const query = this.query
practiceStartAnswer({ projectId: Number(query.projectId), courseId: Number(query.courseId), type: Number(query.practiceType || 1) }).then(res => {
console.log('res', res)
})
}
}
}
</script>
<style lang="less" scoped>
</style>

View File

@ -15,16 +15,16 @@
"></SearchCom> "></SearchCom>
</div> </div>
<div class="flex-center" style="flex: 0 0 300px;"> <div class="flex-center" style="flex: 0 0 300px;">
<a-button type="link">我的收藏</a-button> <a-button @click="handlerGoMycollection(1)" type="link">我的收藏</a-button>
<a-button type="link">错题集</a-button> <a-button @click="handlerGoMycollection(2)" type="link">错题集</a-button>
<a-button type="link">答题记录</a-button> <a-button @click="handlerGoMycollection(3)" type="link">答题记录</a-button>
</div> </div>
</div> </div>
</div> </div>
</br> </br>
<a-card v-for="(item, index) in 6" :key="index" :bordered="false" :bodyStyle="{paddingLeft: '0px !important'}" :headStyle="{paddingLeft: '0px !important'}" > <a-card v-for="(item, index) in dataList" :key="index" :bordered="false" :bodyStyle="{paddingLeft: '0px !important'}" :headStyle="{paddingLeft: '0px !important'}" >
<template slot="title"> <template slot="title">
<b>安全生产法律法规</b><span class="sub-txt">999</span> <b>{{ item.title }}</b><span class="sub-txt">{{ item.questionCount }}</span>
</template> </template>
<a-row :gutter="16"> <a-row :gutter="16">
<a-col <a-col
@ -33,12 +33,12 @@
:md="6" :md="6"
:sm="8" :sm="8"
:xs="12" :xs="12"
v-for="(item, index) in 8" v-for="(j, k) in item.list"
:key="index"> :key="`${index}-${k}`">
<a-card hoverable style="width: 100%; margin-bottom: 15px;"> <a-card hoverable style="width: 100%; margin-bottom: 15px;">
<div class="flex-center"><h4>建筑工程相关安全生产法律</h4></div> <div class="flex-center"><h4>{{ j.projectName }}</h4></div>
<div class="flex-center" style="margin-top: 10px;"> <div class="flex-center" style="margin-top: 10px;">
<a-button type="primary" size="small" round>开始答题</a-button> <a-button @click="handlerStart(j)" type="primary" size="small" round>开始答题</a-button>
</div> </div>
</a-card> </a-card>
</a-col> </a-col>
@ -48,17 +48,20 @@
</template> </template>
<script> <script>
import _ from 'lodash'
import { SearchCom } from '@/components' import { SearchCom } from '@/components'
import { dictionaryDropDown } from '@/api/sys/dictionaryItem' import { dictionaryDropDown } from '@/api/sys/dictionaryItem'
import { dictToTree } from '@/utils/util' import { dictToTree } from '@/utils/util'
import { practiceList } from '@/api/practice/practice'
export default { export default {
components: { SearchCom }, components: { SearchCom },
data () { data () {
return { return {
dataList: [],
loading: true, loading: true,
queryParam: { queryParam: {
classification: '' // courseType: '' //
}, },
queryOptions: [ queryOptions: [
{ type: 'select-dic-tree', placeholder: '课程分类', key: 'courseType', options: [] } { type: 'select-dic-tree', placeholder: '课程分类', key: 'courseType', options: [] }
@ -67,13 +70,57 @@ export default {
}, },
mounted () { mounted () {
this.dictionaryDropDown() this.dictionaryDropDown()
this.initList()
}, },
methods: { methods: {
async initList () {
const result = await practiceList({ type: this.queryParam.courseType })
let dataList = []
if (result.code === 200 && result.data) {
dataList = Object.keys(result.data).map(item => ({ title: item, list: result.data[item] }))
dataList = dataList.map(item => ({ ...item, questionCount: _.sumBy(item.list, 'questionCount') }))
}
this.dataList = dataList
},
handleRefresh () { handleRefresh () {
this.initList()
},
//
handlerGoMycollection (type) {
console.log('12313')
this.$router.push({
path: '/mycollection',
query: { type: type }
})
},
//
handlerStart (item) {
const _this = this
const goExamDetail = function () {
_this.$router.push({
path: '/myexamDetail',
query: { courseId: item.courseId, projectId: item.projectId, practiceType: 1, type: 'practice' }
})
}
if (item.type == 2) {
this.$confirm({
title: '提示',
content: '您上次的练习还未完成,是否继续上次答题?',
okText: '继续答题',
cancelText: '重新答题',
onOk () {
goExamDetail(2)
},
onCancel () {
goExamDetail(1)
}
})
} else {
goExamDetail(1)
}
}, },
dictionaryDropDown () { dictionaryDropDown () {
dictionaryDropDown({ dictionaryCode: '0009' }).then((res) => { dictionaryDropDown({ dictionaryCode: '0006' }).then((res) => {
const result = dictToTree(res.data, [], 0) const result = dictToTree(res.data, [], 0)
this.queryOptions[0].options = result this.queryOptions[0].options = result
this.loading = false this.loading = false

View File

@ -0,0 +1,52 @@
<template>
<a-card :bordered="false">
<a-tabs :default-active-key="activeTab">
<a-tab-pane key="1" tab="答题报告">
<a-card :bordered="false" :bodyStyle="{padding: '0px !important'}" :headStyle="{paddingLeft: '0px !important'}">
<template slot="title">
<h3>建筑施工安全培训第一期课程学习</h3>
<div class="sub-info"><span>交卷时间2021年06月11日 15:06</span><span>答题用时31分19秒</span></div>
<DbReport></DbReport>
</template>
</a-card>
</a-tab-pane>
<a-tab-pane key="2" tab="查看解析">
<a-card :bordered="false" :bodyStyle="{padding: '0px !important'}" :headStyle="{paddingLeft: '0px !important'}">
<template slot="title">
<h4>建筑施工安全培训第一期课程学习</h4>
<div class="sub-info"><span>选择题30/30</span><span>选择题30/30</span><span>选择题30/30</span></div>
</template>
<template v-for="(item, index) in 10" >
<div :key="index">
<DbQuestionInfoItem :questionIndex="index+1" ></DbQuestionInfoItem>
<a-divider></a-divider>
</div>
</template>
</a-card>
</a-tab-pane>
</a-tabs>
</a-card>
</template>
<script>
import DbQuestionInfoItem from '@/components/DbQuestionInfoItem/index.vue'
import DbReport from '@/components/DbReport/index.vue'
export default {
components: { DbQuestionInfoItem, DbReport },
data () {
return {
activeTab: '1'
}
}
}
</script>
<style lang="less" scoped>
.sub-info{
color: #666;
font-weight: normal;
font-size: 14px;
}
</style>

View File

@ -103,7 +103,7 @@ const vueConfig = {
proxy: { proxy: {
'/dawa': { // 捕获API的标志如果API中有这个字符串那么就开始匹配代理 '/dawa': { // 捕获API的标志如果API中有这个字符串那么就开始匹配代理
target: 'http://a.3a6.cn/dawa', // 地址可以是域名也可以是IP地址。比如API请求/api/getList, 会被代理到请求http://www.baidu.com/api/getList 。 target: 'http://a.3a6.cn/dawa', // 地址可以是域名也可以是IP地址。比如API请求/api/getList, 会被代理到请求http://www.baidu.com/api/getList 。
// target: 'http://192.168.2.133:8000/dawa', // 地址可以是域名也可以是IP地址。比如API请求/api/getList, 会被代理到请求http://www.baidu.com/api/getList 。 // target: 'http://localhost:8000/dawa', // 地址可以是域名也可以是IP地址。比如API请求/api/getList, 会被代理到请求http://www.baidu.com/api/getList 。
ws: false, ws: false,
changeOrigin: true, changeOrigin: true,
pathRewrite: { pathRewrite: {