diff --git a/front/src/api/competition.js b/front/src/api/competition.js index 472c698..d9faf21 100644 --- a/front/src/api/competition.js +++ b/front/src/api/competition.js @@ -24,4 +24,26 @@ export function submit(compId,stageId,qList){ qList: qList } }) +} +export function position(q){ + return request({ + url: baseUrl+ "position", + method: 'get', + params: q + }) +} + +export function get(q){ + return request({ + url: baseUrl+ "get", + method: 'get', + params: q + }) +} +export function startExam(q){ + return request({ + url: authUrl+ "exam/start", + method: 'get', + params: q + }) } \ No newline at end of file diff --git a/front/src/components/index.vue b/front/src/components/index.vue index 5f8e72a..d64ca8c 100644 --- a/front/src/components/index.vue +++ b/front/src/components/index.vue @@ -27,8 +27,8 @@ <b-img fluid src="/static/image/title_1_500x102.png" /> </div> <b-container class="d-none d-xl-block"> - <b-row class="tz-box" @click="goCompetition(1)"> - <b-col sm="3"> <b-img fluid src="/static/image/pic_1_340x190.png" /></b-col> + <b-row v-for="item in list1" :key="item.id" class="tz-box" @click="goCompetition(item.id)"> + <b-col sm="3"> <b-img fluid :src="item.thumbnail" /></b-col> <b-col sm="9"> <b-container> <b-row> @@ -37,11 +37,11 @@ <div> <div class=""> <b-img fluid src="/static/image/icon_home1_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span class="tz-team-title">2021年全国高职金融模拟交易大赛</span> + <span class="tz-team-title">{{ item.name}}</span> </div> <div> <b-img fluid src="/static/image/icon_home2_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span>主办方:全国金融职业教育教学指导委员会</span> + <span>主办方:{{ item.sponsor}}</span> </div> </div> <div> @@ -59,72 +59,18 @@ <b-img fluid src="/static/image/icon_home3_30x30.png" class="tz-icon" /> </div> <div> - <div>比赛时间:<span class="tz-yellow-time">2022-05-20 16:00</span> 至 <span class="tz-red-time">2022-05-20 17:00</span></div> - <div>报名时间:<span class="tz-yellow-time">2022-05-20 16:00</span> 至 <span class="tz-red-time">2022-05-20 17:00</span></div> + <div>比赛时间:<span class="tz-yellow-time">{{ new Date(item.startTime).Format('yyyy-MM-dd') }}</span> 至 <span class="tz-red-time">{{ new Date(item.endTime).Format('yyyy-MM-dd')}}</span></div> + <div v-if="item.enableSignup">报名时间:<span class="tz-yellow-time">{{ new Date(item.signupStartTime).Format('yyyy-MM-dd')}}</span> 至 <span class="tz-red-time">{{ new Date(item.signupStartTime).Format('yyyy-MM-dd')}}</span></div> </div> </div> <div class="tz-button-container"> - <b-container class="tz-button tz-button-blue"> + <b-container :class="item.type == 2 ?'tz-button tz-button-yellow':'tz-button tz-button-blue'"> <b-row align-h="center" align-v="center"> <b-col sm="3" align="center"> - <b-img src="/static/image/icon_home4_40x40.png" /> + <b-img :src="item.type==2?'/static/image/icon_home5_40x40.png':'/static/image/icon_home4_40x40.png'" /> </b-col> <b-col sm="9" align="center"> - <span class="d-none d-sm-inline" >团队赛</span>报名中 - </b-col> - </b-row> - </b-container> - </div> - </div> - </b-col> - </b-row> - </b-container> - </b-col> - </b-row> - <b-row class="tz-box" @click="goCompetition(1)"> - <b-col sm="3"> <b-img fluid src="/static/image/pic_1_340x190.png" /></b-col> - <b-col sm="9"> - <b-container> - <b-row> - <b-col> - <div class="tz-box2-content"> - <div> - <div class=""> - <b-img fluid src="/static/image/icon_home1_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span class="tz-team-title">2021年全国高职金融模拟交易大赛</span> - </div> - <div> - <b-img fluid src="/static/image/icon_home2_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span>主办方:全国金融职业教育教学指导委员会</span> - </div> - </div> - <div> - <b-img fluid src="/static/image/going.png" /> - </div> - </div> - </b-col> - </b-row> - <hr /> - <b-row> - <b-col> - <div class="tz-box2-content"> - <div class="tz-time-container"> - <div class="d-none d-sm-inline" > - <b-img fluid src="/static/image/icon_home3_30x30.png" class="tz-icon" /> - </div> - <div> - <div>比赛时间:<span class="tz-yellow-time">2022-05-20 16:00</span> 至 <span class="tz-red-time">2022-05-20 17:00</span></div> - <div>报名时间:<span class="tz-yellow-time">2022-05-20 16:00</span> 至 <span class="tz-red-time">2022-05-20 17:00</span></div> - </div> - </div> - <div class="tz-button-container"> - <b-container class="tz-button tz-button-yellow"> - <b-row align-h="center" align-v="center"> - <b-col sm="3" align="center"> - <b-img src="/static/image/icon_home5_40x40.png" /> - </b-col> - <b-col sm="9" align="center"> - <span class="d-none d-sm-inline" >个人赛</span>报名中 + <span class="d-none d-sm-inline" >{{ item.type == 2?'个人赛':'团队赛' }}</span>{{getStatus(item)}} </b-col> </b-row> </b-container> @@ -212,13 +158,13 @@ <b-img fluid src="/static/image/title_2_500x102.png" /> </div> <b-container> - <b-row> - <b-col sm> - <div class="tz-box2" @click="goCompetition(1)"> + <b-row v-for="(subList,$index) in list2" :key="$index"> + <b-col sm v-for="item in subList" :key="item.id" > + <div class="tz-box2" @click="goCompetition(item.id)"> <div class="tz-box2-header"> - <div class="tz-bg-blue"> - <b-img fluid src="/static/image/icon_home4_40x40.png"/> - <span>团体赛</span> + <div :class="item.type==1 ?'tz-bg-blue':'tz-bg-yellow' "> + <b-img fluid :src="item.type == 1?'/static/image/icon_home4_40x40.png':'/static/image/icon_home5_40x40.png'"/> + <span>{{ item.type == 1?'团体赛':'个人赛'}}</span> </div> <div class="tz-bg-black"> 已结束 @@ -231,11 +177,11 @@ <div class="tz-footer-content"> <div> <b-img src="/static/image/icon_home1_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span class="tz-footer-title" >2021年全国高职金融模拟交易大赛</span> + <span class="tz-footer-title" >{{ item.name}}</span> </div> <div> <b-img src="/static/image/icon_home2_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span>主办方:全国金融职业教育教学指导委员会</span> + <span>主办方:{{ item.sponsor}}</span> </div> </div> <div class="tz-flex"> @@ -243,82 +189,8 @@ <b-img src="/static/image/icon_home3_30x30.png" class="d-none d-sm-inline tz-icon" /> </div> <div> - <div>比赛时间:05/20 16:00 至 05/20 17:00</div> - <div>报名时间:05/20 16:00 至 05/20 17:00</div> - </div> - </div> - </div> - </div> - </b-col> - <b-col sm> - <div class="tz-box2" @click="goCompetition(1)"> - <div class="tz-box2-header"> - <div class="tz-bg-blue"> - <b-img fluid src="/static/image/icon_home4_40x40.png"/> - <span>团体赛</span> - </div> - <div class="tz-bg-black"> - 已结束 - </div> - </div> - <div class="tz-box2-container"> - <b-img src="/static/image/pic_1_340x190.png" /> - </div> - <div class="tz-box2-footer"> - <div class="tz-footer-content"> - <div> - <b-img src="/static/image/icon_home1_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span class="tz-footer-title" >2021年全国高职金融模拟交易大赛</span> - </div> - <div> - <b-img src="/static/image/icon_home2_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span>主办方:全国金融职业教育教学指导委员会</span> - </div> - </div> - <div class="tz-flex"> - <div> - <b-img src="/static/image/icon_home3_30x30.png" class="d-none d-sm-inline tz-icon" /> - </div> - <div> - <div>比赛时间:05/20 16:00 至 05/20 17:00</div> - <div>报名时间:05/20 16:00 至 05/20 17:00</div> - </div> - </div> - </div> - </div> - </b-col> - <b-col sm> - <div class="tz-box2" @click="goCompetition(1)"> - <div class="tz-box2-header"> - <div class="tz-bg-yellow"> - <b-img fluid src="/static/image/icon_home5_40x40.png"/> - <span>个人赛</span> - </div> - <div class="tz-bg-black"> - 已结束 - </div> - </div> - <div class="tz-box2-container"> - <b-img src="/static/image/pic_1_340x190.png" /> - </div> - <div class="tz-box2-footer"> - <div class="tz-footer-content"> - <div> - <b-img src="/static/image/icon_home1_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span class="tz-footer-title" >2021年全国高职金融模拟交易大赛</span> - </div> - <div> - <b-img src="/static/image/icon_home2_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span>主办方:全国金融职业教育教学指导委员会</span> - </div> - </div> - <div class="tz-flex"> - <div> - <b-img src="/static/image/icon_home3_30x30.png" class="d-none d-sm-inline tz-icon" /> - </div> - <div> - <div>比赛时间:05/20 16:00 至 05/20 17:00</div> - <div>报名时间:05/20 16:00 至 05/20 17:00</div> + <div>比赛时间:{{new Date(item.startTime).Format('yyyy-MM-dd')}} 至 {{ new Date(item.endTime).Format('yyyy-MM-dd')}}</div> + <div v-if="item.enableSignup" >报名时间:{{ new Date(item.signupStartTime).Format('yyyy-MM-dd') }} 至 {{ new Date(item.singnupEndTime).Format('yyyy-MM-dd')}}</div> </div> </div> </div> @@ -331,12 +203,30 @@ </template> <script> import Footer from '@/components/footer.vue' +import * as competitionApi from '@/api/competition' export default { components:{ "tz-footer": Footer }, + data(){ + return { + list1: [], + list2: [], + page1: { + pageNo: 1, + pageSize: 20, + type:1 + }, + page2: { + pageNo: 1, + pageSize: 20, + type: 2 + } + } + }, mounted(){ - + this.listGoing() + this.listDone() }, created(){ @@ -352,6 +242,34 @@ export default { this.$router.push({ path: '/member' }) + }, + listGoing(){ + competitionApi.getList(this.page1.pageNo,this.page1.type).then(res=>{ + if(res.code == 200){ + this.list1 = res.data.list + } + }) + }, + listDone(){ + competitionApi.getList(this.page2.pageNo,this.page2.type).then(res=>{ + if(res.code == 200){ + for(var i= 0;i<res.data.list.length;i+=3) { + let index = i/3 + this.list2[index] = res.data.list.slice(i,i+3) + } + } + }) + }, + getStatus(item){ + let now = new Date().getTime() + if(item.enableSignup) { + let singnupStartTime = new Date(item.singnupStartTime).getTime() + let singnupEndTime = new Date(item.singnupEndTime).getTime() + if(now>= singnupStartTime &&now<=singnupEndTime){ + return "报名中"; + } + } + return "进行中"; } } } diff --git a/front/src/utils/auth.js b/front/src/utils/auth.js index 54c3523..d32c437 100644 --- a/front/src/utils/auth.js +++ b/front/src/utils/auth.js @@ -1,16 +1,25 @@ let infoName = "userInfo" export function getToken(){ let info = localStorage.getItem("token") - if(info){ return info } return null } export function setInfo(userInfo){ - localStorage.setItem(infoName,userInfo) + localStorage.setItem(infoName,JSON.stringify(userInfo)) localStorage.setItem("token",userInfo.token) } export function getInfo(){ - return localStorage.getItem(infoName) + return JSON.parse(localStorage.getItem(infoName)) +} +export function loginout(){ + localStorage.removeItem(infoName) + localStorage.removeItem('token') +} +export function setObj(key,value){ + localStorage.setItem(key,JSON.stringify(value)) +} +export function getObj(key){ + return JSON.parse(localStorage.getItem(key)) } \ No newline at end of file diff --git a/front/src/views/competition/first.vue b/front/src/views/competition/first.vue index c944bc3..edb66e8 100644 --- a/front/src/views/competition/first.vue +++ b/front/src/views/competition/first.vue @@ -2,22 +2,22 @@ <div class="tz-container"> <div class="tz-box"> <div class="tz-banner"> - <b-img src="/static/image/pic_1_340x190.png" /> + <b-img fluid :src="competition.thumbnail" /> </div> <div class="tz-box-content"> <div class="tz-img-container"> <b-img fluid src="/static/image/icon_home1_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span class="tz-title">2021年全国高职金融模拟交易大赛</span> + <span class="tz-title">{{ competition.name}}</span> </div> <hr /> <div class="tz-box-info"> <div class="tz-img-container"> <b-img fluid src="/static/image/icon_home2_30x30.png" class="d-none d-sm-inline tz-icon" /> - <span class="info">主办方:全国金融职业教育教学指导委员会</span> + <span class="info">主办方:{{ competition.sponsor}}</span> </div> <div class="tz-img-container"> <b-img fluid src="/static/image/supporter_icon.png" class="d-none d-sm-inline tz-icon" /> - <span class="info">技术支持方:深圳市天泽教育科技有限公司</span> + <span class="info">技术支持方:{{ competition.supporter}}</span> </div> </div> </div> @@ -25,129 +25,86 @@ <b-img src="/static/image/medal_icon.png" /> <div class="tz-flex"> <div class="tz-border"> - <div>2056</div> + <div>{{ competition.teamCount}}</div> <div>参赛团队</div> </div> <div class="tz-v-spliter"></div> <div> - <div>8399</div> + <div>{{ competition.peopleCount }}</div> <div>参赛人数</div> </div> </div> </div> </div> - <div class="stage-name"> - <hr class="black-hr" /> <div> <div class="stage-icon">初</div><span>初赛</span> </div><hr class="black-hr" /> - </div> - <div class="stage-list"> - <div class="stage-box"> - <div class="stage-header"> - <div>赛项一:证券投资交易赛项</div> - <div @click="gotPage(1)">进入答题></div> - </div> - <div> - <b-img fluid src="/static/image/img1_580x260.jpg"/> - </div> - <div class="stage-time"> - 竞赛时间:<span>2022-04-03 18:00</span>--<span>2022-05-06 18:00</span> - </div> + <div v-for="item in competition.stageList" :key="item.id"> + <div class="stage-name"> + <hr class="black-hr" /> <div> <div class="stage-icon"> {{ item.name.substring(0,1)}}</div><span>{{item.name}}</span> </div><hr class="black-hr" /> </div> - <div class="stage-box"> - <div class="stage-header"> - <div>赛项一:证券投资交易赛项</div> - <div @click="gotPage(2)">进入实操></div> - </div> - <div> - <b-img fluid src="/static/image/img4_580x260.jpg"/> - </div> - <div class="stage-time"> - 竞赛时间:<span>2022-04-03 18:00</span>--<span>2022-05-06 18:00</span> - </div> - </div> - </div> - - <div class="stage-name"> - <hr class="black-hr" /> <div> <div class="stage-icon">决</div><span>决赛</span> </div><hr class="black-hr" /> - </div> - - <div class="stage-list"> - <div class="stage-box"> - <div class="stage-header"> - <div>赛项一:证券投资交易赛项</div> - <div @click="gotPage(1)">进入答题></div> - </div> - <div> - <b-img fluid src="/static/image/img2_580x260.jpg"/> - </div> - <div class="stage-time"> - 竞赛时间:<span>2022-04-03 18:00</span>--<span>2022-05-06 18:00</span> - </div> - </div> - <div class="stage-box"> - <div class="stage-header"> - <div>赛项一:证券投资交易赛项</div> - <div @click="gotPage(2)">进入实操></div> - </div> - <div> - <b-img fluid src="/static/image/img5_580x260.jpg"/> - </div> - <div class="stage-time"> - 竞赛时间:<span>2022-04-03 18:00</span>--<span>2022-05-06 18:00</span> - </div> - </div> - </div> - - - - <div class="stage-name"> - <hr class="black-hr" /> <div> <div class="stage-icon">冠</div><span>冠军邀请赛</span> </div><hr class="black-hr" /> - </div> - - <div class="stage-list"> - <div class="stage-box"> - <div class="stage-header"> - <div>赛项一:证券投资交易赛项</div> - <div @click="gotPage(1)">进入答题></div> - </div> - <div> - <b-img fluid src="/static/image/img3_580x260.jpg"/> - </div> - <div class="stage-time"> - 竞赛时间:<span>2022-04-03 18:00</span>--<span>2022-05-06 18:00</span> - </div> - </div> - <div class="stage-box"> - <div class="stage-header"> - <div>赛项一:证券投资交易赛项</div> - <div @click="gotPage(2)">进入实操></div> - </div> - <div> - <b-img fluid src="/static/image/img6_580x260.jpg"/> + <div class="stage-list"> + <div class="stage-box"> + <div class="stage-header"> + <div>赛项一:证券投资交易赛项</div> + <div @click="gotPage(1,item.id)">进入答题></div> + </div> + <div> + <b-img fluid src="/static/image/img1_580x260.jpg"/> + </div> + <div class="stage-time"> + 竞赛时间:<span>2022-04-03 18:00</span>--<span>2022-05-06 18:00</span> + </div> </div> - <div class="stage-time"> - 竞赛时间:<span>2022-04-03 18:00</span>--<span>2022-05-06 18:00</span> + <div class="stage-box"> + <div class="stage-header"> + <div>赛项一:证券投资交易赛项</div> + <div @click="gotPage(2,item.id)">进入实操></div> + </div> + <div> + <b-img fluid src="/static/image/img4_580x260.jpg"/> + </div> + <div class="stage-time"> + 竞赛时间:<span>2022-04-03 18:00</span>--<span>2022-05-06 18:00</span> + </div> </div> </div> </div> - </div> </template> <script> +import * as competitionApi from '@/api/competition' export default { + data(){ + return { + compId: 0, + competition:{} + } + }, + created(){ + + if(this.$route.query){ + this.compId = this.$route.query.id + } + competitionApi.get({compId: this.compId}).then(res=>{ + console.log(res) + if(res.code == 200){ + this.competition = res.data + } + }) + }, methods:{ - gotPage(type){ + gotPage(type,id){ if(type ==1){ this.$router.push({ - path: '/exam' + path: '/exam', + query: { id: this.compId,stageId: id } }) }else{ this.$router.push({ - path: '/system' + path: '/system', + query: { id: this.compId,stageId: id} }) } - } } @@ -244,6 +201,7 @@ export default { .tz-banner{ margin-right: 1rem; padding: .8rem; + width: 25rem; } .info{ margin-left: 1rem; diff --git a/front/src/views/competition/ranking.vue b/front/src/views/competition/ranking.vue index 74d70a4..cd2935c 100644 --- a/front/src/views/competition/ranking.vue +++ b/front/src/views/competition/ranking.vue @@ -69,9 +69,11 @@ </b-container> </template> <script> +import { getInfo } from '@/utils/auth' export default { data(){ return { + userInfo: null, stageId: 1, regionId:0, levelId: 0, @@ -137,6 +139,9 @@ export default { } ] } + }, + created(){ + this.userInfo = getInfo() } } </script> diff --git a/front/src/views/dialog/confirmdialog.vue b/front/src/views/dialog/confirmdialog.vue new file mode 100644 index 0000000..81d0f21 --- /dev/null +++ b/front/src/views/dialog/confirmdialog.vue @@ -0,0 +1,57 @@ +<template> + <div v-if="visiable" class="tz-dialog"> + <div class="dlg-line"> + {{ msg }} + </div> + <div> + <b-button @click="cancel">取消</b-button> + <b-button @click="confirm">确认</b-button> + </div> + </div> +</template> +<script> +export default { + props:{ + visiable:{ + type: Boolean, + default: true + }, + ok: { + type: Boolean, + default: false + }, + msg: { + type: String, + default: '' + } + }, + methods:{ + cancel(){ + this.$router.back(); + }, + confirm(){ + this.$emit("update:ok",true) + } + } +} +</script> +<style scoped> +.tz-dialog{ + position: absolute; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + top:0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.9); + color: white; + font-size: 200%; + font-weight: bold; +} +.dlg-line{ + width: 100%; +} +</style> \ No newline at end of file diff --git a/front/src/views/system/cutdown.vue b/front/src/views/system/cutdown.vue index e2c8d61..4f64d49 100644 --- a/front/src/views/system/cutdown.vue +++ b/front/src/views/system/cutdown.vue @@ -14,18 +14,9 @@ export default { created(){ this.startTime = new Date(this.start) this.endTime = new Date(this.end) - - }, mounted(){ - let end = setInterval(() => { - - }, 3000); - for(var i = 0;i<=end;i++){ - clearInterval(i); - } - console.log("cutDown component mounted") - this.cutDownManger = setInterval(this.cutDown,1000) + }, props:{ start:{ @@ -37,6 +28,17 @@ export default { default: null } }, + watch:{ + start(val){ + this.startTime = new Date(this.start) + console.log("cutDown startTime:"+this.startTime) + }, + end(val){ + this.endTime = new Date(this.end) + console.log("cutDown endTime:"+this.endTime) + this.initCutDown() + } + }, data(){ return { startTime: null, @@ -50,6 +52,15 @@ export default { } }, methods:{ + initCutDown(){ + let end = setInterval(() => { + + }, 3000); + for(var i = 0;i<=end;i++){ + clearInterval(i); + } + this.cutDownManger = setInterval(this.cutDown,1000) + }, cutDown(){ let now = new Date() // console.log(this.cutDownManger) diff --git a/front/src/views/system/exam.vue b/front/src/views/system/exam.vue index 17357d6..0faa041 100644 --- a/front/src/views/system/exam.vue +++ b/front/src/views/system/exam.vue @@ -7,12 +7,12 @@ <b-img src="/static/image/exam_title.png" /> </div> <div> - <cut-down start="2022-3-14 00:00:00" end="2022-3-28 03:00:00" /> + <cut-down :start="examInfo.startTime" :end="examInfo.endTime" /> </div> </div> <div class="exam-header-title"> <div> - 2020年全国高职财经大数据分析大赛--金融实操赛项 + {{ competition.name}}--金融实操赛项 </div> <div> <b-button class="exam-button" @click="handle">交卷</b-button> @@ -22,9 +22,9 @@ <div class="tz-exam-content"> <div class="tz-exam-left-panel"> <div class="tz-exam-box"> - <div class="tz-exam-box-title2">产品研究部试用吴京和</div> + <div class="tz-exam-box-title2">{{userInfo.school +' '+ userInfo.name}}</div> <div class="tz-exam-box-content"> - <b-img src="/static/image/tx80x80.png" /> 考试日期: {{new Date().Format("yyyy-MM-dd")}} + <b-img src="/static/image/tx80x80.png" /> 考试日期: {{examInfo.startTime}} </div> </div> <div class="tz-exam-box"> @@ -68,7 +68,7 @@ <div class="exam-tab-content"> <div> <a name="single" /> - 单选题(共<span>60</span>题,每题<span>0.5</span>分,共<span>20.0</span>分) + 单选题(共<span>{{singleInfo.size}}</span>题,每题<span>{{singleInfo.score}}</span>分,共<span>{{singleInfo.sumScore}}</span>分) </div> <div v-for="cq in singleQuestion" :key="cq.id"> <a :name="cq.id" /> @@ -83,7 +83,7 @@ </div> <div> <a name="multi" /> - 多选题(共<span>60</span>题,每题<span>0.5</span>分,共<span>20.0</span>分) + 多选题(共<span>{{multiInfo.size}}</span>题,每题<span>{{multiInfo.score}}</span>分,共<span>{{ multiInfo.sumScore}}</span>分) </div> <div v-for="cq in multiQuestion" :key="cq.id"> <a :name="cq.id" /> @@ -98,7 +98,7 @@ </div> <div> <a name="judge" /> - 判断题(共<span>60</span>题,每题<span>0.5</span>分,共<span>20.0</span>分) + 判断题(共<span>{{judgeInfo.size}}</span>题,每题<span>{{judgeInfo.score}}</span>分,共<span>{{judgeInfo.sumScore}}</span>分) </div> <div v-for="cq in judgeQuestion" :key="cq.id"> <a :name="cq.id" /> @@ -114,17 +114,17 @@ <div> <a name="anli" /> - 案例题(共<span>60</span>题,每题<span>0.5</span>分,共<span>20.0</span>分) + 案例题(共<span>{{anliInfo.size}}</span>题,每题<span>{{anliInfo.score}}</span>分,共<span>{{anliInfo.sumScore}}</span>分) </div> <div v-for="cq in anliQuestion" :key="cq.id"> <a :name="cq.id" /> - <div>案例名称:</div> - <div v-if="!!cq.item"> - {{cq.id}}.{{cq.item.stem}} + <div class="anli_title">案例名称:</div> + <div class="anli_sub_title" v-if="!!cq.item"> + {{cq.item.stem}} </div> - <div>案例介绍:</div> - <div v-html="cq.item.content"></div> - + <div class="anli_title">案例介绍:</div> + <div class="anli_sub_title" v-html="cq.item.content"></div> + <hr class="tz-line-dash" /> <div v-for="subcq in cq.item.children" :key="subcq.id"> <div class="question-stem"> {{subcq.id}}.{{subcq.stem}} @@ -148,17 +148,39 @@ </div> </div> <tz-footer /> + <tz-dialog msg="确认后开始考试,答题时间为1个小时,是否现在开始答题?" :ok.sync="confirm" :visiable="dlgVisiable" /> </div> </template> <script> import CutDown from './cutdown.vue' import Footer from '@/components/footer.vue' +import ConfirmDialog from '@/views/dialog/confirmdialog.vue' import * as examApi from '@/api/competition' import { getInfo } from '@/utils/auth' export default { data(){ return { - singleQuestion: [], + singleInfo: { + size: 0, + score: 0, + sumScore: 0 + }, + multiInfo: { + size: 0, + score: 0, + sumScore: 0 + }, + judgeInfo: { + size: 0, + score: 0, + sumScore: 0 + }, + anliInfo: { + size: 0, + score: 0, + sumScore: 0 + }, + singleQuestion: [], multiQuestion: [], judgeQuestion: [], anliQuestion:[], @@ -168,8 +190,18 @@ export default { currentQ: null, userInfo: null, tabId: 0, - compId: 0, - stageId: 0 + compId: 1, + stageId: 1, + confirm: false, + dlgVisiable: true, + competition: null, + examInfo: { + startTime: null, + endTime: null, + doneList:[], + markList:[], + current: 1, + } } }, methods:{ @@ -209,7 +241,6 @@ export default { qList= qList.concat(this.getQList(this.multiQuestion)) qList=qList.concat(this.getQList(this.judgeQuestion)) qList=qList.concat(this.getQList(this.anliQuestion)) - console.log(qList) examApi.submit(this.compId,this.stageId,qList).then(res=>{ console.log(res) }) @@ -218,80 +249,185 @@ export default { let list = [] obj.forEach(i=>{ if(i.item.type == 0 ){ + let ids = [] + if( i.item.answerId instanceof Array){ + ids = i.item.answerId + }else{ + ids.push(i.item.answerId) + } + list.push({ id: i.item.id, subId: 0, - answerId: i.item.answerId + ids: ids }) }else if(i.item.type == 1){ i.item.children.forEach( q=>{ + let ids = [] + if( q.answerId instanceof Array){ + ids = q.answerId + }else{ + ids.push(q.answerId) + } list.push({ id: i.item.id, subId: q.id, - answerId: q.answerId + ids: ids }) }) } }) return list - } - }, - created(){ - this.userInfo = getInfo() - examApi.listQuestion(1,1).then(res=>{ - if(res instanceof Array){ - - let singleList = res.filter( item => item.questionType == 1 &&item.type == 0) - let multiList = res.filter(item =>item.questionType == 2&&item.type == 0) - let judeList = res.filter(item =>item.questionType == 3&&item.type == 0) - let anliList = res.filter(item => item.type == 1) - - for(var i= 0;i<singleList.length;i++){ - let item = singleList[i] - if(item.answerId.length>0){ - item.answerId = item.answerId[0] - } - - this.singleQuestion.push({id: (i+1), item: item}) - } - this.currentQ = this.singleQuestion[0] + }, + loadQuestion(){ + examApi.listQuestion(this.compId,this.stageId).then(res=>{ + if(res instanceof Array){ + + let singleList = res.filter( item => item.questionType == 1 &&item.type == 0) + let multiList = res.filter(item =>item.questionType == 2&&item.type == 0) + let judeList = res.filter(item =>item.questionType == 3&&item.type == 0) + let anliList = res.filter(item => item.type == 1) + singleList.sort(function(){ + return (0.5 - Math.random()) + }) + multiList.sort(function(){ + return (0.5 - Math.random()) + }) + judeList.sort(function(){ + return (0.5 - Math.random()) + }) + anliList.sort(function(){ + return (0.5 - Math.random()) + }) + for(var i= 0;i<singleList.length;i++){ + let item = singleList[i] + if(item.answerId.length>0){ + item.answerId = item.answerId[0] + } + + this.singleQuestion.push({id: (i+1), item: item}) + } + this.currentQ = this.singleQuestion[0] - let startIndex =this.singleQuestion.length+1 - for(var i = 0; i<multiList.length; i++){ - let item = multiList[i] - this.multiQuestion.push({id: (startIndex+i), item: item}) + let startIndex =this.singleQuestion.length+1 + for(var i = 0; i<multiList.length; i++){ + let item = multiList[i] + this.multiQuestion.push({id: (startIndex+i), item: item}) + } + startIndex =this.singleQuestion.length+ this.multiQuestion.length +1 + for(var i = 0; i< judeList.length ;i++){ + let item = judeList[i] + if(item.answerId.length>0){ + item.answerId = item.answerId[0] + } + this.judgeQuestion.push({id:(startIndex + i ), item: item}) + } + startIndex = this.singleQuestion.length+ this.multiQuestion.length + this.judgeQuestion.length + 1 + for(var i = 0;i<anliList.length;i++){ + let item = anliList[i] + item.children.forEach( child =>{ + if((child.questionType == 1 || child.questionType == 3)&&child.answerId.length>0){ + child.answerId = child.answerId[0] + } + }) + this.anliQuestion.push({id: (startIndex + i ) ,item: item}) + } + } - startIndex =this.singleQuestion.length+ this.multiQuestion.length +1 - for(var i = 0; i< judeList.length ;i++){ - let item = judeList[i] - if(item.answerId.length>0){ - item.answerId = item.answerId[0] - } - this.judgeQuestion.push({id:(startIndex + i ), item: item}) + this.dlgVisiable = false + this.initQuestionInfo() + }) + }, + startExam(){ + examApi.startExam({ compId:this.compId,stageId: this.stageId}).then(res=>{ + if(res.code == 200){ + this.examInfo.startTime = res.data.startTime + this.examInfo.endTime = res.data.endTime + this.loadQuestion() } - startIndex = this.singleQuestion.length+ this.multiQuestion.length + this.judgeQuestion.length + 1 - for(var i = 0;i<anliList.length;i++){ - let item = anliList[i] - item.children.forEach( child =>{ - if((child.questionType == 1 || child.questionType == 3)&&child.answerId.length>0){ - child.answerId = child.answerId[0] - } + }) + }, + initQuestionInfo(){ + this.singleInfo.size = this.singleQuestion.length + this.judgeInfo.size = this.judgeQuestion.length + this.multiInfo.size = this.multiQuestion.length + this.anliInfo.size = this.anliQuestion.length + this.singleInfo.sumScore = this.sumScore(this.singleQuestion) + this.singleInfo.score = this.singleInfo.sumScore/this.singleInfo.size + this.judgeInfo.sumScore = this.sumScore(this.judgeQuestion) + this.judgeInfo.score = this.judgeInfo.sumScore/this.judgeInfo.size + this.multiInfo.sumScore = this.sumScore(this.multiQuestion) + this.multiInfo.score = this.multiInfo.sumScore/this.multiInfo.size + this.anliInfo.sumScore = this.sumAnliScore(this.anliQuestion) + this.anliInfo.score = this.anliInfo.sumScore/this.anliInfo.size + + }, + sumScore(qList){ + let score = 0 + if(qList instanceof Array){ + qList.forEach(q=>{ + score +=q.item.score + }) + } + return score + }, + sumAnliScore(qList){ + let score = 0 + if(qList instanceof Array){ + qList.forEach(q=>{ + + q.item.children.forEach(cq=>{ + console.log("anliItem:",cq) + score += cq.score }) - this.anliQuestion.push({id: (startIndex + i ) ,item: item}) + }) + } + return score + } + }, + created(){ + if(this.$route.query){ + this.compId = this.$route.query.id + examApi.get({compId: this.compId}).then(res=>{ + if(res.code == 200){ + this.competition = res.data } - - } - }) - + }) + } + this.userInfo = getInfo() + // this.loadQuestion() + }, + watch:{ + confirm(val){ + if(val){ + this.startExam() + } + } }, components:{ "cutDown": CutDown, - "tz-footer": Footer + "tz-footer": Footer, + 'tz-dialog': ConfirmDialog } } </script> <style scoped> +.tz-line-dash{ + border: none; + border-top: 1px dotted #ccc; +} +.anli_title{ + text-align: left; + font-weight: bold; + color: black; + margin-bottom: 1rem; +} +.anli_sub_title{ + color: #536073; + text-align: left; + margin-bottom: 1rem; +} .tz-exam-header{ background-image: url('/static/image/answer_topbg_1990x140.jpg'); background-size: cover; diff --git a/front/src/views/system/index.vue b/front/src/views/system/index.vue index 31c015d..4820572 100644 --- a/front/src/views/system/index.vue +++ b/front/src/views/system/index.vue @@ -105,7 +105,7 @@ <div> <b-img src="/static/image/system_icon11.png"/> <span> 欢迎</span> - <span>王灿灿</span> + <span>{{ userInfo.name}}</span> </div> <div> <b-img src="/static/image/system_icon12.png" /> @@ -324,7 +324,8 @@ import Footer from '@/components/footer' import Quotation from './quotation.vue' import Portrait from './portrait.vue' -import * as echarts from 'echarts'; +import * as echarts from 'echarts' +import { getInfo } from '@/utils/auth' export default { components:{ 'tz-footer': Footer, @@ -374,6 +375,7 @@ export default { }, data(){ return{ + userInfo: null, tabId: 0, list:[ ], @@ -381,6 +383,7 @@ export default { } }, created(){ + this.userInfo = getInfo() for(var i = 0 ;i<50;i++){ this.list.push({ name: '王先生', diff --git a/front/src/views/system/portrait.vue b/front/src/views/system/portrait.vue index a724526..3d7a919 100644 --- a/front/src/views/system/portrait.vue +++ b/front/src/views/system/portrait.vue @@ -6,7 +6,7 @@ <div> <b-img src="/static/image/system_icon11.png"/> <span> 欢迎</span> - <span>王灿灿</span> + <span>{{userInfo.name}}</span> </div> <div> <b-img src="/static/image/system_icon12.png" /> @@ -132,9 +132,11 @@ </template> <script> import * as echarts from 'echarts'; +import { getInfo } from '@/utils/auth' export default { data(){ return { + userInfo: null, positionCharts: null, profitCharts: null, heavyCharts: null, @@ -184,13 +186,7 @@ export default { this.drawInvestAfter() this.drawTradeCount() }) - - }, - beforeUpdate(){ - console.log("beforeUpdate") - }, - updated(){ - console.log("updated") + this.userInfo = getInfo() }, methods:{ draw(){ diff --git a/tz/competition/competition-service/src/main/java/com/tz/platform/competitiion/api/biz/CompetitionExamBiz.java b/tz/competition/competition-service/src/main/java/com/tz/platform/competitiion/api/biz/CompetitionExamBiz.java index 5ba2f93..3216e92 100644 --- a/tz/competition/competition-service/src/main/java/com/tz/platform/competitiion/api/biz/CompetitionExamBiz.java +++ b/tz/competition/competition-service/src/main/java/com/tz/platform/competitiion/api/biz/CompetitionExamBiz.java @@ -1,19 +1,35 @@ package com.tz.platform.competitiion.api.biz; +import com.tz.platform.common.core.base.Result; +import com.tz.platform.common.core.bo.GroupCat; +import com.tz.platform.common.core.bo.SubQuestionVO; +import com.tz.platform.common.core.tools.BeanUtils; +import com.tz.platform.common.core.tools.DateUtil; +import com.tz.platform.competitiion.api.dto.ExamDTO; +import com.tz.platform.competitiion.api.dto.SubmitResultDTO; +import com.tz.platform.competitiion.api.vo.SubmitQuestionVO; +import com.tz.platform.competitiion.api.vo.SubmitVo; +import com.tz.platform.entity.CompetitionGroup; +import com.tz.platform.entity.CompetitionMember; import com.tz.platform.entity.CompetitionTask; +import com.tz.platform.entity.ExamPaper; import com.tz.platform.feign.exam.IFeignExam; -import com.tz.platform.feign.exam.qo.CacheQuetionQO; -import com.tz.platform.feign.exam.qo.QuestionQO; +import com.tz.platform.feign.exam.qo.CacheQuestionQO; import com.tz.platform.feign.exam.vo.QuestionVo; import com.tz.platform.feign.user.IFeignUser; import com.tz.platform.feign.user.vo.UserVo; import com.tz.platform.repository.CompetitionGroupDao; +import com.tz.platform.repository.CompetitionMemberDao; import com.tz.platform.repository.CompetitionTaskDao; +import com.tz.platform.repository.ExamPaperDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; +import java.util.Date; import java.util.List; +import java.util.stream.Collectors; @Component public class CompetitionExamBiz { @@ -27,19 +43,37 @@ public class CompetitionExamBiz { @Autowired private CompetitionGroupDao groupDao; + @Autowired + private CompetitionMemberDao competitionMemberDao; + + @Autowired + private ExamPaperDao examPaperDao; + @Autowired private IFeignExam feignExam; public List<QuestionVo> getExamQuestion(Long compId,Integer stageId,Long userId){ - + UserVo currentUser = feignUser.getByUserNo(userId); CompetitionTask task = competitionTaskDao.getByCompetitionIdAndStageId(compId,stageId); - + List<CompetitionGroup> groupList = groupDao.findByCompetitionId(compId); + //学生层次限制 + List<CompetitionGroup> limitList = groupList.stream().filter(g->g.getLimitType() == 1).collect(Collectors.toList()); List<Long> ids = new ArrayList<>(); task.getQuestionList().forEach(taskQuestion -> { - ids.addAll(taskQuestion.getQuestionIds()); + if(taskQuestion.getGroupId().equals(0)){ + ids.addAll(taskQuestion.getQuestionIds()); + }else{ + //不同学生层次不同案例题 + CompetitionGroup group = limitList.stream().filter(g->g.getId() .equals(taskQuestion.getGroupId())).findFirst().orElse(null); + if(group!=null) { + GroupCat groupCat = group.getCatList().stream().filter(groupCat1 -> groupCat1.getId().equals(currentUser.getLevelId())).findFirst().orElse(null); + if (groupCat != null) { + ids.addAll(taskQuestion.getQuestionIds()); + } + } + } }); - - CacheQuetionQO qo = new CacheQuetionQO(); + CacheQuestionQO qo = new CacheQuestionQO(); qo.setIds(ids); List<QuestionVo> questionVos = feignExam.listQusetion(qo); return questionVos; @@ -48,7 +82,117 @@ public class CompetitionExamBiz { private List<QuestionVo> getQList(List<QuestionVo> qList,Long userId){ UserVo userVo = feignUser.getByUserNo(userId); System.out.println(userVo.getLevelId()); - return null; } + + @Transactional + public Result<ExamDTO> startExam(Long compId, Integer stageId, Long userNo){ + CompetitionMember member = competitionMemberDao.getByCompetitionIdAndStageIdAndUserId(compId,stageId,userNo); + if(member == null){ + return Result.error("未报名该大赛或赛段"); + } + if(member.getExamStartTime()!=null){ + ExamDTO dto = new ExamDTO(); + dto.setStartTime(member.getExamStartTime()); + dto.setEndTime(DateUtil.addHours(member.getExamStartTime(),1)); + return Result.success(dto); + } + + Date examStartTime = new Date(); + Date examEndTime = DateUtil.addHours(examStartTime,1); + int affect = competitionMemberDao.updateExamStartTime(userNo,stageId,compId,examStartTime); + if(affect>0){ + ExamDTO dto = new ExamDTO(); + dto.setStartTime(examStartTime); + dto.setEndTime(examEndTime); + return Result.success(dto); + } + return Result.error("failed"); + } + + @Transactional + public Result<SubmitResultDTO> submit(SubmitVo vo){ + Date now = new Date(); + CompetitionMember member = competitionMemberDao.getByCompetitionIdAndStageIdAndUserId(vo.getCompId(),vo.getStageId(),vo.getUserNo()); + if(member.getExamScore()!=null){ + SubmitResultDTO dto = new SubmitResultDTO(); + dto.setScore(member.getExamScore()); + return Result.success(dto); + } + + Long costTime =now.getTime() - member.getExamStartTime().getTime(); + if(costTime >3600000){ + return Result.error("考试超时"); + } + CompetitionTask task = competitionTaskDao.getByCompetitionIdAndStageId(vo.getCompId(),vo.getStageId()); + if(task.getExamEndTime().getTime()<now.getTime()){ + return Result.error("考试超时"); + } + + SubmitResultDTO dto = new SubmitResultDTO(); + List<QuestionVo> questionVoList = getExamQuestion(vo.getCompId(),vo.getStageId(),vo.getUserNo()); + Long score = computeScore(questionVoList,vo.getQList()); + competitionMemberDao.updateScore(vo.getUserNo(),vo.getStageId(),vo.getCompId(),score); + competitionMemberDao.updateExamEndTimeAndCostTime(vo.getUserNo(),vo.getStageId(),vo.getCompId(),now,costTime); + ExamPaper paper = BeanUtils.copyProperties(vo,ExamPaper.class); + paper.setId(paper.getCompId()+"_"+paper.getStageId()+"_"+paper.getUserNo()); + examPaperDao.save(paper); + dto.setScore(score); + return Result.success(dto); + } + + //计算得分 + private Long computeScore(List<QuestionVo> questionVoList, List<SubmitQuestionVO> submitQuestionVOS){ + Long totalScore = 0L; + for(int j = 0;j< submitQuestionVOS.size();j++) + { + SubmitQuestionVO submitQuestionVO = submitQuestionVOS.get(j); + QuestionVo q = questionVoList.stream().filter(questionVo -> questionVo.getId().equals(submitQuestionVO.getId())).findFirst().orElse(null); + if(q == null) { continue; } + if(q.getType() == 0){ + //普通题 + if(checkCorrect(q.getAnswerId(),submitQuestionVO.getIds())){ + totalScore += q.getScore(); + } +// if(q.getAnswerId().size() == submitQuestionVO.getIds().size()){ +// boolean crorrect = true; +// for(int i = 0 ;i <submitQuestionVO.getIds().size();i++){ +// if(q.getAnswerId().indexOf(submitQuestionVO.getIds().get(i))<0){ +// crorrect = false; +// break; +// } +// } +// if(crorrect){ +// totalScore+= q.getScore(); +// } +// +// } + }else{ + //案例题 + SubQuestionVO subQuestionVO = q.getChildren().stream().filter(subQuestionVO1 -> subQuestionVO1.getId().intValue() == submitQuestionVO.getSubId()).findFirst().orElse(null); + if(subQuestionVO == null) { + continue; + } + if(checkCorrect(subQuestionVO.getAnswerId(),submitQuestionVO.getIds())){ + totalScore += subQuestionVO.getScore(); + } + } + } + return totalScore; + } + + private boolean checkCorrect(List<Integer> answerId,List<Integer> checkList){ + if(checkList ==null&&checkList.size() == 0) {return false;} + if(answerId.size() == checkList.size()){ + boolean correct = true; + for(int i = 0 ;i <checkList.size();i++){ + if(answerId.indexOf(checkList.get(i))<0){ + correct = false; + break; + } + } + return correct; + } + return false; + } }