This commit is contained in:
caoqianming 2020-03-30 18:05:42 +08:00
parent 63607cca89
commit 721d4353ef
26 changed files with 449 additions and 120 deletions

View File

@ -68,4 +68,19 @@ export function deleteWorkScope(id) {
url: `/examtest/workscope/${id}/`, url: `/examtest/workscope/${id}/`,
method: 'delete', method: 'delete',
}) })
}
export function getExamTestlist(query) {
return request({
url: '/examtest/examtest/',
method: 'get',
params: query
})
}
export function getExamTestDetail(id){
return request({
url: `/examtest/examtest/${id}/`,
method: 'get',
})
} }

View File

@ -174,10 +174,10 @@ export const asyncRoutes = [
meta: { title: '统计分析', icon: 'chart'}, meta: { title: '统计分析', icon: 'chart'},
children: [ children: [
{ {
path: 'djlist', path: 'examtest',
name: 'djlist', name: 'ExamTest',
component: () => import('@/views/analyse/djlist.vue'), component: () => import('@/views/analyse/examtest.vue'),
meta: { title: '答卷列表', icon: '', perms: ['djlist_manage'] } meta: { title: '答卷列表', icon: '', perms: ['examtest_list'] }
}, },
{ {
path: 'chart', path: 'chart',

View File

@ -0,0 +1,157 @@
<template>
<div class="app-container">
<div style="margin-top:10px">
<el-select
v-model="listQuery.is_pass"
placeholder="是否通过"
clearable
style="width: 200px"
class="filter-item"
@change="handleFilter"
>
<el-option
v-for="item in passOptions"
:key="item.key"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-select
v-model="listQuery.type"
placeholder="模考类型"
clearable
style="width: 200px"
class="filter-item"
@change="handleFilter"
>
<el-option
v-for="item in typeOptions"
:key="item.key"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>刷新重置</el-button>
<div style="margin-top:10px">
</div>
</div>
<el-table
:data="tableData.results"
style="width: 100%;margin-top:10px;"
border
stripe
fit
v-loading="listLoading"
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50"></el-table-column>
<el-table-column align="left" label="类型">
<template slot-scope="scope">{{ scope.row.type }}</template>
</el-table-column>
<el-table-column align="left" label="消费者">
<template slot-scope="scope">{{ scope.row.consumer_name }}</template>
</el-table-column>
<el-table-column align="left" label="工作类别">
<template slot-scope="scope">{{ scope.row.workscope_name }}</template>
</el-table-column>
<el-table-column align="left" label="押题卷">
<template slot-scope="scope">{{ scope.row.paper_name }}</template>
</el-table-column>
<el-table-column align="left" label="得分">
<template slot-scope="scope">{{ scope.row.score }}</template>
</el-table-column>
<el-table-column align="left" label="耗时(秒)">
<template slot-scope="scope">{{ scope.row.took }}</template>
</el-table-column>
<el-table-column align="left" label="答题时间">
<template slot-scope="scope">{{ scope.row.start_time }}</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="handleDetail(scope)"
icon="el-icon-more"
></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="tableData.count>0"
:total="tableData.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.limit"
@pagination="getList"
/>
</div>
</template>
<script>
import { getExamTestlist } from "@/api/examtest";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination";
const listQuery = {
page: 1,
limit: 20,
search:''
};
export default {
components: { Pagination },
data() {
return {
listQuery: Object.assign({}, listQuery),
tableData: {
count:0,
results:[],
},
listLoading: true,
typeOptions: [
{ key: "自助模考", label: "自助模考", value: "自助模考" },
{ key: "押卷模考", label: "押卷模考", value: "押卷模考"},
],
passOptions: [
{ key: true, label: "通过", value: true },
{ key: false, label: "未通过", value: false},
],
};
},
computed: {},
created() {
this.getList();
},
methods: {
checkPermission,
getList(query = this.listQuery) {
this.listLoading = true;
getExamTestlist(query).then(response => {
this.tableData = response.data;
this.listLoading = false;
});
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
resetFilter() {
this.listQuery = {
page: 1,
limit: 20,
search:''
};
this.getList();
},
handleDetail(scope) {
// this.dialogVisible = true
// this.question = scope.row
},
}
};
</script>

View File

@ -0,0 +1,157 @@
<template>
<div class="app-container">
<div style="margin-top:10px">
<el-select
v-model="listQuery.is_pass"
placeholder="是否通过"
clearable
style="width: 200px"
class="filter-item"
@change="handleFilter"
>
<el-option
v-for="item in passOptions"
:key="item.key"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-select
v-model="listQuery.type"
placeholder="模考类型"
clearable
style="width: 200px"
class="filter-item"
@change="handleFilter"
>
<el-option
v-for="item in typeOptions"
:key="item.key"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>刷新重置</el-button>
<div style="margin-top:10px">
</div>
</div>
<el-table
:data="tableData.results"
style="width: 100%;margin-top:10px;"
border
stripe
fit
v-loading="listLoading"
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50"></el-table-column>
<el-table-column align="left" label="类型">
<template slot-scope="scope">{{ scope.row.type }}</template>
</el-table-column>
<el-table-column align="left" label="消费者">
<template slot-scope="scope">{{ scope.row.consumer_name }}</template>
</el-table-column>
<el-table-column align="left" label="工作类别">
<template slot-scope="scope">{{ scope.row.workscope_name }}</template>
</el-table-column>
<el-table-column align="left" label="押题卷">
<template slot-scope="scope">{{ scope.row.paper_name }}</template>
</el-table-column>
<el-table-column align="left" label="得分">
<template slot-scope="scope">{{ scope.row.score }}</template>
</el-table-column>
<el-table-column align="left" label="耗时(秒)">
<template slot-scope="scope">{{ scope.row.took }}</template>
</el-table-column>
<el-table-column align="left" label="答题时间">
<template slot-scope="scope">{{ scope.row.start_time }}</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="handleDetail(scope)"
icon="el-icon-more"
></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="tableData.count>0"
:total="tableData.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.limit"
@pagination="getList"
/>
</div>
</template>
<script>
import { getExamTestlist } from "@/api/examtest";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination";
const listQuery = {
page: 1,
limit: 20,
search:''
};
export default {
components: { Pagination },
data() {
return {
listQuery: Object.assign({}, listQuery),
tableData: {
count:0,
results:[],
},
listLoading: true,
typeOptions: [
{ key: "自助模考", label: "自助模考", value: "自助模考" },
{ key: "押卷模考", label: "押卷模考", value: "押卷模考"},
],
passOptions: [
{ key: true, label: "通过", value: true },
{ key: false, label: "未通过", value: false},
],
};
},
computed: {},
created() {
this.getList();
},
methods: {
checkPermission,
getList(query = this.listQuery) {
this.listLoading = true;
getExamTestlist(query).then(response => {
this.tableData = response.data;
this.listLoading = false;
});
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
resetFilter() {
this.listQuery = {
page: 1,
limit: 20,
search:''
};
this.getList();
},
handleDetail(scope) {
// this.dialogVisible = true
// this.question = scope.row
},
}
};
</script>

View File

@ -138,9 +138,9 @@ export default {
this.banner.path = res.data.path this.banner.path = res.data.path
}, },
beforeImgUpload(file) { beforeImgUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 0.5; const isLt2M = file.size / 1024 / 1024 < 0.6;
if (!isLt2M) { if (!isLt2M) {
this.$message.error("上传图片大小不能超过 500KB!"); this.$message.error("上传图片大小不能超过 600KB!");
} }
return isLt2M; return isLt2M;
}, },

View File

@ -11,7 +11,7 @@ App({
wx.login({ wx.login({
success: res => { success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId // 发送 res.code 到后台换取 openId, sessionKey, unionId
api.request('crm/consumer/mplogin/','POST', {code:res.code}).then(res=>{ api.request('/crm/consumer/mplogin/','POST', {code:res.code}).then(res=>{
if(res.code==200){ if(res.code==200){
this.globalData.token = res.data.token this.globalData.token = res.data.token
this.globalData.userinfo = res.data.userinfo this.globalData.userinfo = res.data.userinfo
@ -48,10 +48,10 @@ App({
globalData: { globalData: {
userInfo: null, userInfo: null,
userinfo: null, // 服务器传回的消费者信息 userinfo: null, // 服务器传回的消费者信息
host: 'https://apitest.ctcshe.com/', // host: 'https://apitest.ctcshe.com',
mediahost: 'https://apitest.ctcshe.com/', mediahost: 'https://apitest.ctcshe.com',
// host: 'http://127.0.0.1:8000/', host: 'http://127.0.0.1:8000',
// mediahost: 'http://127.0.0.1:8000/', // mediahost: 'http://127.0.0.1:8000',
token : '', token : '',
subject:null, subject:null,
} }

View File

@ -30,7 +30,7 @@ Page({
onLoad: function () { onLoad: function () {
var that = this var that = this
wx.showLoading({}) wx.showLoading({})
api.request('crm/consumer/collects/', 'GET').then(res => { api.request('/crm/consumer/collects/', 'GET').then(res => {
that.data.sctms = res.data that.data.sctms = res.data
that.setData({ that.setData({
tmtotal:res.data.length tmtotal:res.data.length
@ -187,7 +187,7 @@ Page({
remove: function () { remove: function () {
var that = this var that = this
var index = that.data.tm_index var index = that.data.tm_index
api.request('crm/consumer/collects/', 'DELETE', { question: that.data.tm_current.id }).then(res => { api.request('/crm/consumer/collects/', 'DELETE', { question: that.data.tm_current.id }).then(res => {
that.data.sctms.splice(index, 1) that.data.sctms.splice(index, 1)
if (that.data.sctms.length > index) { if (that.data.sctms.length > index) {
that.showTm(index) that.showTm(index)

View File

@ -43,7 +43,7 @@ Page({
getList: function () { getList: function () {
var that = this var that = this
if (that.data.workscopeId) { if (that.data.workscopeId) {
api.request('question/questioncat/workscope/', 'GET', { 'id': that.data.workscopeId }).then(res => { api.request('/question/questioncat/workscope/', 'GET', { 'id': that.data.workscopeId }).then(res => {
let questioncatData = [] let questioncatData = []
if (res.data.length > 0) { if (res.data.length > 0) {
for (var i = 0; i < res.data.length; i++) { for (var i = 0; i < res.data.length; i++) {

View File

@ -66,7 +66,7 @@ Page({
questioncat: that.data.questioncat, questioncat: that.data.questioncat,
ydtms: that.data.ydtms_old ydtms: that.data.ydtms_old
} }
api.request('question/question/exercise/?limit=10&page='+that.data.page, 'POST', query).then(res => { api.request('/question/question/exercise/?limit=10&page='+that.data.page, 'POST', query).then(res => {
that.data.tms = that.data.tms.concat(res.data.results) that.data.tms = that.data.tms.concat(res.data.results)
that.showTm(that.data.tm_index) //展示题目和答案 that.showTm(that.data.tm_index) //展示题目和答案
that.setData({ that.setData({
@ -218,7 +218,7 @@ Page({
var that = this var that = this
var tm_current = that.data.tm_current var tm_current = that.data.tm_current
if (tm_current.is_collect) { if (tm_current.is_collect) {
api.request('crm/consumer/collects/', 'DELETE', { question: tm_current.id }).then(res => { api.request('/crm/consumer/collects/', 'DELETE', { question: tm_current.id }).then(res => {
wx.showToast({ wx.showToast({
title: '已取消!', title: '已取消!',
icon: 'none' icon: 'none'
@ -230,7 +230,7 @@ Page({
}) })
} else { } else {
api.request('crm/consumer/collects/', 'POST', { question: tm_current.id }).then(res => { api.request('/crm/consumer/collects/', 'POST', { question: tm_current.id }).then(res => {
wx.showToast({ wx.showToast({
title: '收藏成功!', title: '收藏成功!',
icon: 'none' icon: 'none'

View File

@ -66,7 +66,7 @@ Page({
sendMsg : function (){ sendMsg : function (){
var that = this var that = this
if(that.isPhone(that.data.form.phone)){ if(that.isPhone(that.data.form.phone)){
api.request('crm/consumer/sendcode', 'GET', { phone: that.data.form.phone }).then(res => { api.request('/crm/consumer/sendcode', 'GET', { phone: that.data.form.phone }).then(res => {
wx.showToast({ wx.showToast({
title: '验证码发送成功!注意查收', title: '验证码发送成功!注意查收',
icon: 'none' icon: 'none'

View File

@ -1,62 +1,44 @@
// pages/main/main.js // pages/main/main.js
const app = getApp() const app = getApp()
const api = require("../../utils/request.js");
Page({ Page({
/** /**
* 页面的初始数据 * 页面的初始数据
*/ */
data: { data: {
// Banner数据 Hei:0,
images: [], background: [],
// 是否显示面板指示点
indicatorDots: true, indicatorDots: true,
// 滑动方向是否为纵向
vertical: false, vertical: false,
// 自动切换
autoplay: true, autoplay: true,
// 采用衔接滑动 interval: 7000,
circular: true,
// 自动切换时间间隔2s
interval: 8000,
// 滑动动画时长0.5s
duration: 1500, duration: 1500,
// 前边距,可用于露出前一项的一小部分,接受 px 和 rpx 值
previousMargin: 0,
// 后边距,可用于露出后一项的一小部分,接受 px 和 rpx 值
nextMargin: 0,// Banner数据
images: [],
// 是否显示面板指示点
indicatorDots: false,
// 滑动方向是否为纵向
vertical: false,
// 自动切换
autoplay: true,
// 采用衔接滑动
circular: true,
// 自动切换时间间隔2s
interval: 6000,
// 滑动动画时长0.5s
duration: 1500,
// 前边距,可用于露出前一项的一小部分,接受 px 和 rpx 值
previousMargin: 0,
// 后边距,可用于露出后一项的一小部分,接受 px 和 rpx 值
nextMargin: 0,
nowWork:null nowWork:null
}, },
imgH: function (e) {
let winWid = wx.getSystemInfoSync().windowWidth;
console.log(e) //获取当前屏幕的宽度
let imgh = e.detail.height;                //图片高度
let imgw = e.detail.width;
let swiperH = winWid * imgh / imgw + "px";
this.setData({
Hei: swiperH        //设置高度
})
},
/** /**
* 生命周期函数--监听页面加载 * 生命周期函数--监听页面加载
*/ */
onLoad: function (options) { onLoad: function (options) {
var that = this var that = this
let images = [ api.request('/examtest/banner/', 'GET').then(res => {
app.globalData.mediahost + 'media/banner/1.jpg', let images = []
app.globalData.mediahost + 'media/banner/2.jpg', for(var i=0;i<res.data.length;i++){
app.globalData.mediahost + 'media/banner/3.jpg', images.push(app.globalData.mediahost + res.data[i].path)
app.globalData.mediahost + 'media/banner/4.jpg', }
] that.setData({
that.setData({ background: images
images: images })
}) })
}, },

View File

@ -1,21 +1,14 @@
<view class="page"> <view class="page">
<swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" circular="{{circular}}" vertical="{{vertical}}" interval="{{interval}}" duration="{{duration}}" previous-margin="{{previousMargin}}px" next-margin="{{nextMargin}}px"> <view class="page-section page-section-spacing swiper">
<swiper indicator-dots="{{indicatorDots}}"
<block wx:for='{{images}}' wx:key='index'> autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" style='height:{{Hei}}'>
<swiper-item> <block wx:for="{{background}}" wx:key="*this">
<image src='{{item}}' mode='aspectFill' class='swiper-item-images' /> <swiper-item>
</swiper-item> <image style="width: 100%;" src="{{item}}" bindload='imgH'></image>
</block> </swiper-item>
</swiper> </block>
<view style="margin-top:4px"> </swiper>
<view style="color:blue;font-weight:bold;text-align:center">
欢迎使用中科辐射学堂!
<view style="color:orange;font-weight:bold">
<view >开通权限请联系课程顾问师老师</view>
<view >18355135390(微信同号)</view>
</view>
</view> </view>
</view>
<view class="weui-cells weui-cells_after-title"> <view class="weui-cells weui-cells_after-title">
<view class="weui-grids"> <view class="weui-grids">
<a class="weui-grid" bindtap="goLianxi"> <a class="weui-grid" bindtap="goLianxi">

View File

@ -1,27 +0,0 @@
/* pages/main/main.wxss */
.swiper-item-images{
width: 100%;
height: 300rpx;
}
/*横向布局 */
.layout_horizontal{
height: 200rpx;
display: flex;
/*row 横向 column 列表 */
flex-direction: row;
padding:4rpx
}
.swiper_container {
background-color: #e7e6e6;
height: 50rpx;
width: 100%;
text-align: center
}
.swiper_item {
font-size: 30rpx;
font-weight: bold;
color:darkblue;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@ -77,7 +77,7 @@ Page({
wx.showLoading({ wx.showLoading({
title: '正在生成试卷', title: '正在生成试卷',
}) })
api.request('examtest/workscope/' + this.data.workId + '/monitest', 'GET').then(res => { api.request('/examtest/workscope/' + this.data.workId + '/monitest', 'GET').then(res => {
try { try {
wx.setStorageSync('monitest', res.data) wx.setStorageSync('monitest', res.data)
} catch (e) { } } catch (e) { }

View File

@ -32,7 +32,7 @@ Page({
* 生命周期函数--监听页面显示 * 生命周期函数--监听页面显示
*/ */
onShow: function () { onShow: function () {
api.request('examtest/myexamtestfx', 'GET').then(res => { api.request('/examtest/myexamtestfx', 'GET').then(res => {
this.setData(res.data) this.setData(res.data)
}) })
}, },

View File

@ -14,9 +14,9 @@ Page({
* 生命周期函数--监听页面加载 * 生命周期函数--监听页面加载
*/ */
onLoad: function (options) { onLoad: function (options) {
api.request('question/subject/', 'GET').then(res => { api.request('/question/subject/', 'GET').then(res => {
var subjectData = res.data var subjectData = res.data
api.request('crm/consumer/subjectpaid', 'GET').then(res => { api.request('/crm/consumer/subjectpaid', 'GET').then(res => {
for(var i=0;i<subjectData.length;i++){ for(var i=0;i<subjectData.length;i++){
if(res.data.indexOf(subjectData[i].id)!=-1){ if(res.data.indexOf(subjectData[i].id)!=-1){
subjectData[i].is_paid = true subjectData[i].is_paid = true

View File

@ -16,7 +16,7 @@ Page({
onLoad: function (options) { onLoad: function (options) {
var that = this var that = this
var query = {'examtest':options.id} var query = {'examtest':options.id}
api.request('examtest/answerdetail/', 'GET', query).then(res => { api.request('/examtest/answerdetail/', 'GET', query).then(res => {
that.data.results= res.data that.data.results= res.data
that.showTm(0) that.showTm(0)
that.setData({ that.setData({

View File

@ -35,7 +35,7 @@ Page({
}, },
getList: function () { getList: function () {
var that = this var that = this
api.request('examtest/myexamtest/', 'GET', that.data.query).then(res => { api.request('/examtest/myexamtest/', 'GET', that.data.query).then(res => {
if (that.data.query.page == 1) { if (that.data.query.page == 1) {
that.data.results = res.data.results that.data.results = res.data.results
} else { } else {

View File

@ -7,10 +7,10 @@
<view class="weui-media-box__bd weui-media-box__bd_in-appmsg"> <view class="weui-media-box__bd weui-media-box__bd_in-appmsg">
<view class="weui-media-box__title">{{item.name}}</view> <view class="weui-media-box__title">{{item.name}}</view>
<view class="weui-media-box__desc"> <view class="weui-media-box__desc">
<span style="font-weight:bold;color:white;background-color:orange;">{{item.type}}</span> <span style="font-weight:bold;color:darkblue">{{item.type}}</span>
<span>-</span> <span>-</span>
<span style="font-weight:bold;color:white;background-color:green;" wx:if="{{item.is_pass}}">通过</span> <span style="font-weight:bold;color:green;" wx:if="{{item.is_pass}}">通过</span>
<span style="font-weight:bold;color:white;background-color:red;" wx:else>未通过</span> <span style="font-weight:bold;color:red;" wx:else>未通过</span>
(得分 (得分
<span style="color:green;" wx:if="{{item.is_pass}}">{{item.score}}</span> <span style="color:green;" wx:if="{{item.is_pass}}">{{item.score}}</span>
<span style="color:red;" wx:else>{{item.score}}</span> <span style="color:red;" wx:else>{{item.score}}</span>

View File

@ -254,7 +254,7 @@ Page({
that.data.monitest.start_time = util.formatTime(new Date(that.data.starttimes)) that.data.monitest.start_time = util.formatTime(new Date(that.data.starttimes))
that.data.monitest.end_time = util.formatTime(new Date()) that.data.monitest.end_time = util.formatTime(new Date())
that.data.monitest.took = Math.floor(((new Date()).getTime() - this.data.starttimes) / 1000) that.data.monitest.took = Math.floor(((new Date()).getTime() - this.data.starttimes) / 1000)
api.request('examtest/monitest/', 'POST', that.data.monitest).then(res => { api.request('/examtest/monitest/', 'POST', that.data.monitest).then(res => {
getApp().globalData.testData = res.data getApp().globalData.testData = res.data
try { try {
wx.removeStorageSync('monitest') wx.removeStorageSync('monitest')

View File

@ -18,7 +18,7 @@ Page({
try { try {
var value = wx.getStorageSync('nowSubject') var value = wx.getStorageSync('nowSubject')
if (value.id) { if (value.id) {
api.request('examtest/workscope/', 'GET', { subject:value.id}).then(res => { api.request('/examtest/workscope/', 'GET', { subject:value.id}).then(res => {
that.setData({ that.setData({
workData:res.data workData:res.data
}) })

View File

@ -40,4 +40,13 @@ class WorkScope(SoftCommonModel):
return self.name return self.name
class Paper(SoftCommonModel): class Paper(SoftCommonModel):
name = models.CharField(max_length=200, verbose_name='名称') name = models.CharField(max_length=200, verbose_name='名称')
questions = models.ManyToManyField(Question, through='PaperQuestions')
limit = models.IntegerField(default=0, verbose_name='限时(分钟)')
total_score = models.FloatField(default=0, verbose_name='满分')
pass_score = models.FloatField(default=0, verbose_name='及格分数')
class PaperQuestions(CommonModel):
paper = models.ForeignKey(Paper, on_delete=models.CASCADE, verbose_name='试卷')
question = models.ForeignKey(Question, on_delete=models.CASCADE, verbose_name='试题')
score = models.FloatField(default=0, verbose_name='满分')

View File

@ -2,7 +2,7 @@ from rest_framework import serializers
from question.models import Questioncat from question.models import Questioncat
from crm.models import Consumer from crm.models import Consumer
from .models import ExamTest, AnswerDetail, Banner from .models import ExamTest, AnswerDetail, Banner
from .models_paper import TestRule, WorkScope from .models_paper import TestRule, WorkScope, Paper, PaperQuestions
class BannerSerializer(serializers.ModelSerializer): class BannerSerializer(serializers.ModelSerializer):
@ -53,12 +53,16 @@ class ExamTestListSerializer(serializers.ModelSerializer):
""" """
start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) paper_name = serializers.StringRelatedField(source='papaer', read_only=True)
consumer_name = serializers.SerializerMethodField()
class Meta: class Meta:
model = ExamTest model = ExamTest
fields = '__all__' exclude = ('detail',)
def get_consumer_name(self, obj):
return obj.consumer.name
class AnswerDetailSerializer(serializers.ModelSerializer): class AnswerDetailSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = AnswerDetail model = AnswerDetail
@ -69,3 +73,10 @@ class AnswerDetailCreateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = AnswerDetail model = AnswerDetail
fields = '__all__' fields = '__all__'
class PaperSerializer(serializers.ModelSerializer):
create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
class Meta:
model = Paper
exclude = ('questions',)

View File

@ -1,5 +1,5 @@
from django.urls import path,include from django.urls import path,include
from .views import TestRuleViewSet, MoniTestView, MyExamTestView, AnswerDetailView, MyExamTestFxView, WorkScopeViewSet, BannerViewSet from .views import TestRuleViewSet, MoniTestView, MyExamTestView, AnswerDetailView, MyExamTestFxView, WorkScopeViewSet, BannerViewSet, ExamTestViewSet, PaperViewSet
from rest_framework import routers from rest_framework import routers
@ -7,6 +7,8 @@ router = routers.DefaultRouter()
router.register('testrule', TestRuleViewSet, basename="testrule") router.register('testrule', TestRuleViewSet, basename="testrule")
router.register('workscope', WorkScopeViewSet, basename="workscope") router.register('workscope', WorkScopeViewSet, basename="workscope")
router.register('banner', BannerViewSet, basename='banner') router.register('banner', BannerViewSet, basename='banner')
router.register('examtest', ExamTestViewSet, basename='examtest')
router.register('paper', PaperViewSet, basename='paper')
urlpatterns = [ urlpatterns = [
path('monitest/',MoniTestView.as_view()), path('monitest/',MoniTestView.as_view()),

View File

@ -17,8 +17,10 @@ from rbac.permission import RbacPermission
from question.models import Question from question.models import Question
from question.serializers import QuestionSerializer from question.serializers import QuestionSerializer
from .models import ExamTest, AnswerDetail, Banner from .models import ExamTest, AnswerDetail, Banner
from .models_paper import TestRule, WorkScope from .models_paper import TestRule, WorkScope, Paper
from .serializers import TestRuleSerializer, MoniTestSerializer, AnswerDetailSerializer, ExamTestListSerializer, AnswerDetailCreateSerializer, WorkScopeSerializer, BannerSerializer from .serializers import (TestRuleSerializer, MoniTestSerializer, AnswerDetailSerializer,
ExamTestListSerializer, AnswerDetailCreateSerializer, WorkScopeSerializer,
BannerSerializer, PaperSerializer)
from server import settings from server import settings
from crm.authentication import ConsumerTokenAuthentication from crm.authentication import ConsumerTokenAuthentication
from utils.custom import CommonPagination from utils.custom import CommonPagination
@ -222,3 +224,31 @@ class TestRuleViewSet(ModelViewSet):
self.permission_classes = [] self.permission_classes = []
return [permission() for permission in self.permission_classes] return [permission() for permission in self.permission_classes]
class ExamTestViewSet(ModelViewSet):
"""
考试记录列表和详情
"""
perms_map = (
{'*': 'admin'}, {'*': 'ExamTest_all'}, {'get': 'ExamTest_list'})
pagination_class = CommonPagination
queryset = ExamTest.objects.filter(is_delete=0).all().order_by("id")
serializer_class = ExamTestListSerializer
ordering_fields = ('id',)
ordering = ['id']
search_fields = ('^name',)
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['type','is_pass']
class PaperViewSet(ModelViewSet):
"""
押题卷增删改查
"""
perms_map = (
{'*': 'admin'}, {'*': 'Paper_all'}, {'get': 'Paper_list'}, {'post': 'Paper_create'},
{'put': 'Paper_update'}, {'delete': 'Paper_delete'})
queryset = Paper.objects.filter(is_delete=0).all().order_by("id")
serializer_class = PaperSerializer
ordering_fields = ('id',)
ordering = ['id']
search_fields = ('^name',)