session complete core 1

This commit is contained in:
caoqianming 2020-03-23 18:58:16 +08:00
parent 4018789af6
commit 02270722ec
30 changed files with 776 additions and 182 deletions

View File

@ -51,7 +51,7 @@ export const constantRoutes = [
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: '' }
meta: { title: '首页', icon: 'dashboard' }
}]
},
@ -68,7 +68,7 @@ export const asyncRoutes = [
component: Layout,
redirect: '/crm/',
name: 'Crm',
meta: { title: '客户管理', icon: '', perms: ['custom_manage'] },
meta: { title: '客户管理', icon: 'peoples', perms: ['custom_manage'] },
children: [
{
path: 'company',
@ -84,61 +84,12 @@ export const asyncRoutes = [
},
]
},
{
path: '/sjmanage',
component: Layout,
redirect: '/sjmanage/',
name: 'Sjmanage',
meta: { title: '试卷管理', icon: ''},
children: [
{
path: 'testrule',
name: 'TestRule',
component: () => import('@/views/examtest/rule.vue'),
meta: { title: '模考规则', icon: '', perms: ['testrule_manage'] },
},
{
path: 'testpaper',
name: 'testpaper',
component: () => import('@/views/question/question.vue'),
meta: { title: '押题试卷', icon: '', perms: ['question_manage'] }
},
{
path: 'testrule/create',
name: 'CreateRule',
component: () => import('@/views/examtest/rulecreate.vue'),
meta: { title: '新建模考规则', noCache: true, icon: '', perms: ['testrule_add']},
hidden: true
},
]
},
{
path: '/djmanage',
component: Layout,
redirect: '/djmanage/',
name: 'Djmanage',
meta: { title: '答卷管理', icon: ''},
children: [
{
path: 'testrule',
name: 'testrule',
component: () => import('@/views/question/questioncat.vue'),
meta: { title: '答卷列表', icon: '', perms: ['questioncat_manage'] }
},
{
path: 'testpaper',
name: 'testpaper',
component: () => import('@/views/question/question.vue'),
meta: { title: '答卷统计', icon: '', perms: ['question_manage'] }
},
]
},
{
path: '/Qmanage',
component: Layout,
redirect: '/Qmanage/',
name: 'Qmanage',
meta: { title: '题库管理', icon: ''},
meta: { title: '题库管理', icon: 'table'},
children: [
{
path: 'subject',
@ -160,12 +111,62 @@ export const asyncRoutes = [
},
]
},
{
path: '/sjmanage',
component: Layout,
redirect: '/sjmanage/',
name: 'Sjmanage',
meta: { title: '试卷管理', icon: 'component'},
children: [
{
path: 'testrule',
name: 'TestRule',
component: () => import('@/views/examtest/rule.vue'),
meta: { title: '模考规则', icon: '', perms: ['testrule_manage'] },
},
{
path: 'testpaper',
name: 'testpaper',
component: () => import('@/views/examtest/paper.vue'),
meta: { title: '押题试卷', icon: '', perms: ['paper_manage'] }
},
{
path: 'testrule/create',
name: 'CreateRule',
component: () => import('@/views/examtest/rulecreate.vue'),
meta: { title: '新建模考规则', noCache: true, icon: '', perms: ['testrule_add']},
hidden: true
},
]
},
{
path: '/analyse',
component: Layout,
redirect: '/analyse/',
name: 'Analyse',
meta: { title: '统计分析', icon: 'chart'},
children: [
{
path: 'djlist',
name: 'djlist',
component: () => import('@/views/analyse/djlist.vue'),
meta: { title: '答卷列表', icon: '', perms: ['djlist_manage'] }
},
{
path: 'chart',
name: 'chart',
component: () => import('@/views/analyse/chart.vue'),
meta: { title: '图标分析', icon: '', perms: ['chart_manage'] }
},
]
},
{
path: '/system',
component: Layout,
redirect: '/system/user',
name: 'System',
meta: { title: '系统管理', icon: '', perms: ['system_manage'] },
meta: { title: '系统管理', icon: 'tree', perms: ['system_manage'] },
children: [
{
path: 'user',

View File

View File

View File

View File

@ -3,7 +3,7 @@
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
<div class="title-container">
<h3 class="title">登陆系统</h3>
<h3 class="title">答题平台后台管理</h3>
</div>
<el-form-item prop="username">

View File

@ -14,7 +14,7 @@ App({
api.request('crm/consumer/mplogin/','POST', {code:res.code}).then(res=>{
if(res.code==200){
this.globalData.token = res.data.token
this.globalData.userInfo = res.data.userinfo
this.globalData.userinfo = res.data.userinfo
if(res.data.userinfo.username == null){
//匿名用户
wx.reLaunch({
@ -47,6 +47,7 @@ App({
},
globalData: {
userInfo: null,
userinfo: null, // 服务器传回的消费者信息
host: 'http://127.0.0.1:8000/api/',
mediahost: 'http://127.0.0.1:8000/',
token : '',

View File

@ -15,7 +15,9 @@
"pages/test/result",
"pages/test/detail",
"pages/test/sheet",
"pages/test/list"
"pages/test/list",
"pages/my/index",
"pages/collect/main"
],
"window": {
"backgroundTextStyle": "light",
@ -36,7 +38,7 @@
"text": "主页"
},
{
"pagePath": "pages/index/index",
"pagePath": "pages/my/index",
"iconPath": "images/me.png",
"selectedIconPath": "images/mec.png",
"text": "个人中心"

View File

@ -0,0 +1,204 @@
// pages/lianxi/main.js
const api = require("../../utils/request.js");
var util = require('../../utils/util.js')
Page({
/**
* 页面的初始数据
*/
data: {
sctms: [],
tm_index: 0,
is_right: false,
answerP: false,
tmtotal: 0
},
radioChange: function (e) {
var that = this
that.data.tm_current['user_answer'] = e.detail.value
that.data.sctms[that.data.tm_index] = that.data.tm_current
that.showAnswer()
},
checkboxChange: function (e) {
var that = this
that.data.tm_current['user_answer'] = e.detail.value
that.data.sctms[that.data.tm_index] = that.data.tm_current
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function () {
var that = this
wx.showLoading({})
api.request('crm/consumer/collects/', 'GET').then(res => {
that.data.sctms = res.data
that.setData({
tmtotal:res.data.length
})
if (res.data.length) {
that.showTm(that.data.tm_index)
} else {
wx.showModal({
title: '提示',
content: '收藏集无记录!',
confirmText: '返回',
cancelText: '前去练习',
success: function (res) {
if (res.confirm) {
wx.navigateBack({
})
} else {
wx.redirectTo({
url: '/pages/lianxi/index',
})
}
}
})
}
})
try {
const res = wx.getSystemInfoSync()
that.setData({
scrollHeight: res.windowHeight - 70
})
} catch (e) {
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
try {
wx.setStorageSync('sctms', this.data.sctms)
} catch (e) { }
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
showTm: function (index) {
var that = this
var tm_current = that.data.sctms[index]
that.setData({
tm_index: index,
tmtotal: that.data.sctms.length,
tm_current: tm_current,
answerP: false
})
that.showOptions()
if (tm_current.user_answer) {
that.showAnswer()
}
},
panTi: function () {
var that = this
let tm_current = that.data.tm_current
let is_right = false
if (tm_current.type == '多选') {
if (tm_current.user_answer) {
if (tm_current.user_answer.sort().toString() == tm_current.right.sort().toString()) {
is_right = true
}
}
} else {
is_right = tm_current.right == tm_current.user_answer
}
return is_right
},
showAnswer: function () {
let is_right = this.panTi()
this.setData({
is_right: is_right,
answerP: true,
tm_current: this.data.tm_current
})
},
next: function () {
var that = this
var tm_index = that.data.tm_index + 1
that.showTm(tm_index)
},
previous: function () {
var that = this
var tm_index = that.data.tm_index - 1
that.showTm(tm_index)
},
showOptions: function () {
let tm_current = this.data.tm_current
let options = []
for (let key in tm_current.options) {
let option = {}
option.key = key
option.value = key + ':' + tm_current.options[key]
if (tm_current.user_answer) {
if (key == tm_current.user_answer || tm_current.user_answer.indexOf(key) != -1) {
option.checked = true
}
} else {
option.checked = false
}
options.push(option)
}
this.setData({
options: options
})
},
remove: function () {
var that = this
var index = that.data.tm_index
api.request('crm/consumer/collects/', 'DELETE', { question: that.data.tm_current.id }).then(res => {
that.data.sctms.splice(index, 1)
if (that.data.sctms.length > index) {
that.showTm(index)
} else if (that.data.sctms.length > 0 && index > 1) {
that.showTm(index - 1)
}
else {
wx.navigateBack({
})
}
})
}
})

View File

@ -0,0 +1,4 @@
{
"usingComponents": {},
"navigationBarTitleText": "收藏集"
}

View File

@ -0,0 +1,66 @@
<view class="head">
题量: {{tm_index+1}}/{{tmtotal}}
</view>
<scroll-view scroll-y="true" style="height: {{scrollHeight}}px;">
<view class="weui-article">
<view class="weui-article__h2">{{tm_index+1}}.
<span class="txlabel">{{tm_current.type}}</span>
</view>
<view style="text-align:center">
<span style="color:drakblue;font-weight:bold;font-size:14px">{{tm_current.questioncat_name}}(</span>
<span style="color:orange;font-weight:bold;font-size:14px">{{tm_current.dtime}})</span>
</view>
<view class="weui-article__title">{{tm_current.name}}</view>
</view>
<view class="weui-cells weui-cells_radio">
<radio-group class="radio-group" bindchange="radioChange" wx:if="{{(tm_current.type=='单选' ||tm_current.type=='判断')}}">
<label class="weui-cell weui-cell_active weui-check__label" wx:for="{{options}}" wx:key="key">
<view class="weui-cell__bd">
<view>{{item.value}}</view>
</view>
<view class="weui-cell__ft">
<radio class="weui-check" value="{{item.key}}" checked="{{item.checked}}" />
<i class="weui-icon-checked"></i>
</view>
</label>
</radio-group>
</view>
<view class="weui-cells weui-cells_checkbox">
<checkbox-group bindchange="checkboxChange" wx:if="{{tm_current.type=='多选'}}">
<label class="weui-cell weui-cell_active weui-check__label" wx:for="{{options}}" wx:key="key">
<view class="weui-cell__bd">
<view>{{item.value}}</view>
</view>
<view class="weui-cell__hd">
<checkbox class="weui-check" value="{{item.key}}" checked="{{item.checked}}"/>
<i class="weui-icon-checked"></i>
</view>
</label>
</checkbox-group>
</view>
<view class="weui-article" wx:if="{{answerP}}">
<view class="weui-article__h2" wx:if="{{is_right}}" style="color:green;font-weight:bold">回答正确!</view>
<view class="weui-article__h2" wx:else style="color:red;font-weight:bold">回答有误!</view>
<view class="weui-article__h2">正确答案是{{tm_current.right}},你的答案是{{tm_current.user_answer}}</view>
<view class="weui-article__title">
<span style="color:blue">解析: </span>
<span wx:if="{{tm_current.resoluation != null}}">{{tm_current.resoluation}}</span>
<span wx:else>无</span>
</view>
</view>
</scroll-view>
<view class="btns">
<view style="width:25%">
<button type="primary" size="mini" bindtap="previous" disabled="{{tm_index==0}}">上题</button>
</view>
<view style="width:25%">
<button type="primary" size="mini" bindtap="next" disabled="{{tm_index==tmtotal-1}}">下题</button>
</view>
<view style="width:25%">
<button type="primary" size="mini" bindtap="showAnswer">答案</button>
</view>
<view style="width:25%">
<button type="primary" size="mini" bindtap="remove">移除</button>
</view>
</view>

View File

@ -0,0 +1,20 @@
.head{
width:100%;
height:30px;
color:#fff;
background-color: cornflowerblue;
text-align: center;
}
.btns{
height:40px;
display:flex;
flex-direction: row;
flex-wrap: wrap;
text-align:center;
}
.txlabel{
color:#fff;
background-color: rgb(216, 140, 0);
padding: 2px
}

View File

@ -44,24 +44,27 @@ Page({
},
getList: function (){
var that = this
api.request('question/questioncat/subject/', 'GET', { 'id': that.data.questioncatId }).then(res => {
if (res.code == 200) {
let questioncatData = []
if (res.data.length > 0) {
for (var i = 0; i < res.data.length; i++) {
let questioncat = {}
questioncat['id'] = res.data[i].id
questioncat['name'] = res.data[i].name
questioncat['tmtotal'] = res.data[i].tmtotal
questioncat['ydtmtotal'] = 0
questioncatData.push(questioncat)
if(that.data.questioncatId){
api.request('question/questioncat/subject/', 'GET', { 'id': that.data.questioncatId }).then(res => {
if (res.code == 200) {
let questioncatData = []
if (res.data.length > 0) {
for (var i = 0; i < res.data.length; i++) {
let questioncat = {}
questioncat['id'] = res.data[i].id
questioncat['name'] = res.data[i].name
questioncat['tmtotal'] = res.data[i].tmtotal
questioncat['ydtmtotal'] = 0
questioncatData.push(questioncat)
}
that.setData({
questioncatData: that.showYd(questioncatData)
})
}
that.setData({
questioncatData: that.showYd(questioncatData)
})
}
}
})
})
}
},
showYd: function (cat) {
for (var i = 0; i < cat.length; i++) {

View File

@ -7,24 +7,24 @@ Page({
* 页面的初始数据
*/
data: {
questioncat:null,
tms:[],
ydtms:[],
ctms:[],
questioncat: null,
tms: [],
ydtms: [],
ctms: [],
tm_index: 0,
answerP: false,
isLoad:true,
isLoad: true,
},
radioChange: function (e) {
radioChange: function(e) {
var that = this
that.data.tm_current['user_answer'] = e.detail.value
that.data.tms[that.data.tm_index] = that.data.tm_current
that.showAnswer()
if (that.data.ydtms.indexOf(that.data.tm_current.id)==-1){
if (that.data.ydtms.indexOf(that.data.tm_current.id) == -1) {
that.data.ydtms.push(that.data.tm_current.id)
}
},
checkboxChange: function (e) {
checkboxChange: function(e) {
var that = this
that.data.tm_current['user_answer'] = e.detail.value
that.data.tms[that.data.tm_index] = that.data.tm_current
@ -35,7 +35,7 @@ Page({
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
onLoad: function(options) {
var that = this
that.data.questioncat = options.questioncat
try {
@ -49,106 +49,101 @@ Page({
if (value) {
that.data.ctms = value
}
} catch (e) { }
} catch (e) {}
that.getTms()
try{
try {
const res = wx.getSystemInfoSync()
that.setData({
scrollHeight:res.windowHeight-70
scrollHeight: res.windowHeight - 70
})
}catch(e){
}
} catch (e) {}
},
getTms: function(){
getTms: function() {
var that = this
var query = {
questioncat: that.data.questioncat,
ydtms: that.data.ydtms
}
api.request('question/question/exercise/', 'POST', query).then(res => {
if (res.code == 200) {
if (res.data.results.length==0){
wx.showModal({
title: '提示',
content: '无更多新题,返回重新开始',
showCancel: false,
success: function (res) {
if (res.confirm) {
wx.navigateBack({
})
}
if (res.data.results.length == 0) {
wx.showModal({
title: '提示',
content: '无更多新题,返回重新开始',
showCancel: false,
success: function(res) {
if (res.confirm) {
wx.navigateBack({})
}
})
}else{
that.data.tms = that.data.tms.concat(res.data.results)
that.showTm(that.data.tm_index) //展示题目和答案
if(that.data.isLoad){
that.setData({
tmtotal: res.data.total,
})
that.data.isLoad=false
}
})
} else {
that.data.tms = that.data.tms.concat(res.data.results)
that.showTm(that.data.tm_index) //展示题目和答案
if (that.data.isLoad) {
that.setData({
tmtotal: res.data.total,
})
that.data.isLoad = false
}
}
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
onReady: function() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
onShow: function() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
onHide: function() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
onUnload: function() {
try {
wx.setStorageSync('cat' + this.data.questioncat.toString(), this.data.ydtms)
} catch (e) { }
} catch (e) {}
try {
wx.setStorageSync('ctms', this.data.ctms)
} catch (e) { }
} catch (e) {}
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
onPullDownRefresh: function() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
onReachBottom: function() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
onShareAppMessage: function() {
},
showTm: function (index) {
showTm: function(index) {
var that = this
var tm_current = that.data.tms[index]
that.setData({
@ -156,11 +151,11 @@ Page({
'tm_current': tm_current
})
that.showOptions()
if (tm_current.user_answer){
if (tm_current.user_answer) {
that.showAnswer()
}
},
panTi: function () {
panTi: function() {
var that = this
let tm_current = that.data.tm_current
let isright = false
@ -174,16 +169,16 @@ Page({
} else {
isright = tm_current.right == tm_current.user_answer
}
if(isright == false && tm_current.user_answer != undefined){
if (isright == false && tm_current.user_answer != undefined) {
tm_current.dtime = util.formatTime(new Date())
that.data.ctms.unshift(tm_current)
if(that.data.ctms.length>40){
if (that.data.ctms.length > 40) {
that.data.ctms.length = 40
}
}
return isright
},
showAnswer: function () {
showAnswer: function() {
let isright = this.panTi()
this.setData({
isright: isright,
@ -191,7 +186,7 @@ Page({
tm_current: this.data.tm_current
})
},
next: function () {
next: function() {
var that = this
var tm_index = that.data.tm_index + 1
that.setData({
@ -205,7 +200,7 @@ Page({
}
},
previous: function () {
previous: function() {
var that = this
var tm_index = that.data.tm_index - 1
that.setData({
@ -213,24 +208,53 @@ Page({
})
that.showTm(tm_index)
},
showOptions: function () {
showOptions: function() {
let tm_current = this.data.tm_current
let options = []
for (let key in tm_current.options) {
let option = {}
option.key = key
option.value = key + ':' + tm_current.options[key]
if (tm_current.user_answer){
if (key == tm_current.user_answer || tm_current.user_answer.indexOf(key)!=-1){
if (tm_current.user_answer) {
if (key == tm_current.user_answer || tm_current.user_answer.indexOf(key) != -1) {
option.checked = true
}
}else{
} else {
option.checked = false
}
options.push(option)
}
this.setData({
options:options
options: options
})
},
shoucang: function() {
var that = this
var tm_current = that.data.tm_current
if (tm_current.is_collect) {
api.request('crm/consumer/collects/', 'DELETE', { question: tm_current.id }).then(res => {
wx.showToast({
title: '已取消!',
icon: 'none'
})
tm_current.is_collect = false
that.setData({
tm_current: tm_current
})
})
} else {
api.request('crm/consumer/collects/', 'POST', { question: tm_current.id }).then(res => {
wx.showToast({
title: '收藏成功!',
icon: 'none'
})
tm_current.is_collect = true
that.setData({
tm_current: tm_current
})
})
}
}
})

View File

@ -57,7 +57,8 @@
<button type="primary" size="mini" bindtap="showAnswer">答案</button>
</view>
<view style="width:25%">
<image style="height: 80%;" src="/images/weishoucang.svg" bindtap="shoucang" wx:if="weishoucang"></image>
<image style="height: 80%;" src="/images/yishoucang.svg" bindtap="shoucang" wx:else></image>
<image style="height: 80%;" src="/images/yishoucang.svg" bindtap="shoucang" wx:if="{{tm_current.is_collect}}"></image>
<image style="height: 80%;" src="/images/weishoucang.svg" bindtap="shoucang" wx:else></image>
</view>
</view>

View File

@ -6,7 +6,14 @@ Page({
data: {
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo')
canIUse: wx.canIUse('button.open-type.getUserInfo'),
countDown:40,
form:{
phone:0,
code:0,
nickname:0,
avatar:0
}
},
//事件处理函数
bindViewTap: function () {
@ -15,10 +22,10 @@ Page({
})
},
phoneChange: function (e) {
this.data.phone = e.detail.value
this.data.form.phone = e.detail.value
},
codeChange: function (e) {
this.data.code = e.detail.value
this.data.form.code = e.detail.value
},
onLoad: function () {
wx.hideHomeButton()
@ -56,31 +63,77 @@ Page({
hasUserInfo: true
})
},
sendMsg : function (e){
api.request('crm/consumer/sendcode', 'GET', {phone:this.data.phone}).then(res => {
wx.showToast({
title: '验证码发送成功!',
icon:'none'
sendMsg : function (){
var that = this
if(that.isPhone(that.data.form.phone)){
api.request('crm/consumer/sendcode', 'GET', { phone: that.data.form.phone }).then(res => {
wx.showToast({
title: '验证码发送成功!注意查收',
icon: 'none'
})
getApp().globalData.timer = setInterval(function () {
that.startPass()
}, 1000)
})
})
}else{
wx.showToast({
title: '请输入正确的手机号!',
icon: 'none'
})
}
},
onGetInfo : function (e){
this.setData({
userInfo: e.detail.userInfo
})
this.denglu()
var that = this
if(e.detail.userInfo){
this.setData({
userInfo: e.detail.userInfo
})
that.data.form.nickname = e.detail.userInfo.nickName
that.data.form.avatar = e.detail.userInfo.avatarUrl
}
if(that.isPhone(that.data.form.phone)){
that.denglu(that.data.form)
}else{
wx.showToast({
title: '请输入正确的手机号!',
icon: 'none'
})
}
},
goMain: function (){
wx.reLaunch({
url: '/pages/main/main',
})
},
denglu: function () {
api.request('crm/consumer/register/', 'POST', { phone: this.data.phone, code: this.data.code }).then(res => {
denglu: function (data) {
api.request('crm/consumer/register/', 'POST', data).then(res => {
getApp().onLaunch()
wx.switchTab({
url: '/pages/main/main',
})
})
wx.switchTab({
url: '/pages/main/main',
})
},
startPass: function(){
var that = this
var mil = that.data.countDown
if (mil < 2) {
that.setData({
countDown:40
})
clearInterval(getApp().globalData.timer)
}else{
this.setData({
countDown: mil-1,
});
}
},
isPhone: function(phone){
var phoneReg = /^[1][3,4,5,7,8][0-9]{9}$/;
if (phoneReg.test(phone)) {
return true;
} else {
return false;
}
}
})

View File

@ -14,7 +14,8 @@
<input class="weui-input" placeholder="请输入手机号" bindinput="phoneChange" />
</view>
<view class="weui-cell__ft">
<view class="weui-vcode-btn" bindtap="sendMsg">获取验证码</view>
<view class="weui-vcode-btn" bindtap="sendMsg" wx:if="{{countDown==40}}">获取验证码</view>
<view class="weui-vcode-btn" wx:else>{{countDown}}s</view>
</view>
</view>
<view class="weui-cell weui-cell_input">

View File

@ -30,12 +30,12 @@
</view>
<view class="weui-grid__label">错题集</view>
</navigator>
<a class="weui-grid">
<navigator class="weui-grid" url="/pages/collect/main">
<view class="weui-grid__icon">
<image src="/images/shoucang.svg" alt></image>
</view>
<view class="weui-grid__label">收藏集</view>
</a>
</navigator>
</view>
</view>
<view class="weui-cells__title">考试</view>

View File

@ -0,0 +1,81 @@
// pages/my/index.js
const api = require("../../utils/request.js");
Page({
/**
* 页面的初始数据
*/
data: {
total:0,
avg_score:0,
pass_rate:0
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.setData({
userinfo: getApp().globalData.userinfo
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
api.request('examtest/myexamtestfx', 'GET').then(res => {
this.setData(res.data)
})
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
register: function() {
var that = this
if (!that.data.userinfo.username){
wx.reLaunch({
url: '/pages/login/login',
})
}
}
})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,42 @@
<view class="page">
<view class="page__bd">
<view style="height:10px"></view>
<view class="weui-cells__title">基本信息</view>
<view class="weui-cells weui-cells_after-title">
<view class="weui-panel__bd">
<view class="weui-media-box weui-media-box_appmsg" hover-class="weui-cell_active" bindtap="register">
<view class="weui-media-box__hd weui-media-box__hd_in-appmsg">
<open-data type="userAvatarUrl"></open-data>
</view>
<view class="weui-media-box__bd weui-media-box__bd_in-appmsg">
<view class="weui-media-box__title" wx:if="{{userinfo && userinfo.username}}">账号: {{userinfo.username}}
</view>
<view class="weui-media-box__title" wx:else>账号: 未登陆
</view>
<view class="weui-media-box__desc">昵称:
<open-data type="userNickName"></open-data>
</view>
<view class="weui-media-box__desc">单位:
<span wx:if="{{userinfo && userinfo.company_name}}">{{ userinfo.company_name }}</span>
</view>
</view>
</view>
</view>
</view>
<view class="weui-cells__title">统计分析</view>
<view class="weui-cells weui-cells_after-title">
<view class="weui-cell">
<view class="weui-cell__bd">自助模考数量</view>
<view class="weui-cell__ft" style="font-weight:bold;color:darkblue">{{total}}</view>
</view>
<view class="weui-cell">
<view class="weui-cell__bd">通过率</view>
<view class="weui-cell__ft" style="font-weight:bold;color:darkblue">{{pass_rate}}%</view>
</view>
<view class="weui-cell">
<view class="weui-cell__bd">平均分</view>
<view class="weui-cell__ft" style="font-weight:bold;color:darkblue" wx:if="{{avg_score}}">{{avg_score}}</view>
</view>
</view>
</view>
</view>

View File

@ -0,0 +1 @@
/* pages/my/index.wxss */

View File

@ -47,14 +47,10 @@
</view>
</scroll-view>
<view class="btns">
<view style="width:33%">
<view style="width:50%">
<button type="primary" size="mini" bindtap="previous" disabled="{{tm_index==0}}">上题</button>
</view>
<view style="width:33%">
<view style="width:50%">
<button type="primary" size="mini" bindtap="next" disabled="{{tm_index==tmtotal-1}}">下题</button>
</view>
<view style="width:33%">
<image style="height: 80%;" src="/images/weishoucang.svg" bindtap="shoucang" wx:if="weishoucang"></image>
<image style="height: 80%;" src="/images/yishoucang.svg" bindtap="shoucang" wx:else></image>
</view>
</view>

View File

@ -24,7 +24,7 @@
},
"compileType": "miniprogram",
"libVersion": "2.10.3",
"appid": "wx5c39b569f01c27db",
"appid": "wxf1e9471c93f05ad6",
"projectname": "test_mini",
"debugOptions": {
"hidedInDevtools": []

View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.4 on 2020-03-23 06:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('question', '0007_auto_20200319_0846'),
('crm', '0008_auto_20200322_2113'),
]
operations = [
migrations.AddField(
model_name='consumer',
name='collects',
field=models.ManyToManyField(to='question.Question', verbose_name='收藏试题'),
),
]

View File

@ -1,7 +1,7 @@
from django.db import models
import django.utils.timezone as timezone
from rbac.models import SoftCommonModel, CommonModel
from question.models import Questioncat
from question.models import Questioncat, Question
# Create your models here.
class Company(SoftCommonModel):
@ -29,6 +29,7 @@ class Consumer(SoftCommonModel):
avatar = models.CharField(default='/media/default/avatar.png',max_length=1000, null=True, blank=True, verbose_name='头像')
nickname = models.CharField(max_length=200, verbose_name='昵称', null=True, blank=True)
subjects = models.ManyToManyField(Questioncat, verbose_name='付费学科', through='PaySubject')
collects = models.ManyToManyField(Question, verbose_name='收藏试题')
class Meta:

View File

@ -24,12 +24,13 @@ from rbac.permission import RbacPermission
from crm.authentication import ConsumerTokenAuthentication
from .models import Company, Consumer, PaySubject, SendCode
from .serializers import CompanySerializer, ConsumerSerializer
from question.serializers import QuestionSerializer
from server import settings
from question.models import Questioncat
from crm.zhenzismsclient import ZhenziSmsClient
appid = 'wx5c39b569f01c27db'
secret = '68762892f8df2b4a0b1940c5250a8dc0'
appid = 'wxf1e9471c93f05ad6'
secret = '4bf7f9bd6c52634586bbe792a1f0a834'
sms_appid = '104951'
sms_appsecret = '3d0ccaf9-f680-47e3-ad93-9e83093c5a04'
sms_url = 'https://sms_developer.zhenzikj.com'
@ -117,6 +118,9 @@ class ConsumerViewSet(ModelViewSet):
@action(methods=['get'], detail=False, permission_classes=[], authentication_classes=[],
url_path='sendcode', url_name='code_send')
def sendcode(self, request):
'''
发送二维码
'''
client = ZhenziSmsClient(sms_url, sms_appid, sms_appsecret)
code = random.randint(1000,9999)
phone = request.query_params.get('phone')
@ -127,6 +131,33 @@ class ConsumerViewSet(ModelViewSet):
return Response(status=status.HTTP_200_OK)
else:
return Response({'error':result['data']})
@action(methods=['post','delete', 'get'], detail=False, permission_classes=[], authentication_classes=[ConsumerTokenAuthentication],
url_path='collects', url_name='create_collects')
def collects(self, request):
'''
个人收藏集
'''
if request.method == 'POST':
questionId = request.data.get('question',None)
if questionId:
request.user.collects.remove(questionId)
request.user.collects.add(questionId)
return Response(status=status.HTTP_200_OK)
else:
return Response({'error':'post参数错误'})
elif request.method == 'GET':
queryset = request.user.collects.all().order_by('-update_time')
serializer = QuestionSerializer(instance=queryset,many=True)
return Response(serializer.data)
else:
questionId = request.data.get('question',None)
if questionId:
request.user.collects.remove(questionId)
return Response(status=status.HTTP_200_OK)
else:
return Response({'error':'delete参数错误'})
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated],
url_path='import', url_name='import_consumer')
@ -145,6 +176,8 @@ class ConsumerViewSet(ModelViewSet):
return Response({"error":"账户列错误!"})
if sheet['c2'].value != '单位':
return Response({"error":"单位列错误!"})
if sheet['d2'].value != '付费学科':
return Response({"error":"付费学科列错误!"})
companydict = {}
consumerdict = {}
companys = Company.objects.filter(is_delete=0)
@ -165,6 +198,7 @@ class ConsumerViewSet(ModelViewSet):
return Response({"error":"不存在单位("+companyname+")!请先新建"})
else:
companyobj = Company.objects.get(id=companydict[companyname])
subjects = sheet['d'+str(i)].value
if Consumer.objects.filter(username = username).exists():
consumerdict[username]=i
else:
@ -173,9 +207,12 @@ class ConsumerViewSet(ModelViewSet):
obj.username = username
obj.company = companyobj
obj.save()
subjects = Questioncat.objects.filter(is_subject=True,is_delete=False)
if subjects.exists():
PaySubject.objects.create(subject=subjects.first(), consumer=obj)
if subjects:
subjects_list = subjects.replace(' ','').split(',')
for i in subjects_list:
queryset = Questioncat.objects.filter(name=i,is_subject=True,is_delete=False)
if queryset.exists():
PaySubject.objects.create(subject=queryset.first(), consumer=obj)
i = i + 1
if consumerdict:
return {"code":206,"data":consumerdict,"msg":"导入部分成功"}
@ -218,16 +255,32 @@ class ConsumerRegister(APIView):
data = request.data
phone = data.get('phone', None)
code = data.get('code', None)
avatar = data.get('avatar', None)
nickname = data.get('nickname', None)
if phone and code:
obj = SendCode.objects.filter(phone=phone).last()
if code == obj.code: # 验证通过
consumer_queryset = Consumer.objects.filter(username=phone)
if consumer_queryset.exists(): # 是否存在
consumer = consumer_queryset.first()
openid = request.user.openid
request.user.delete(soft=False) # 彻底删除
consumer.openid = openid
consumer.save()
return Response(status=status.HTTP_200_OK)
if obj:
if code == obj.code: # 验证通过
consumer_queryset = Consumer.objects.filter(username=phone)
if consumer_queryset.exists(): # 是否存在
consumer = consumer_queryset.first()
openid = request.user.openid
request.user.delete(soft=False) # 彻底删除
consumer.openid = openid
if avatar and nickname:
consumer.avatar = avatar
consumer.nickname = nickname
consumer.save()
return Response(status=status.HTTP_200_OK)
else:
consumer = request.user
consumer.username = phone
if avatar and nickname:
consumer.avatar = avatar
consumer.nickname = nickname
consumer.save()
return Response(status=status.HTTP_200_OK)
else:
return Response({'error':'验证码错误!'})
else:
return Response({'error':'验证码错误!'})
return Response({'error':'认证错误!'})

View File

@ -66,4 +66,4 @@ class AnswerDetail(SoftCommonModel):
is_right = models.BooleanField(default=False, verbose_name='是否正确')
class Meta:
verbose_name = '答题记录'
verbose_name_plural = verbose_name
verbose_name_plural = verbose_name

View File

@ -1,5 +1,5 @@
from django.urls import path,include
from .views import TestRuleViewSet, MoniTestView, MyExamTestView, AnswerDetailView
from .views import TestRuleViewSet, MoniTestView, MyExamTestView, AnswerDetailView, MyExamTestFxView
from rest_framework import routers
@ -9,6 +9,7 @@ router.register('testrule', TestRuleViewSet, basename="testrule")
urlpatterns = [
path('monitest/',MoniTestView.as_view()),
path('myexamtest/',MyExamTestView.as_view()),
path('myexamtestfx/',MyExamTestFxView.as_view()),
path('answerdetail/', AnswerDetailView.as_view()),
path('', include(router.urls)),
]

View File

@ -10,6 +10,7 @@ from django_filters.rest_framework import DjangoFilterBackend
from openpyxl import Workbook, load_workbook
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from datetime import datetime
from django.db.models import Avg
from utils.custom import CommonPagination
from rbac.permission import RbacPermission
@ -64,6 +65,16 @@ class MyExamTestView(APIView):
serializer = ExamTestListSerializer(instance=p,many=True)
return pg.get_paginated_response(serializer.data)
class MyExamTestFxView(APIView):
authentication_classes = [ConsumerTokenAuthentication]
permission_classes = []
def get(self, request, *args, **kwargs):
queryset = ExamTest.objects.filter(consumer=request.user)
ret = {}
ret['total'] = queryset.count()
ret['avg_score'] = queryset.aggregate(avg=Avg('score'))['avg']
ret['pass_rate'] = round(((queryset.filter(is_pass=True).count())/ret['total'])*100) if ret['total'] else 0
return Response(ret)
class AnswerDetailView(APIView):
authentication_classes = []
@ -75,7 +86,6 @@ class AnswerDetailView(APIView):
serializer = AnswerDetailSerializer(instance=queryset,many=True)
return Response(serializer.data)
class TestRuleViewSet(ModelViewSet):
"""

View File

@ -270,4 +270,11 @@ class ExerciseView(APIView):
# serializer = QuestionSerializer(instance=p,many=True)
# return pg.get_paginated_response(serializer.data)
serializer = QuestionSerializer(instance=queryset,many=True)
return Response({'total':total, 'results':serializer.data})
collects = request.user.collects.all().values_list('id',flat=True) #当前用户收藏的题目
results = serializer.data
for i in results:
if i['id'] in collects:
i['is_collect'] = True
else:
i['is_collect'] = False
return Response({'total':total, 'results':results})