diff --git a/test_client/src/router/index.js b/test_client/src/router/index.js index c2dd927..6045b3a 100644 --- a/test_client/src/router/index.js +++ b/test_client/src/router/index.js @@ -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', diff --git a/test_client/src/views/analyse/chart.vue b/test_client/src/views/analyse/chart.vue new file mode 100644 index 0000000..e69de29 diff --git a/test_client/src/views/analyse/djlist.vue b/test_client/src/views/analyse/djlist.vue new file mode 100644 index 0000000..e69de29 diff --git a/test_client/src/views/examtest/paper.vue b/test_client/src/views/examtest/paper.vue new file mode 100644 index 0000000..e69de29 diff --git a/test_client/src/views/login/index.vue b/test_client/src/views/login/index.vue index 79fc016..0018a1b 100644 --- a/test_client/src/views/login/index.vue +++ b/test_client/src/views/login/index.vue @@ -3,7 +3,7 @@
-

登陆系统

+

答题平台后台管理

diff --git a/test_mini/app.js b/test_mini/app.js index 684abc4..07f6491 100644 --- a/test_mini/app.js +++ b/test_mini/app.js @@ -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 : '', diff --git a/test_mini/app.json b/test_mini/app.json index 9afa48d..e12ef94 100644 --- a/test_mini/app.json +++ b/test_mini/app.json @@ -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": "个人中心" diff --git a/test_mini/pages/collect/main.js b/test_mini/pages/collect/main.js new file mode 100644 index 0000000..f02f87f --- /dev/null +++ b/test_mini/pages/collect/main.js @@ -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({ + }) + } + }) + + } +}) \ No newline at end of file diff --git a/test_mini/pages/collect/main.json b/test_mini/pages/collect/main.json new file mode 100644 index 0000000..78d7ca7 --- /dev/null +++ b/test_mini/pages/collect/main.json @@ -0,0 +1,4 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "收藏集" +} \ No newline at end of file diff --git a/test_mini/pages/collect/main.wxml b/test_mini/pages/collect/main.wxml new file mode 100644 index 0000000..69f8d35 --- /dev/null +++ b/test_mini/pages/collect/main.wxml @@ -0,0 +1,66 @@ + + 题量: {{tm_index+1}}/{{tmtotal}} + + + + {{tm_index+1}}. + {{tm_current.type}} + + + {{tm_current.questioncat_name}}( + {{tm_current.dtime}}) + + {{tm_current.name}} + + + + + + + + + + + + + 回答正确! + 回答有误! + 正确答案是{{tm_current.right}},你的答案是{{tm_current.user_answer}} + + 解析: + {{tm_current.resoluation}} + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test_mini/pages/collect/main.wxss b/test_mini/pages/collect/main.wxss new file mode 100644 index 0000000..0ee5e6b --- /dev/null +++ b/test_mini/pages/collect/main.wxss @@ -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 +} + diff --git a/test_mini/pages/lianxi/index.js b/test_mini/pages/lianxi/index.js index 05e9f9c..9ab415d 100644 --- a/test_mini/pages/lianxi/index.js +++ b/test_mini/pages/lianxi/index.js @@ -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++) { diff --git a/test_mini/pages/lianxi/main.js b/test_mini/pages/lianxi/main.js index 6224c35..8b328ed 100644 --- a/test_mini/pages/lianxi/main.js +++ b/test_mini/pages/lianxi/main.js @@ -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 + }) + }) + + } + } }) \ No newline at end of file diff --git a/test_mini/pages/lianxi/main.wxml b/test_mini/pages/lianxi/main.wxml index a8b5ff5..f1caa53 100644 --- a/test_mini/pages/lianxi/main.wxml +++ b/test_mini/pages/lianxi/main.wxml @@ -57,7 +57,8 @@ - - + + + \ No newline at end of file diff --git a/test_mini/pages/login/login.js b/test_mini/pages/login/login.js index fbf4f6d..64e9181 100644 --- a/test_mini/pages/login/login.js +++ b/test_mini/pages/login/login.js @@ -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; + } } }) diff --git a/test_mini/pages/login/login.wxml b/test_mini/pages/login/login.wxml index ec2ae6e..83f347e 100644 --- a/test_mini/pages/login/login.wxml +++ b/test_mini/pages/login/login.wxml @@ -14,7 +14,8 @@ - 获取验证码 + 获取验证码 + {{countDown}}s diff --git a/test_mini/pages/main/main.wxml b/test_mini/pages/main/main.wxml index ed7d8a4..6065cd9 100644 --- a/test_mini/pages/main/main.wxml +++ b/test_mini/pages/main/main.wxml @@ -30,12 +30,12 @@ 错题集 - + 收藏集 - + 考试 diff --git a/test_mini/pages/my/index.js b/test_mini/pages/my/index.js new file mode 100644 index 0000000..1a2b279 --- /dev/null +++ b/test_mini/pages/my/index.js @@ -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', + }) + } + } +}) \ No newline at end of file diff --git a/test_mini/pages/my/index.json b/test_mini/pages/my/index.json new file mode 100644 index 0000000..8835af0 --- /dev/null +++ b/test_mini/pages/my/index.json @@ -0,0 +1,3 @@ +{ + "usingComponents": {} +} \ No newline at end of file diff --git a/test_mini/pages/my/index.wxml b/test_mini/pages/my/index.wxml new file mode 100644 index 0000000..7f5a469 --- /dev/null +++ b/test_mini/pages/my/index.wxml @@ -0,0 +1,42 @@ + + + + 基本信息 + + + + + + + + 账号: {{userinfo.username}} + + 账号: 未登陆 + + 昵称: + + + 单位: + {{ userinfo.company_name }} + + + + + + 统计分析 + + + 自助模考数量 + {{total}} + + + 通过率 + {{pass_rate}}% + + + 平均分 + {{avg_score}} + + + + \ No newline at end of file diff --git a/test_mini/pages/my/index.wxss b/test_mini/pages/my/index.wxss new file mode 100644 index 0000000..beb7c9e --- /dev/null +++ b/test_mini/pages/my/index.wxss @@ -0,0 +1 @@ +/* pages/my/index.wxss */ \ No newline at end of file diff --git a/test_mini/pages/test/detail.wxml b/test_mini/pages/test/detail.wxml index 36def9e..83dd76b 100644 --- a/test_mini/pages/test/detail.wxml +++ b/test_mini/pages/test/detail.wxml @@ -47,14 +47,10 @@ - + - + - - - - \ No newline at end of file diff --git a/test_mini/project.config.json b/test_mini/project.config.json index 1581b63..8b6c1e8 100644 --- a/test_mini/project.config.json +++ b/test_mini/project.config.json @@ -24,7 +24,7 @@ }, "compileType": "miniprogram", "libVersion": "2.10.3", - "appid": "wx5c39b569f01c27db", + "appid": "wxf1e9471c93f05ad6", "projectname": "test_mini", "debugOptions": { "hidedInDevtools": [] diff --git a/test_server/crm/migrations/0009_consumer_collects.py b/test_server/crm/migrations/0009_consumer_collects.py new file mode 100644 index 0000000..fd34696 --- /dev/null +++ b/test_server/crm/migrations/0009_consumer_collects.py @@ -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='收藏试题'), + ), + ] diff --git a/test_server/crm/models.py b/test_server/crm/models.py index 93e611e..ee68a44 100644 --- a/test_server/crm/models.py +++ b/test_server/crm/models.py @@ -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: diff --git a/test_server/crm/views.py b/test_server/crm/views.py index 7d5330a..4f6c5da 100644 --- a/test_server/crm/views.py +++ b/test_server/crm/views.py @@ -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':'验证码错误!'}) \ No newline at end of file + return Response({'error':'认证错误!'}) \ No newline at end of file diff --git a/test_server/examtest/models.py b/test_server/examtest/models.py index 9283be5..b81a205 100644 --- a/test_server/examtest/models.py +++ b/test_server/examtest/models.py @@ -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 \ No newline at end of file diff --git a/test_server/examtest/urls.py b/test_server/examtest/urls.py index de3e18c..1453548 100644 --- a/test_server/examtest/urls.py +++ b/test_server/examtest/urls.py @@ -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)), ] diff --git a/test_server/examtest/views.py b/test_server/examtest/views.py index bc4d864..5a164d5 100644 --- a/test_server/examtest/views.py +++ b/test_server/examtest/views.py @@ -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): """ diff --git a/test_server/question/views.py b/test_server/question/views.py index 804165f..484b88d 100644 --- a/test_server/question/views.py +++ b/test_server/question/views.py @@ -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}) \ No newline at end of file + 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}) \ No newline at end of file