Merge branch 'master' of https://e.coding.net/ctcdevteam/cma_search
This commit is contained in:
commit
4d352a1773
|
|
@ -3,4 +3,5 @@ ENV = 'production'
|
|||
|
||||
# base api
|
||||
VUE_APP_BASE_API = 'https://testsearch.ctc.ac.cn/api'
|
||||
#VUE_APP_BASE_API = 'http://47.95.0.242:2222/api'
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
"dependencies": {
|
||||
"@riophae/vue-treeselect": "^0.4.0",
|
||||
"axios": "0.18.1",
|
||||
"echarts": "^5.4.0",
|
||||
"element-china-area-data": "^5.0.2",
|
||||
"element-ui": "2.13.0",
|
||||
"file-saver": "^2.0.2",
|
||||
|
|
|
|||
|
|
@ -155,6 +155,13 @@ export function updateQtask(id,data) {
|
|||
})
|
||||
}
|
||||
|
||||
export function deleteQtask(id) {
|
||||
return request({
|
||||
url:`/ability/qtask/${id}/`,
|
||||
method:'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function qtaskStart(id) {
|
||||
return request({
|
||||
url:`/ability/qtask/${id}/start/`,
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export function getVideoPlayCode(id) {
|
|||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//已弃用
|
||||
export function getMyView(id, data) {
|
||||
return request({
|
||||
url: `/vod/video/${id}/myview/`,
|
||||
|
|
@ -57,7 +57,7 @@ export function getMyView(id, data) {
|
|||
data
|
||||
})
|
||||
}
|
||||
|
||||
//已弃用
|
||||
export function refreshMyView(id, data) {
|
||||
return request({
|
||||
url: `/vod/video/${id}/myview/`,
|
||||
|
|
@ -65,3 +65,92 @@ export function refreshMyView(id, data) {
|
|||
data
|
||||
})
|
||||
}
|
||||
|
||||
//开始播放
|
||||
export function videoStart(id) {
|
||||
return request({
|
||||
url: `/vod/video/${id}/start/`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
//观看统计
|
||||
export function videoView2(data) {
|
||||
return request({
|
||||
url: `/vod/view2/`,
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
//我的观看统计
|
||||
export function myVideoView2(data) {
|
||||
return request({
|
||||
url: `/vod/view2/my/`,
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
//观看记录
|
||||
export function viewItem(data) {
|
||||
return request({
|
||||
url: `/vod/viewitem/`,
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
//我的观看记录
|
||||
export function myViewItem(data) {
|
||||
return request({
|
||||
url: `/vod/viewitem/my/`,
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
//更新观看记录
|
||||
export function refreshViewItem(id, data) {
|
||||
return request({
|
||||
url: `/vod/viewitem/${id}/`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//本视频的我的观看统计
|
||||
export function myView(id) {
|
||||
return request({
|
||||
url: `/vod/video/${id}/my/`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
//播放完成
|
||||
export function viewItemComplete(id) {
|
||||
return request({
|
||||
url: `/vod/viewitem/${id}/complete/`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//单位观看量统计
|
||||
export function groupByOrgView(data) {
|
||||
return request({
|
||||
url: '/vod/analyse/group_by_org_view/',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
//个人观看量统计
|
||||
export function groupByUserView(data) {
|
||||
return request({
|
||||
url: '/vod/analyse/group_by_user_view/',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
//视频大类播放量统计
|
||||
export function groupByCategoryView(data) {
|
||||
return request({
|
||||
url: '/vod/analyse/group_by_video_category_big/',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -300,12 +300,19 @@ export const asyncRoutes = [
|
|||
meta: { title: '上传视频', perms: ['video_create'] }
|
||||
},
|
||||
{
|
||||
path: 'index/:id',
|
||||
name: 'Index',
|
||||
path: 'index',
|
||||
name: 'index',
|
||||
component: () => import('@/views/testvideo/index.vue'),
|
||||
meta: { title: '视频播放', perms: ['video_view'] },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'videoStatistics',
|
||||
name: 'videoStatistics',
|
||||
component: () => import('@/views/testvideo/videoStatistics.vue'),
|
||||
meta: { title: '视频播放统计', perms: ['video_view'] },
|
||||
// hidden: true
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -289,11 +289,11 @@
|
|||
label-position="right"
|
||||
:rules="rule"
|
||||
>
|
||||
<el-form-item label="资质认定" prop="type">
|
||||
<el-form-item label="资质名称" prop="type">
|
||||
<el-select
|
||||
style="width: 100%;"
|
||||
v-model="qualiForm.type"
|
||||
placeholder="资质认定"
|
||||
placeholder="资质名称"
|
||||
@change="qualiTypeChange"
|
||||
>
|
||||
<el-option
|
||||
|
|
@ -304,8 +304,8 @@
|
|||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="资质名称" prop="name" v-if="qualiForm.type==='OTHER'">
|
||||
<el-input v-model="qualiForm.name" placeholder="资质名称"/>
|
||||
<el-form-item label="具体名称" prop="name" v-if="qualiForm.type==='OTHER'">
|
||||
<el-input v-model="qualiForm.name" placeholder="具体名称"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="资质类型" v-if="qualiForm.type==='CMA'">
|
||||
<el-select
|
||||
|
|
@ -494,11 +494,11 @@
|
|||
label-position="right"
|
||||
:rules="rule"
|
||||
>
|
||||
<el-form-item label="资质认定" prop="type">
|
||||
<el-form-item label="资质名称" prop="type">
|
||||
<el-select
|
||||
style="width: 100%;"
|
||||
v-model="qualiForm.type"
|
||||
placeholder="资质认定"
|
||||
placeholder="资质名称"
|
||||
@change="qualiTypeChange"
|
||||
>
|
||||
<el-option
|
||||
|
|
@ -509,8 +509,8 @@
|
|||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="资质名称" prop="name" v-if="qualiForm.type==='OTHER'">
|
||||
<el-input v-model="qualiForm.name" placeholder="资质名称"/>
|
||||
<el-form-item label="具体名称" prop="name" v-if="qualiForm.type==='OTHER'">
|
||||
<el-input v-model="qualiForm.name" placeholder="具体名称"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="资质类型" v-if="qualiForm.type==='CMA'">
|
||||
<el-select
|
||||
|
|
@ -734,7 +734,7 @@
|
|||
cityLists,
|
||||
qactionItem,
|
||||
qualiNoChange,
|
||||
abilityNoChange
|
||||
abilityNoChange,
|
||||
} from "@/api/ability";
|
||||
import {getDictList} from "@/api/dict";
|
||||
import {genTree} from "@/utils";
|
||||
|
|
|
|||
|
|
@ -65,18 +65,23 @@
|
|||
size="small"
|
||||
@click="handleClick(scope)"
|
||||
>执行</el-link>
|
||||
<!-- <el-link
|
||||
v-if="scope.row.state==='待发布'"
|
||||
<el-link
|
||||
v-if="scope.row.state!='已关闭'"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link>-->
|
||||
>编辑</el-link>
|
||||
<el-link
|
||||
v-if="scope.row.state==='待发布'"
|
||||
type="warning"
|
||||
size="small"
|
||||
@click="handleStart(scope)"
|
||||
>发布</el-link>
|
||||
<el-link
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="handleDelete(scope)"
|
||||
>删除</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -135,7 +140,7 @@
|
|||
|
||||
<script>
|
||||
import { getOrgList } from "@/api/org";
|
||||
import {getQtask,createQtask,updateQtask,qtaskStart} from "@/api/ability";
|
||||
import {getQtask,createQtask,updateQtask,qtaskStart, deleteQtask} from "@/api/ability";
|
||||
import {genTree} from "@/utils";
|
||||
import checkPermission from "@/utils/permission";
|
||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||
|
|
@ -280,6 +285,22 @@
|
|||
resetFilter() {
|
||||
this.pageForm.search = '';
|
||||
this.getQtaskList();
|
||||
},
|
||||
//删除操作
|
||||
handleDelete(scope) {
|
||||
let that = this;
|
||||
that.$confirm("确认删除吗?", "提示")
|
||||
.then(async () => {
|
||||
await deleteQtask(scope.row.id).then(res => {
|
||||
if (res.code >= 200 && res.code < 400) {
|
||||
that.getQtaskList();
|
||||
that.$message.success("成功");
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -364,7 +364,8 @@
|
|||
atypeOptions: {},
|
||||
afieldOptions: {},
|
||||
atype_name:'',
|
||||
afield_name:''
|
||||
afield_name:'',
|
||||
item:{}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
|
@ -422,6 +423,7 @@
|
|||
},
|
||||
//操作处理
|
||||
handleRecord(type, item) {
|
||||
this.item = item
|
||||
this.showData.id = item.id;
|
||||
this.showData.data = item;
|
||||
this.showData.type = item.action;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-container>
|
||||
<el-header style="height: 80px;padding: 0">
|
||||
<el-header style="height: 80px;padding: 0;position: absolute;">
|
||||
<el-row class="biaotou">
|
||||
<el-col :span="20" style="text-align:center;color:seashell;font-size:32px;line-height: 70px;">
|
||||
{{ video.name }}
|
||||
|
|
@ -8,7 +8,9 @@
|
|||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="margin-top: 70px;">
|
||||
<div style="margin:20px 12%;">
|
||||
<el-row>
|
||||
<el-col :sm="24" :lg="15" :xl="13">
|
||||
<div style="margin:20px;">
|
||||
<div class="content">
|
||||
<video
|
||||
:id="tcPlayerId"
|
||||
|
|
@ -26,8 +28,8 @@
|
|||
<el-col class="firstLineDetail">
|
||||
<div class="firstLineText">{{ video.name }}</div>
|
||||
<div>
|
||||
<el-button class="firstLineBtn" type="error" icon="el-icon-view">{{video.views}}</el-button>
|
||||
<el-button class="firstLineBtn" type="error" icon="el-icon-s-custom">{{video.viewsp}}</el-button>
|
||||
<el-button class="firstLineBtn" type="error" icon="el-icon-view">{{video.views_n}}</el-button>
|
||||
<el-button class="firstLineBtn" type="error" icon="el-icon-s-custom">{{video.viewsp_n}}</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
<div style="font-size: 15px">
|
||||
|
|
@ -35,11 +37,27 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :sm="24" :lg="9" :xl="11">
|
||||
<div style="margin:20px;height:calc(100% - 140px);">
|
||||
<p class="firstLineText">观看记录:</p>
|
||||
<div class="viewRecordList">
|
||||
<div class="viewRecordItemWrap" v-for="item in recordList" :key="item.id"
|
||||
@click="recordItemPlay(item.video)">
|
||||
<div class="recordName" v-if="item.video_"><span>{{item.video_.name}}</span></div>
|
||||
<div class="viewInfo">上次观看时间:<span class="viewInfo_tiem">{{item.update_time}}</span></div>
|
||||
<div class="viewInfo">上次观看进度:<span class="viewInfo_current">{{item.current}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div></el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
</el-main>
|
||||
</el-container>
|
||||
</template>
|
||||
<script>
|
||||
import {getVideo, getMyView,refreshMyView, getVideoPlayCode} from "@/api/video";
|
||||
import {getVideo,videoStart,myViewItem, myView,getMyView,refreshViewItem, getVideoPlayCode,viewItemComplete} from "@/api/video";
|
||||
export default {
|
||||
name: 'TencentPlayer',
|
||||
props: {
|
||||
|
|
@ -60,9 +78,12 @@
|
|||
video: {id: 0},
|
||||
description: '',
|
||||
name: '',
|
||||
videoFileid:false,
|
||||
userName:"",
|
||||
playTimer:null,
|
||||
isFirstView:true,
|
||||
id:'',
|
||||
videoViId:'',
|
||||
recordList:[],
|
||||
};
|
||||
},
|
||||
mounted(){
|
||||
|
|
@ -70,44 +91,52 @@
|
|||
if(this.player!==null){
|
||||
this.player.null;
|
||||
}
|
||||
if(this.$route.params.id){
|
||||
this.id = this.$route.params.id;
|
||||
this.videoFileId = this.$route.params.fileid;
|
||||
if(this.$route.query.id){
|
||||
this.id = this.$route.query.id;
|
||||
let videoId = sessionStorage.getItem('videoId');
|
||||
let videoFileId = sessionStorage.getItem('videoFileId');
|
||||
if(videoId){
|
||||
if(videoId!==undefined&&videoId!==null&&videoId!==''){
|
||||
sessionStorage.removeItem('videoId');
|
||||
sessionStorage.setItem('videoId',this.$route.params.id);
|
||||
}else{
|
||||
sessionStorage.setItem('videoId',this.$route.params.id);
|
||||
}
|
||||
if(videoFileId){
|
||||
sessionStorage.removeItem('videoFileId');
|
||||
sessionStorage.setItem('videoFileId',this.$route.params.fileid);
|
||||
}else{
|
||||
sessionStorage.setItem('videoFileId',this.$route.params.fileid);
|
||||
}
|
||||
}else{
|
||||
this.id = sessionStorage.getItem('videoId');
|
||||
this.videoFileId = sessionStorage.getItem('videoFileId');
|
||||
}
|
||||
this.getPlayCode(this.videoFileId);
|
||||
this.getVideo();
|
||||
this.clicknub();
|
||||
this.getMyVideoView();
|
||||
},
|
||||
|
||||
methods: {
|
||||
//获取视频详情
|
||||
getVideo() {
|
||||
getVideo(this.id).then((response) => {
|
||||
let that = this;
|
||||
getVideo(that.id).then((response) => {
|
||||
if (response.data) {
|
||||
this.video = response.data;
|
||||
that.video = response.data;
|
||||
that.videoFileId = response.data.fileid;
|
||||
that.getPlayCode(response.data.fileid);
|
||||
}
|
||||
this.listLoading = false;
|
||||
that.listLoading = false;
|
||||
});
|
||||
},
|
||||
//获取饿哦的观看记录
|
||||
getMyVideoView() {
|
||||
let that = this;
|
||||
myViewItem().then((response) => {
|
||||
if (response.data) {
|
||||
that.recordList = response.data.results;
|
||||
// debugger;
|
||||
console.log(that.recordList)
|
||||
}
|
||||
});
|
||||
},
|
||||
//获取播放码
|
||||
getPlayCode(id){
|
||||
let that = this;
|
||||
getVideoPlayCode(id).then(res=>{
|
||||
if(res.data){
|
||||
that.videoFileid = true;
|
||||
that.videoPsign = res.data.psign;
|
||||
that.initVideo();
|
||||
}
|
||||
|
|
@ -115,13 +144,17 @@
|
|||
},
|
||||
//视频观看次数
|
||||
clicknub() {
|
||||
getMyView(this.id).then((response) => {});
|
||||
myView(this.id).then((response) => {
|
||||
// debugger;
|
||||
console.log(response.data);
|
||||
});
|
||||
},
|
||||
//初始化视频播放器
|
||||
initVideo() {
|
||||
let that = this;
|
||||
getMyView(that.id,{}).then((response) => {
|
||||
debugger;
|
||||
console.log(response.data);
|
||||
// debugger;
|
||||
// console.log(response.data);
|
||||
let current = response.data.current;
|
||||
let playerParm = {
|
||||
fileID: that.videoFileId,
|
||||
|
|
@ -132,7 +165,10 @@
|
|||
speed: 0.1,
|
||||
content: "用户:"+that.userName
|
||||
},
|
||||
}
|
||||
},
|
||||
controlBar:{
|
||||
playbackRateMenuButton:false
|
||||
},
|
||||
};
|
||||
if (!that.player) {
|
||||
that.player = window.TCPlayer(that.tcPlayerId, playerParm);
|
||||
|
|
@ -143,39 +179,72 @@
|
|||
that.player.currentTime(current);
|
||||
//视频播放
|
||||
that.player.on('play', function(error) {
|
||||
// debugger;
|
||||
if(that.playTimer!==null){
|
||||
clearInterval(that.playTimer);
|
||||
that.playTimer = null;
|
||||
}
|
||||
if(that.isFirstView){
|
||||
that.isFirstView = false;
|
||||
videoStart(that.id).then(ews=>{
|
||||
// debugger;
|
||||
that.videoViId = ews.data.vi;
|
||||
})
|
||||
}
|
||||
that.playTimer = setInterval(function(){
|
||||
let currentTimeNum = 0;
|
||||
currentTimeNum = that.player.currentTime();
|
||||
console.log(currentTimeNum);
|
||||
refreshMyView(that.id,{current:currentTimeNum}).then((response) => {});
|
||||
refreshViewItem(that.videoViId,{current:currentTimeNum,seconds:10})
|
||||
.then((response) => {})
|
||||
.catch(response=>{
|
||||
debugger;
|
||||
clearInterval(that.playTimer);
|
||||
that.playTimer = null;
|
||||
that.player.pause();
|
||||
});
|
||||
},10000)
|
||||
});
|
||||
//视频暂停
|
||||
that.player.on('pause', function(error) {
|
||||
let currentTimeNum = 0;
|
||||
currentTimeNum = that.player.currentTime();
|
||||
console.log(currentTimeNum);
|
||||
refreshMyView(that.id,{current:currentTimeNum}).then((response) => {});
|
||||
refreshViewItem(that.videoViId,{current:currentTimeNum,seconds:0}).then((response) => {
|
||||
|
||||
});
|
||||
clearInterval(that.playTimer);
|
||||
that.playTimer = null;
|
||||
});
|
||||
//视频观看中
|
||||
that.player.on('playing', function(error) {
|
||||
|
||||
});
|
||||
//视频播放已结束时触发,此时 currentTime 值等于媒体资源最大值。
|
||||
that.player.on('ended', function(error) {
|
||||
viewItemComplete(that.videoViId).then(res=>{
|
||||
})
|
||||
});
|
||||
});
|
||||
},
|
||||
recordItemPlay(id){
|
||||
debugger;
|
||||
let routeData = this.$router.resolve({
|
||||
path: "/test/index",
|
||||
query: {
|
||||
id: id
|
||||
}
|
||||
});
|
||||
|
||||
//必要操作,否则不会打开新页面
|
||||
window.open(routeData.href, '_blank');
|
||||
},
|
||||
},
|
||||
|
||||
beforeDestroy () {
|
||||
let that = this;
|
||||
if(that.playTimer!==null){
|
||||
clearInterval(that.playTimer);
|
||||
that.playTimer = null;
|
||||
}
|
||||
this.player.dispose()
|
||||
that.player.dispose()
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -188,7 +257,7 @@
|
|||
color: #333;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
position: fixed;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: 1010;
|
||||
}
|
||||
|
|
@ -239,4 +308,30 @@
|
|||
border: 1px solid #e74e4e;
|
||||
border-radius: 15px;
|
||||
}
|
||||
.viewRecordList{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.viewRecordItemWrap{
|
||||
margin: 10px 0;
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
.recordName{
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.viewInfo{
|
||||
font-size: 14px;
|
||||
color: #a2a2a2;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.viewInfo_tiem{
|
||||
color:#6090e6
|
||||
}
|
||||
.viewInfo_current{
|
||||
color:#86c793
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,610 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-card>
|
||||
<div style="margin-top:10px">
|
||||
<el-date-picker
|
||||
v-model="dataValue"
|
||||
type="daterange"
|
||||
align="right"
|
||||
unlink-panels
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:picker-options="pickerOptions"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
:default-time="['00:00:00', '23:59:59']">
|
||||
</el-date-picker>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleFilter">搜索</el-button>
|
||||
<div style="margin-top:10px"></div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card style="margin-top:10px">
|
||||
<div id="main" style="width:1000px;height:600px;margin-top: 50px;"></div>
|
||||
<div id="userMain" style="width:1000px;height:600px;margin-top: 50px;"></div>
|
||||
<div id="orgMain" style="width:1000px;height:600px;margin-top: 50px;"></div>
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import FileSaver from "file-saver";
|
||||
import XLSX from "xlsx";
|
||||
import { groupByCategoryView,groupByUserView,groupByOrgView } from '@/api/video'
|
||||
export default{
|
||||
data () {
|
||||
return {
|
||||
cateChart:null,
|
||||
userChart:null,
|
||||
orgChart:null,
|
||||
dataValue:'',
|
||||
dataQuery:{
|
||||
start_time:'',
|
||||
end_time:'',
|
||||
limit:500
|
||||
},
|
||||
pickerOptions: {
|
||||
shortcuts: [{
|
||||
text: '最近一天',
|
||||
onClick(picker) {
|
||||
let end = new Date();
|
||||
let start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24);
|
||||
picker.$emit('pick', [start, end]);
|
||||
}
|
||||
}, {
|
||||
text: '最近一周',
|
||||
onClick(picker) {
|
||||
let end = new Date();
|
||||
let start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
|
||||
picker.$emit('pick', [start, end]);
|
||||
}
|
||||
}, {
|
||||
text: '最近一个月',
|
||||
onClick(picker) {
|
||||
let end = new Date();
|
||||
let start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
||||
picker.$emit('pick', [start, end]);
|
||||
}
|
||||
}, {
|
||||
text: '最近三个月',
|
||||
onClick(picker) {
|
||||
let end = new Date();
|
||||
let start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
|
||||
picker.$emit('pick', [start, end]);
|
||||
}
|
||||
}]
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted(){
|
||||
let dateNow = new Date();
|
||||
let yeear = dateNow.getFullYear();
|
||||
let month = dateNow.getMonth()+1;
|
||||
let day = dateNow.getDate();
|
||||
this.dataQuery.start_time=yeear+'-'+month+'-'+'01 00:00:00';
|
||||
this.dataQuery.end_time=yeear+'-'+month+'-'+day+' 23:59:59';
|
||||
this.dataValue = [this.dataQuery.start_time,this.dataQuery.end_time];
|
||||
this.getCategoryView();
|
||||
this.getUserView();
|
||||
this.getGroupView();
|
||||
},
|
||||
methods: {
|
||||
getCategoryView(){
|
||||
groupByCategoryView(this.dataQuery).then(res=>{
|
||||
let data = res.data;
|
||||
let xAxisOptions = [],data1 = [],data2 = [],data3 = [];
|
||||
data.forEach(item=>{
|
||||
xAxisOptions.push(item.视频大类);
|
||||
data1.push(item.视频数量);
|
||||
data2.push(item.观看总次数);
|
||||
data3.push(item.观看总人数);
|
||||
})
|
||||
let chartDom = document.getElementById('main');
|
||||
this.cateChart = echarts.init(chartDom);
|
||||
let labelOption = {
|
||||
show: true,
|
||||
position: 'insideBottom',
|
||||
distance: 5,
|
||||
align: 'left',
|
||||
verticalAlign: 'middle',
|
||||
rotate: 90,
|
||||
formatter: '{c}',
|
||||
fontSize: 12,
|
||||
rich: {
|
||||
name: {}
|
||||
}
|
||||
};
|
||||
let option = {
|
||||
title: { text: '视频大类观看统计' },
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['视频数量', '观看总次数', '观看总人数']
|
||||
},
|
||||
toolbox: {
|
||||
show: true,
|
||||
orient: 'vertical',
|
||||
left: 'right',
|
||||
top: 'center',
|
||||
feature: {
|
||||
mark: { show: true },
|
||||
dataView: {
|
||||
show: true,
|
||||
title: '数据视图',
|
||||
lang: ['视频大类观看统计', '关闭', '导出Excel'], // 按钮
|
||||
contentToOption: function (opts) {
|
||||
$('#tableExcel').table2excel({
|
||||
exclude: '.noExl', //过滤位置的 css 类名, 有class = “noExl” 的行不被导出
|
||||
filename: '最大需量', // 文件名称
|
||||
name: 'Excel Document Name.xls',
|
||||
exclude_img: true,
|
||||
exclude_links: true,
|
||||
exclude_inputs: true
|
||||
})
|
||||
},
|
||||
optionToContent: function (opt) {
|
||||
var axisData = opt.xAxis[0].data //坐标轴
|
||||
var series = opt.series //折线图的数据
|
||||
console.log(series);
|
||||
var tdHeads =
|
||||
'<td style="margin-top:10px; padding: 0 15px">视频大类</td>' //表头
|
||||
var tdBodys = ''
|
||||
series.forEach(function (item) {
|
||||
tdHeads += `<td style="padding:5px 15px">${item.name}</td>`
|
||||
})
|
||||
var table = `<table id='table-content' border="1" style="margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center;"><tbody><tr>${tdHeads} </tr>`
|
||||
for (var i = 0, l = axisData.length; i < l; i++) {
|
||||
for (var j = 0; j < series.length; j++) {
|
||||
if (series[j].data[i] == undefined) {
|
||||
tdBodys += `<td>${'-'}</td>`
|
||||
} else {
|
||||
tdBodys += `<td>${series[j].data[i]}</td>`
|
||||
}
|
||||
}
|
||||
table += `<tr><td style="padding: 0 15px">${axisData[i]}</td>${tdBodys}</tr>`
|
||||
tdBodys = ''
|
||||
}
|
||||
table += '</tbody></table>'
|
||||
return table
|
||||
},
|
||||
contentToOption: function (HTMLDomElement, opt) {
|
||||
let et = XLSX.utils.table_to_book(
|
||||
document.getElementById("table-content")
|
||||
); //此处传入table的DOM节点
|
||||
let etout = XLSX.write(et, {
|
||||
bookType: "xlsx",
|
||||
bookSST: true,
|
||||
type: "array",
|
||||
});
|
||||
try {
|
||||
FileSaver.saveAs(
|
||||
new Blob([etout], {
|
||||
type: "application/octet-stream",
|
||||
}),
|
||||
"统计数据.xlsx"
|
||||
); //trade-publish.xlsx 为导出的文件名
|
||||
} catch (e) {
|
||||
}
|
||||
return etout;
|
||||
},
|
||||
},
|
||||
magicType: { show: true, type: ['line', 'stack'] },
|
||||
restore: { show: true },
|
||||
saveAsImage: { show: true }
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
axisTick: { show: false },
|
||||
data: xAxisOptions,
|
||||
axisLabel: {
|
||||
interval:0,
|
||||
rotate:60//角度顺时针计算的
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '视频数量',
|
||||
type: 'bar',
|
||||
barGap: 0,
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data1
|
||||
},
|
||||
{
|
||||
name: '观看总次数',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data2
|
||||
},
|
||||
{
|
||||
name: '观看总人数',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data3
|
||||
}
|
||||
]
|
||||
};
|
||||
this.cateChart.setOption(option);
|
||||
|
||||
})
|
||||
},
|
||||
getGroupView(){
|
||||
groupByOrgView(this.dataQuery).then(res=>{
|
||||
debugger;console.log(res.data)
|
||||
let data = res.data;
|
||||
let xAxisOptions = [],data1 = [],data2 = [],data3 = [],data4=[];
|
||||
data.forEach(item=>{
|
||||
xAxisOptions.push(item.单位名称);
|
||||
data1.push(item.观看完成视频总数);
|
||||
data2.push(item.观看视频总数);
|
||||
data3.push(item.观看总次数);
|
||||
data4.push(item.观看总时间);
|
||||
})
|
||||
let chartDom = document.getElementById('orgMain');
|
||||
this.orgChart = echarts.init(chartDom);
|
||||
let labelOption = {
|
||||
show: true,
|
||||
position: 'insideBottom',
|
||||
distance: 5,
|
||||
align: 'left',
|
||||
verticalAlign: 'middle',
|
||||
rotate: 90,
|
||||
formatter: '{c}',
|
||||
fontSize: 12,
|
||||
rich: {
|
||||
name: {}
|
||||
}
|
||||
};
|
||||
let option = {
|
||||
title: { text: '单位观看量统计' },
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['观看完成视频总数','观看视频总数', '观看总次数', '观看总时间']
|
||||
},
|
||||
toolbox: {
|
||||
show: true,
|
||||
orient: 'vertical',
|
||||
left: 'right',
|
||||
top: 'center',
|
||||
feature: {
|
||||
mark: { show: true },
|
||||
dataView: {
|
||||
show: true,
|
||||
title: '数据视图',
|
||||
lang: ['单位观看量统计', '关闭', '导出Excel'], // 按钮
|
||||
contentToOption: function (opts) {
|
||||
$('#tableExcel').table2excel({
|
||||
exclude: '.noExl', //过滤位置的 css 类名, 有class = “noExl” 的行不被导出
|
||||
filename: '最大需量', // 文件名称
|
||||
name: 'Excel Document Name.xls',
|
||||
exclude_img: true,
|
||||
exclude_links: true,
|
||||
exclude_inputs: true
|
||||
})
|
||||
},
|
||||
optionToContent: function (opt) {
|
||||
var axisData = opt.yAxis[0].data //坐标轴
|
||||
var series = opt.series //折线图的数据
|
||||
console.log(series);
|
||||
var tdHeads =
|
||||
'<td style="margin-top:10px; padding: 0 15px">视频大类</td>' //表头
|
||||
var tdBodys = ''
|
||||
series.forEach(function (item) {
|
||||
tdHeads += `<td style="padding:5px 15px">${item.name}</td>`
|
||||
})
|
||||
var table = `<table id='table-content' border="1" style="margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center;"><tbody><tr>${tdHeads} </tr>`
|
||||
for (var i = 0, l = axisData.length; i < l; i++) {
|
||||
for (var j = 0; j < series.length; j++) {
|
||||
if (series[j].data[i] == undefined) {
|
||||
tdBodys += `<td>${'-'}</td>`
|
||||
} else {
|
||||
tdBodys += `<td>${series[j].data[i]}</td>`
|
||||
}
|
||||
}
|
||||
table += `<tr><td style="padding: 0 15px">${axisData[i]}</td>${tdBodys}</tr>`
|
||||
tdBodys = ''
|
||||
}
|
||||
table += '</tbody></table>'
|
||||
return table
|
||||
},
|
||||
contentToOption: function (HTMLDomElement, opt) {
|
||||
let et = XLSX.utils.table_to_book(
|
||||
document.getElementById("table-content")
|
||||
); //此处传入table的DOM节点
|
||||
let etout = XLSX.write(et, {
|
||||
bookType: "xlsx",
|
||||
bookSST: true,
|
||||
type: "array",
|
||||
});
|
||||
try {
|
||||
FileSaver.saveAs(
|
||||
new Blob([etout], {
|
||||
type: "application/octet-stream",
|
||||
}),
|
||||
"统计数据.xlsx"
|
||||
); //trade-publish.xlsx 为导出的文件名
|
||||
} catch (e) {
|
||||
}
|
||||
return etout;
|
||||
},
|
||||
},
|
||||
magicType: { show: true, type: [ 'stack'] },
|
||||
restore: { show: true },
|
||||
saveAsImage: { show: true }
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
axisTick: { show: false },
|
||||
data: xAxisOptions,
|
||||
// axisLabel: {
|
||||
// interval:0,
|
||||
// rotate:60//角度顺时针计算的
|
||||
// }
|
||||
}
|
||||
],
|
||||
xAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '观看完成视频总数',
|
||||
type: 'bar',
|
||||
barGap: 0,
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data1
|
||||
},
|
||||
{
|
||||
name: '观看视频总数',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data2
|
||||
},
|
||||
{
|
||||
name: '观看总次数',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data3
|
||||
}
|
||||
,
|
||||
{
|
||||
name: '观看总时间',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data4
|
||||
}
|
||||
]
|
||||
};
|
||||
this.orgChart.setOption(option);
|
||||
|
||||
})
|
||||
},
|
||||
getUserView(){
|
||||
groupByUserView(this.dataQuery).then(res=>{
|
||||
debugger;
|
||||
console.log(res.data);
|
||||
let data = res.data;
|
||||
let xAxisOptions = [],data1 = [],data2 = [],data3 = [],data4=[];
|
||||
data.forEach(item=>{
|
||||
xAxisOptions.push(item.姓名);
|
||||
data1.push(item.观看完成视频总数);
|
||||
data2.push(item.观看视频总数);
|
||||
data3.push(item.观看总次数);
|
||||
data4.push(item.观看总时间);
|
||||
})
|
||||
let chartDom = document.getElementById('userMain');
|
||||
this.userChart = echarts.init(chartDom);
|
||||
let labelOption = {
|
||||
show: true,
|
||||
position: 'insideBottom',
|
||||
distance: 5,
|
||||
align: 'left',
|
||||
verticalAlign: 'middle',
|
||||
rotate: 90,
|
||||
formatter: '{c}',
|
||||
fontSize: 12,
|
||||
rich: {
|
||||
name: {}
|
||||
}
|
||||
};
|
||||
let option = {
|
||||
title: { text: '个人观看量统计' },
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['观看完成视频总数','观看视频总数', '观看总次数', '观看总时间']
|
||||
},
|
||||
toolbox: {
|
||||
show: true,
|
||||
orient: 'vertical',
|
||||
left: 'right',
|
||||
top: 'center',
|
||||
feature: {
|
||||
mark: { show: true },
|
||||
dataView: {
|
||||
show: true,
|
||||
title: '数据视图',
|
||||
lang: ['个人观看量统计', '关闭', '导出Excel'], // 按钮
|
||||
contentToOption: function (opts) {
|
||||
$('#tableExcel').table2excel({
|
||||
exclude: '.noExl', //过滤位置的 css 类名, 有class = “noExl” 的行不被导出
|
||||
filename: '最大需量', // 文件名称
|
||||
name: 'Excel Document Name.xls',
|
||||
exclude_img: true,
|
||||
exclude_links: true,
|
||||
exclude_inputs: true
|
||||
})
|
||||
},
|
||||
optionToContent: function (opt) {
|
||||
var axisData = opt.yAxis[0].data //坐标轴
|
||||
var series = opt.series //折线图的数据
|
||||
console.log(series);
|
||||
var tdHeads =
|
||||
'<td style="margin-top:10px; padding: 0 15px">视频大类</td>' //表头
|
||||
var tdBodys = ''
|
||||
series.forEach(function (item) {
|
||||
tdHeads += `<td style="padding:5px 15px">${item.name}</td>`
|
||||
})
|
||||
var table = `<table id='table-content' border="1" style="margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center;"><tbody><tr>${tdHeads} </tr>`
|
||||
for (var i = 0, l = axisData.length; i < l; i++) {
|
||||
for (var j = 0; j < series.length; j++) {
|
||||
if (series[j].data[i] == undefined) {
|
||||
tdBodys += `<td>${'-'}</td>`
|
||||
} else {
|
||||
tdBodys += `<td>${series[j].data[i]}</td>`
|
||||
}
|
||||
}
|
||||
table += `<tr><td style="padding: 0 15px">${axisData[i]}</td>${tdBodys}</tr>`
|
||||
tdBodys = ''
|
||||
}
|
||||
table += '</tbody></table>'
|
||||
return table
|
||||
},
|
||||
contentToOption: function (HTMLDomElement, opt) {
|
||||
let et = XLSX.utils.table_to_book(
|
||||
document.getElementById("table-content")
|
||||
); //此处传入table的DOM节点
|
||||
let etout = XLSX.write(et, {
|
||||
bookType: "xlsx",
|
||||
bookSST: true,
|
||||
type: "array",
|
||||
});
|
||||
try {
|
||||
FileSaver.saveAs(
|
||||
new Blob([etout], {
|
||||
type: "application/octet-stream",
|
||||
}),
|
||||
"统计数据.xlsx"
|
||||
); //trade-publish.xlsx 为导出的文件名
|
||||
} catch (e) {
|
||||
}
|
||||
return etout;
|
||||
},
|
||||
},
|
||||
magicType: { show: true, type: [ 'stack'] },
|
||||
restore: { show: true },
|
||||
saveAsImage: { show: true }
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
axisTick: { show: false },
|
||||
data: xAxisOptions,
|
||||
// axisLabel: {
|
||||
// interval:0,
|
||||
// rotate:60//角度顺时针计算的
|
||||
// }
|
||||
}
|
||||
],
|
||||
xAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '观看完成视频总数',
|
||||
type: 'bar',
|
||||
barGap: 0,
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data1
|
||||
},
|
||||
{
|
||||
name: '观看视频总数',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data2
|
||||
},
|
||||
{
|
||||
name: '观看总次数',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data3
|
||||
}
|
||||
,
|
||||
{
|
||||
name: '观看总时间',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: data4
|
||||
}
|
||||
]
|
||||
};
|
||||
this.userChart.setOption(option);
|
||||
})
|
||||
|
||||
},
|
||||
handleFilter(){
|
||||
this.cateChart.resize();
|
||||
this.userChart.resize();
|
||||
this.orgChart.resize();
|
||||
this.dataQuery.start_time = this.dataValue[0];
|
||||
this.dataQuery.end_time = this.dataValue[1];
|
||||
this.getCategoryView();
|
||||
this.getGroupView();
|
||||
this.getUserView();
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
@ -54,12 +54,12 @@
|
|||
<div class="bottom clearfix">
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-button type="warning" style="border: none;float: left;padding: 2px; color:#dcae07;background-color: white;" icon="el-icon-view">{{o.views}}
|
||||
<el-button type="warning" style="border: none;float: left;padding: 2px; color:#dcae07;background-color: white;" icon="el-icon-view">{{o.views_n}}
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-button type="warning" style="border: none;float: left;padding: 2px; color:#dcae07;
|
||||
background-color: white;" icon="el-icon-s-custom">{{o.viewsp}}
|
||||
background-color: white;" icon="el-icon-s-custom">{{o.viewsp_n}}
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
|
|
@ -182,7 +182,16 @@
|
|||
}else{
|
||||
sessionStorage.removeItem('videoType');
|
||||
}
|
||||
this.$router.push({name: "Index", params: {fileid: a.fileid, id: a.id}})
|
||||
let routeData = this.$router.resolve({
|
||||
path: "/test/index",
|
||||
query: {
|
||||
id: a.id
|
||||
}
|
||||
});
|
||||
|
||||
//必要操作,否则不会打开新页面
|
||||
window.open(routeData.href, '_blank');
|
||||
// this.$router.push({path: "index", query: {fileid: a.fileid, id: a.id}})
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -50,8 +50,10 @@ const install = (Vue, vm) => {
|
|||
let getExamList = (params={})=>vm.$u.get('/exam/exam/', params);//考试列表
|
||||
let startExam = (id)=>vm.$u.post(`/exam/exam/${id}/start/`);//开始考试
|
||||
let submitExam = (id,params={})=>vm.$u.post(`/exam/examrecord/${id}/submit/`,params);//开始考试
|
||||
let examRecord = (id,params={})=>vm.$u.get(`/exam/examrecord/self/`,params);//我的考试记录
|
||||
let examRecord = (id,params={})=>vm.$u.get(`/exam/examrecord/self/`,params);//我的考试记录
|
||||
let examRecordDetail = (id,params={})=>vm.$u.get(`/exam/examrecord/${id}/`,params);//我的考试记录
|
||||
let paperDetail = (id,params={})=>vm.$u.get(`/exam/paper/${id}/`,params);//测试
|
||||
let questionList = (params={})=>vm.$u.get(`/exam/question/`,params);//题目
|
||||
|
||||
vm.$u.api = {getUserInfo,
|
||||
getCode,
|
||||
|
|
@ -79,6 +81,8 @@ const install = (Vue, vm) => {
|
|||
startExam,
|
||||
submitExam,
|
||||
examRecord,
|
||||
paperDetail,
|
||||
questionList,
|
||||
examRecordDetail
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,6 +131,42 @@
|
|||
,{
|
||||
"path" : "pages/exam/index",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "考试",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
}
|
||||
,{
|
||||
"path" : "pages/exam/test",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "练习",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
}
|
||||
,{
|
||||
"path" : "pages/exam/question",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "专题练习",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
}
|
||||
,{
|
||||
"path" : "pages/exam/testDetail",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "练习题目",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
}
|
||||
,{
|
||||
"path" : "pages/exam/exam",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "考试列表",
|
||||
"enablePullDownRefresh": false
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
<template>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -1,6 +1,27 @@
|
|||
<template>
|
||||
<view>
|
||||
|
||||
<uni-list>
|
||||
<!-- 垂直排列,无略缩图,主标题+副标题显示 -->
|
||||
<uni-list-item direction="column" :key="item.id" v-for="(item, index) in examList">
|
||||
<template v-slot:header>
|
||||
<view class="uni-title">{{item.name}}</view>
|
||||
</template>
|
||||
<template v-slot:body>
|
||||
<view class="uni-list-box">
|
||||
<view class="uni-content">
|
||||
<view class="uni-title-sub uni-ellipsis-2">开启时间: {{item.open_time}}至{{item.close_time}}</view>
|
||||
<view class="uni-note">考试机会: {{item.chance}}次</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<view class="uni-footer">
|
||||
<u-button size="mini" type="primary" @click="attendExam(item)">我要参加</u-button>
|
||||
<u-button size="mini" type="info">成绩排名</u-button>
|
||||
</view>
|
||||
</template>
|
||||
</uni-list-item>
|
||||
</uni-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
|
@ -8,11 +29,28 @@
|
|||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
query:{
|
||||
page: 1
|
||||
},
|
||||
examList: []
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getExamList();
|
||||
},
|
||||
methods: {
|
||||
|
||||
getExamList(){
|
||||
this.$u.api.getExamList(this.query).then(res=>{
|
||||
this.examList = res.data.results
|
||||
})
|
||||
},
|
||||
attendExam(val){
|
||||
console.log(val)
|
||||
uni.setStorageSync('currentExam', val)
|
||||
uni.navigateTo({
|
||||
url:"/pages/exam/preview"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,11 @@
|
|||
<template>
|
||||
<view>
|
||||
<uni-list>
|
||||
<!-- 垂直排列,无略缩图,主标题+副标题显示 -->
|
||||
<uni-list-item direction="column" :key="item.id" v-for="(item, index) in examList">
|
||||
<template v-slot:header>
|
||||
<view class="uni-title">{{item.name}}</view>
|
||||
</template>
|
||||
<template v-slot:body>
|
||||
<view class="uni-list-box">
|
||||
<view class="uni-content">
|
||||
<view class="uni-title-sub uni-ellipsis-2">开启时间: {{item.open_time}}至{{item.close_time}}</view>
|
||||
<view class="uni-note">考试机会: {{item.chance}}次</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<view class="uni-footer">
|
||||
<u-button size="mini" type="primary" @click="attendExam(item)">我要参加</u-button>
|
||||
<u-button size="mini" type="info">成绩排名</u-button>
|
||||
</view>
|
||||
</template>
|
||||
</uni-list-item>
|
||||
</uni-list>
|
||||
<view class="cellWrap">
|
||||
<view class="cellItem" v-for="item in cellList" :index="item.id" :key="item.id" @click="intoPage(item)">
|
||||
<image class="cellImg" :src="item.img"></image>
|
||||
<text class="cellText">{{item.title}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
|
@ -32,29 +16,79 @@
|
|||
query:{
|
||||
page: 1
|
||||
},
|
||||
examList: []
|
||||
cellList: [
|
||||
{img:'../../static/exam/exam.png',title:'正式考试',id:'exam'},
|
||||
{img:'../../static/exam/test.png',title:'模拟测试',id:'test'},
|
||||
{img:'../../static/exam/question.png',title:'专题练习',id:'question'},
|
||||
{img:'../../static/exam/errorIcon.png',title:'错题记录',id:'record'},
|
||||
]
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getExamList();
|
||||
},
|
||||
methods: {
|
||||
getExamList(){
|
||||
this.$u.api.getExamList(this.query).then(res=>{
|
||||
this.examList = res.data.results
|
||||
})
|
||||
},
|
||||
attendExam(val){
|
||||
console.log(val)
|
||||
uni.setStorageSync('currentExam', val)
|
||||
uni.navigateTo({
|
||||
url:"/pages/exam/preview"
|
||||
})
|
||||
intoPage(item){
|
||||
switch (item.id){
|
||||
case 'exam':
|
||||
uni.navigateTo({
|
||||
url:"/pages/exam/exam"
|
||||
})
|
||||
break;
|
||||
case 'test':
|
||||
uni.navigateTo({
|
||||
url:"/pages/exam/test"
|
||||
})
|
||||
break;
|
||||
case 'question':
|
||||
uni.navigateTo({
|
||||
url:"/pages/exam/question"
|
||||
})
|
||||
break;
|
||||
case 'erroRrecord':
|
||||
uni.navigateTo({
|
||||
url:"/pages/exam/erroRrecord"
|
||||
})
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.cellWrap{
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
margin: auto;
|
||||
margin-top: 30upx;
|
||||
margin-bottom: 30upx;
|
||||
justify-content: space-evenly;
|
||||
|
||||
}
|
||||
.cellItem{
|
||||
width: 35%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
margin-top: 50upx;
|
||||
}
|
||||
.cellImg{
|
||||
margin: auto;
|
||||
width: 120upx;
|
||||
height: 120upx;
|
||||
}
|
||||
.cellText{
|
||||
height: 60upx;
|
||||
line-height: 60upx;
|
||||
text-align: center;
|
||||
color: #339900;
|
||||
}
|
||||
.cellItem:nth-of-type(2) .cellText{
|
||||
color: #efb336;
|
||||
}
|
||||
.cellItem:nth-of-type(3) .cellText{
|
||||
color: #1296db;
|
||||
}
|
||||
.cellItem:nth-of-type(4) .cellText{
|
||||
color: #d81e06;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="cellWrap">
|
||||
<view class="cellItem" v-for="item in typeList" :key="item" @click="intoPage(item)">
|
||||
<view class="cellText">{{item}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
query:{
|
||||
page: 1,
|
||||
page_size:999,
|
||||
type:'单选题'
|
||||
},
|
||||
typeList: ['单选','多选','判断']
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
intoPage(item){
|
||||
this.query.type=item;
|
||||
this.$u.api.questionList(this.query).then(res=>{
|
||||
let currentExam={};
|
||||
currentExam.questions_ = res.data.results;
|
||||
uni.setStorageSync('currentExam', currentExam);
|
||||
uni.navigateTo({
|
||||
url:"/pages/exam/testDetail"
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.cellWrap{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: auto;
|
||||
margin-top: 30upx;
|
||||
margin-bottom: 30upx;
|
||||
justify-content: space-evenly;
|
||||
|
||||
}
|
||||
.cellItem{
|
||||
text-align: center;
|
||||
margin-top: 50upx;
|
||||
width: 60%;
|
||||
margin-left: 20%;
|
||||
}
|
||||
|
||||
.cellText{
|
||||
height: 60upx;
|
||||
line-height: 60upx;
|
||||
text-align: center;
|
||||
color: #339900;
|
||||
border: 1px solid #339900;
|
||||
border-radius: 15rpx;
|
||||
}
|
||||
.cellItem:nth-of-type(2) .cellText{
|
||||
color: #efb336;
|
||||
border: 1px solid #efb336;
|
||||
}
|
||||
.cellItem:nth-of-type(3) .cellText{
|
||||
color: #1296db;
|
||||
border: 1px solid #1296db;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
<template>
|
||||
<view>
|
||||
<uni-list>
|
||||
<!-- 垂直排列,无略缩图,主标题+副标题显示 -->
|
||||
<uni-list-item direction="column" :key="item.id" v-for="(item, index) in examList">
|
||||
<template v-slot:header>
|
||||
<view class="uni-title">{{item.name}}</view>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<view class="uni-footer">
|
||||
<u-button size="mini" type="primary" @click="attendTest(item)">开始练习</u-button>
|
||||
</view>
|
||||
</template>
|
||||
</uni-list-item>
|
||||
</uni-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
query:{
|
||||
page: 1
|
||||
},
|
||||
examList: []
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getExamList();
|
||||
},
|
||||
methods: {
|
||||
getExamList(){
|
||||
this.$u.api.getExamList(this.query).then(res=>{
|
||||
this.examList = res.data.results
|
||||
})
|
||||
},
|
||||
attendTest(val){
|
||||
console.log(val)
|
||||
let currentExam = val;
|
||||
this.$u.api.paperDetail(val.paper_.id).then(res=>{
|
||||
currentExam = res.data;
|
||||
uni.setStorageSync('currentExam', currentExam)
|
||||
uni.navigateTo({
|
||||
url:"/pages/exam/testDetail"
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,294 @@
|
|||
<template>
|
||||
<view>
|
||||
<!-- 大标题 -->
|
||||
<view class="header" id="header">
|
||||
<span class="header-button">第{{currentIndex+1}}/{{currentExam.questions_.length}} 题</span>
|
||||
|
||||
</view>
|
||||
<!-- 小标题栏 -->
|
||||
<view class="sub-header">
|
||||
<u-row>
|
||||
<u-col span="4">
|
||||
<view style="text-align: center;"><span class="header-card">{{currentQuestion.type}}</span></view>
|
||||
</u-col>
|
||||
<u-col span="4">
|
||||
<view style="text-align: right;"><span class="submitButton" @click='handleSubmit()' >显示答案</span></view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<scroll-view class="content" scroll-y="true" v-bind:style="{height:scollHeight+'rpx'}">
|
||||
<view class="name">
|
||||
<view>{{currentIndex}}·{{currentQuestion.name}}</view>
|
||||
<!-- <rich-text :nodes="currentQuestion.name"></rich-text> -->
|
||||
<view v-if="currentQuestion.img">
|
||||
{{currentQuestion.img}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="options">
|
||||
<checkbox-group @change="checkboxGroupChange" v-if="currentQuestion.type=='多选'">
|
||||
<label class="option" v-for="item in currentOptions" :key="item.id" >
|
||||
<view class="option-item1">
|
||||
<checkbox :value="item.value" :checked="item.checked" color="#2979ff"/>
|
||||
</view >
|
||||
<view class="option-item2">{{item.value}}.{{item.text}}</view>
|
||||
</label>
|
||||
</checkbox-group>
|
||||
<radio-group v-else @change="checkboxGroupChange">
|
||||
<label class="option" v-for="item in currentOptions" :key="item.id">
|
||||
<view class="option-item1">
|
||||
<radio :value="item.value" :checked="item.checked" color="#2979ff"></radio>
|
||||
</view>
|
||||
<view class="option-item2">
|
||||
{{item.value}}.{{item.text}}
|
||||
</view>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<view v-if="showAns">正确答案:{{currentQuestion.right}}</view>
|
||||
<view style="height:20rpx"></view>
|
||||
</scroll-view>
|
||||
<u-popup v-model="showM" mode="bottom" height="40%">
|
||||
<view class="questionArea" style="display:flex">
|
||||
<block v-for="(item, index) in currentExam.questions_" :key="index">
|
||||
<view class="questionItem questionItem-select" v-if="item.user_answer" @click="jumpQuestion(index)">{{index+1}}</view>
|
||||
<view class="questionItem questionItem-unselect" v-else @click="jumpQuestion(index)">{{index+1}}</view>
|
||||
</block>
|
||||
</view>
|
||||
</u-popup>
|
||||
<!-- 底部栏 -->
|
||||
<view class="footer" id="footer">
|
||||
<u-button @click='previousQ()' throttle-time="200" :plain="true" type="primary">上一题</u-button>
|
||||
<u-button @click="showM = !showM" type="primary">答题卡</u-button>
|
||||
<u-button @click='nextQ()' throttle-time="200" :plain="true" type="primary">下一题</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentExam:{questions_:[]},
|
||||
currentIndex:0,
|
||||
currentOptions:[],
|
||||
currentQuestion:{type:'单选'},
|
||||
showM:false,
|
||||
keyid:0,
|
||||
start_time:null,
|
||||
scollHeight:0,
|
||||
showAns:false,
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
//#ifdef MP-WEIXIN
|
||||
uni.hideHomeButton()
|
||||
//#endif
|
||||
let res = uni.getSystemInfoSync();
|
||||
let ratio = 750 / res.windowWidth;
|
||||
this.scollHeight = res.windowHeight*ratio - 230;
|
||||
this.currentExam = uni.getStorageSync('currentExam');
|
||||
this.initQuestion();
|
||||
},
|
||||
methods: {
|
||||
handleSubmit(){
|
||||
this.showAns = true;
|
||||
},
|
||||
panTi(tm_current) {
|
||||
// 返回当前题目是否正确,得分多少
|
||||
let is_right = false, score = 0
|
||||
if (tm_current.type == '多选') {
|
||||
if (tm_current.user_answer) {
|
||||
if (tm_current.user_answer.sort().toString() == tm_current.right.sort().toString()) {
|
||||
is_right = true
|
||||
score = tm_current.total_score
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(tm_current.right == tm_current.user_answer){
|
||||
is_right = true
|
||||
score = tm_current.total_score
|
||||
}
|
||||
}
|
||||
return {'is_right':is_right,'score':score}
|
||||
},
|
||||
initQuestion(){
|
||||
var currentQuestion = this.currentExam.questions_[this.currentIndex];
|
||||
this.currentQuestion = currentQuestion;
|
||||
let options_ = [];
|
||||
let origin = currentQuestion.options;
|
||||
this.currentOptions = [];
|
||||
for (let key in origin) {
|
||||
let option = {
|
||||
value:key,
|
||||
text:origin[key],
|
||||
id: this.keyid++,
|
||||
checked:false
|
||||
}
|
||||
if (currentQuestion.user_answer) {
|
||||
if (key == currentQuestion.user_answer || currentQuestion.user_answer.indexOf(key) != -1) {
|
||||
option.checked = true
|
||||
}
|
||||
} else {
|
||||
option.checked = false
|
||||
}
|
||||
options_.push(option)
|
||||
}
|
||||
this.currentOptions = options_
|
||||
},
|
||||
nextQ(){
|
||||
this.showAns = false;
|
||||
let index = this.currentIndex + 1
|
||||
if(index<this.currentExam.questions_.length){
|
||||
this.currentIndex = index
|
||||
this.initQuestion()
|
||||
}
|
||||
},
|
||||
previousQ(){
|
||||
this.showAns = false;
|
||||
let index = this.currentIndex - 1;
|
||||
if(index >= 0){
|
||||
this.currentIndex = index
|
||||
this.initQuestion()
|
||||
}
|
||||
},
|
||||
checkboxGroupChange(e){
|
||||
// debugger;
|
||||
console.log(e)
|
||||
this.currentExam.questions_[this.currentIndex].user_answer = e.detail.value
|
||||
},
|
||||
jumpQuestion(index){
|
||||
this.currentIndex = index
|
||||
this.initQuestion()
|
||||
this.showM = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $u-bg-color;
|
||||
}
|
||||
.content{
|
||||
margin-top:8rpx;
|
||||
.name {
|
||||
font-size:34rpx;
|
||||
padding: 25rpx 30rpx;
|
||||
color:$u-content-color;
|
||||
line-height:130%;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
.options {
|
||||
margin-top:8rpx;
|
||||
background-color: #FFFFFF;
|
||||
padding: 6rpx 30rpx;
|
||||
.option {
|
||||
padding: 10rpx 0rpx;
|
||||
display: flex;
|
||||
font-size: 36rpx;
|
||||
.option-item1{
|
||||
justify-content: flex-start
|
||||
}
|
||||
.option-item2{
|
||||
justify-content: flex-start;
|
||||
color:$u-main-color;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
width: 750rpx;
|
||||
text-align: center;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: $theme-color;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
&-button {
|
||||
position: absolute;
|
||||
right: 10rpx;
|
||||
font-size:34rpx;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.scoreText {
|
||||
color: #00b060;
|
||||
font-size: 35rpx;
|
||||
}
|
||||
}
|
||||
.sub-header {
|
||||
padding: 4rpx 20rpx;
|
||||
color: #000;
|
||||
font-size: 33rpx;
|
||||
font-weight: bold;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
.submitButton{
|
||||
padding: 6rpx 20rpx;
|
||||
border-radius: 15rpx;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
background-color: $u-type-error;
|
||||
}
|
||||
.header-card {
|
||||
padding: 6rpx 20rpx;
|
||||
border-radius: 15rpx;
|
||||
color: #FFFFFF;
|
||||
background-color: $u-type-primary-dark;
|
||||
}
|
||||
.footer {
|
||||
width: 750rpx;
|
||||
height: 100rpx;
|
||||
padding: 30rpx 60rpx;
|
||||
position: fixed;
|
||||
bottom: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 32rpx;
|
||||
box-sizing: border-box;
|
||||
color: #4c8af3;
|
||||
box-shadow: 0 0 5px 1px #eee;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
&-card {
|
||||
padding: 10rpx 20rpx;
|
||||
border: 1px solid $theme-color;
|
||||
border-radius: 15rpx;
|
||||
color: #FFFFFF;
|
||||
background-color: $theme-color;
|
||||
}
|
||||
}
|
||||
.questionArea {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.questionItem {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
margin: 10rpx 22rpx;
|
||||
line-height: 80rpx;
|
||||
font-size: 35rpx;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
color: #ffffff;
|
||||
}
|
||||
.questionItem-select {
|
||||
background-color: $theme-color;
|
||||
}
|
||||
|
||||
.questionItem-unselect {
|
||||
background-color: #bbbbbb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
Binary file not shown.
Loading…
Reference in New Issue