From ee8c64f169ce84b5dae760d5d6b2ed71d19f33f2 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sun, 13 Jun 2021 22:46:59 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E7=AD=BE=E5=88=B0?= =?UTF-8?q?=E5=92=8C=E7=8E=B0=E5=9C=BA=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_mini/app.js | 4 +- test_mini/app.json | 3 +- test_mini/pages/admin/exam/detail.js | 21 +- test_mini/pages/admin/exam/detail.wxml | 64 +++--- test_mini/pages/admin/exam/upimg.js | 207 ++++++++++++++++++ test_mini/pages/admin/exam/upimg.json | 4 + test_mini/pages/admin/exam/upimg.wxml | 65 ++++++ test_mini/pages/admin/exam/upimg.wxss | 1 + test_mini/project.config.json | 6 +- .../migrations/0031_auto_20210613_2229.py | 24 ++ .../migrations/0032_auto_20210613_2234.py | 32 +++ test_server/examtest/models.py | 5 +- test_server/examtest/views.py | 13 +- 13 files changed, 405 insertions(+), 44 deletions(-) create mode 100644 test_mini/pages/admin/exam/upimg.js create mode 100644 test_mini/pages/admin/exam/upimg.json create mode 100644 test_mini/pages/admin/exam/upimg.wxml create mode 100644 test_mini/pages/admin/exam/upimg.wxss create mode 100644 test_server/examtest/migrations/0031_auto_20210613_2229.py create mode 100644 test_server/examtest/migrations/0032_auto_20210613_2234.py diff --git a/test_mini/app.js b/test_mini/app.js index 877e559..307bbe3 100644 --- a/test_mini/app.js +++ b/test_mini/app.js @@ -70,9 +70,9 @@ App({ globalData: { userInfo: {}, userinfo: {}, // 服务器传回的消费者信息 - host: 'https://apitest.ahctc.cn', + //host: 'https://apitest.ahctc.cn', mediahost: 'https://apitest.ahctc.cn', - //host: 'http://127.0.0.1:8000', + host: 'http://127.0.0.1:8000', //mediahost: 'http://127.0.0.1:8000', token : '', rlogin:true diff --git a/test_mini/app.json b/test_mini/app.json index ed34f71..f643090 100644 --- a/test_mini/app.json +++ b/test_mini/app.json @@ -39,7 +39,8 @@ "pages/admin/exam/index", "pages/candidate/show", "pages/admin/candidate/index", - "pages/candidate/my" + "pages/candidate/my", + "pages/admin/exam/upimg" ], "window": { "backgroundTextStyle": "light", diff --git a/test_mini/pages/admin/exam/detail.js b/test_mini/pages/admin/exam/detail.js index 47c2986..e4eb023 100644 --- a/test_mini/pages/admin/exam/detail.js +++ b/test_mini/pages/admin/exam/detail.js @@ -16,11 +16,7 @@ Page({ onLoad: function (options) { if(options.id){ let id = options.id - api.requesta(`/examtest/exam/${id}/`, 'GET').then(res=>{ - this.setData({ - exam:res.data - }) - }) + that.data.exam.id = id api.requesta('/examtest/examtest/', 'GET', {exam:id, pageoff:true}).then(res=>{ this.setData({ tests:res.data @@ -28,6 +24,14 @@ Page({ }) } }, + getExam: function(){ + let id = this.data.exam.id + api.requesta(`/examtest/exam/${id}/`, 'GET').then(res=>{ + this.setData({ + exam:res.data + }) + }) + }, issue: function(){ wx.showLoading({ title: '正在生成...', @@ -45,7 +49,7 @@ Page({ * 生命周期函数--监听页面显示 */ onShow: function () { - + this.getExam() }, /** @@ -108,5 +112,10 @@ Page({ wx.navigateTo({ url: '/pages/candidate/show?id='+candidate_.id, }) + }, + upImg: function(){ + wx.navigateTo({ + url: '/pages/admin/exam/upimg?id='+this.data.exam.id, + }) } }) \ No newline at end of file diff --git a/test_mini/pages/admin/exam/detail.wxml b/test_mini/pages/admin/exam/detail.wxml index c005bd7..46901ca 100644 --- a/test_mini/pages/admin/exam/detail.wxml +++ b/test_mini/pages/admin/exam/detail.wxml @@ -1,39 +1,42 @@ - - - - {{exam.name}} - - + + + + {{exam.name}} + + 工作类别:{{exam.workscope_name}} - + 考试地点:{{exam.place}} - + 开关时间:{{exam.opentime}}-{{exam.closetime}} 监考人:{{exam.proctor_name}}-{{exam.proctor_phone}} + + + + - - - 共{{tests.length}}次考试记录 - - -

- 通过 - 未过 - {{item.consumer_detail.name}} + + 共{{tests.length}}次考试记录 + + +

+ 通过 + 未过 + {{item.consumer_detail.name}}

{{item.consumer_detail.company_name}} {{item.consumer_detail.deptname}} - + 身份证号:{{item.consumer_detail.ID_number}} @@ -47,22 +50,25 @@ {{item.candidate_.number}} - - - - + + + +
-
- -
+ - 到底了 - - - \ No newline at end of file + 到底了 + + + \ No newline at end of file diff --git a/test_mini/pages/admin/exam/upimg.js b/test_mini/pages/admin/exam/upimg.js new file mode 100644 index 0000000..60a7592 --- /dev/null +++ b/test_mini/pages/admin/exam/upimg.js @@ -0,0 +1,207 @@ +// pages/admin/exam/u'p.js +const api = require("../../../utils/request.js"); +Page({ + + /** + * 页面的初始数据 + */ + data: { + exam:0, + qdimgs: [], + xcimgs: [], + upqdimgs:[], + upxcimgs:[] + }, + chooseImage: function (e) { + var that = this; + wx.chooseImage({ + sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 + sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 + success: function (res) { + // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片 + console.log(e.currentTarget.dataset.type) + if(e.currentTarget.dataset.type == 'qdimgs'){ + that.setData({ + qdimgs: that.data.qdimgs.concat(res.tempFilePaths) + }); + }else{ + that.setData({ + xcimgs: that.data.xcimgs.concat(res.tempFilePaths) + }); + } + + } + }) + }, + previewImage: function (e) { + if(e.currentTarget.dataset.type=='qdimgs'){ + wx.previewImage({ + current: e.currentTarget.id, // 当前显示图片的http链接 + urls: this.data.qdimgs // 需要预览的图片http链接列表 + }) + }else{ + wx.previewImage({ + current: e.currentTarget.id, // 当前显示图片的http链接 + urls: this.data.xcimgs // 需要预览的图片http链接列表 + }) + } + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + this.data.exam = options.id + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady: function () { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow: function () { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide: function () { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload: function () { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh: function () { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom: function () { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage: function () { + + }, + deleteImg: function(e){ + var that = this + wx.showModal({ + content: '确认删除该图片?', + success (res) { + if (res.confirm) { + if(e.currentTarget.dataset.type=='qdimgs'){ + var qdimgs = that.data.qdimgs + qdimgs.splice(e.currentTarget.dataset.index, 1); + that.setData({ + qdimgs:qdimgs + }) + }else{ + var xcimgs = that.data.xcimgs + xcimgs.splice(e.currentTarget.dataset.index, 1); + that.setData({ + xcimgs:xcimgs + }) + } + } + } + }) + }, + confirm: function(){ + if(this.data.upqdimgs.length>0 && this.data.upxcimgs.length>0){ + let formdata={ + qdimgs:this.data.upqdimgs, + xcimgs:this.data.upxcimgs + } + let id = this.data.exam + wx.showLoading({ + title: '正在提交...', + }) + api.requesta(`/examtest/exam/${id}/upimgs/`,'POST', formdata).then(res=>{ + wx.hideLoading({ + success: (res) => {}, + }) + wx.navigateBack({ + delta: 0, + }) + }) + } + else if(this.data.qdimgs.length>0 && this.data.xcimgs.length>0){ + this.upImgx(0, 'qdimgs') + } + else{ + wx.showToast({ + title: '图片信息不全', + }) + } + }, + upImgx: function(index, type){ + var that = this + if(type=='qdimgs'){ + let x = index+1 + wx.showLoading({ + title: '正在上传签到图片', + }) + wx.uploadFile({ + filePath: that.data.qdimgs[index], + name: 'file', + url: getApp().globalData.host+'/uploadfile/', + header:{ + 'Authorization': 'JWT ' + getApp().globalData.admintoken + }, + success (res){ + wx.hideLoading() + let data = JSON.parse(res.data); + that.data.upqdimgs.push(data.data.path) + if(x == that.data.qdimgs.length){ + that.upImgx(0, 'xcimgs') + }else{ + that.upImgx(index+1, 'qdimgs') + } + } + }) + }else{ + let x = index+1 + wx.showLoading({ + title: '正在上传现场图片', + }) + wx.uploadFile({ + filePath: that.data.xcimgs[index], + name: 'file', + url: getApp().globalData.host+'/uploadfile/', + header:{ + 'Authorization': 'JWT ' + getApp().globalData.admintoken + }, + success (res){ + wx.hideLoading() + let data = JSON.parse(res.data); + that.data.upxcimgs.push(data.data.path) + if(x == that.data.xcimgs.length){ + that.confirm() + }else{ + that.upImgx(index+1, 'xcimgs') + } + } + }) + } + + } +}) \ No newline at end of file diff --git a/test_mini/pages/admin/exam/upimg.json b/test_mini/pages/admin/exam/upimg.json new file mode 100644 index 0000000..b55b5a2 --- /dev/null +++ b/test_mini/pages/admin/exam/upimg.json @@ -0,0 +1,4 @@ +{ + "usingComponents": { + } +} \ No newline at end of file diff --git a/test_mini/pages/admin/exam/upimg.wxml b/test_mini/pages/admin/exam/upimg.wxml new file mode 100644 index 0000000..d05ce30 --- /dev/null +++ b/test_mini/pages/admin/exam/upimg.wxml @@ -0,0 +1,65 @@ + + + + + + + + + 签到表图片 + + + + 长按删除 + + + + + + + + + + + + + + + + + + + + + + + 现场照片 + + + + 长按删除 + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test_mini/pages/admin/exam/upimg.wxss b/test_mini/pages/admin/exam/upimg.wxss new file mode 100644 index 0000000..227da4c --- /dev/null +++ b/test_mini/pages/admin/exam/upimg.wxss @@ -0,0 +1 @@ +/* pages/admin/exam/u'p.wxss */ \ No newline at end of file diff --git a/test_mini/project.config.json b/test_mini/project.config.json index 3ce91d1..1945110 100644 --- a/test_mini/project.config.json +++ b/test_mini/project.config.json @@ -23,20 +23,20 @@ "compileHotReLoad": false, "useMultiFrameRuntime": true, "useApiHook": true, - "useApiHostProcess": false, "babelSetting": { "ignore": [], "disablePlugins": [], "outputPath": "" }, - "enableEngineNative": false, + "bundle": false, "useIsolateContext": true, "useCompilerModule": true, "userConfirmedUseCompilerModuleSwitch": false, "userConfirmedBundleSwitch": false, "packNpmManually": false, "packNpmRelationList": [], - "minifyWXSS": true + "minifyWXSS": true, + "useApiHostProcess": false }, "compileType": "miniprogram", "libVersion": "2.15.0", diff --git a/test_server/examtest/migrations/0031_auto_20210613_2229.py b/test_server/examtest/migrations/0031_auto_20210613_2229.py new file mode 100644 index 0000000..b2ac982 --- /dev/null +++ b/test_server/examtest/migrations/0031_auto_20210613_2229.py @@ -0,0 +1,24 @@ +# Generated by Django 3.0.4 on 2021-06-13 14:29 + +import django.contrib.postgres.fields.jsonb +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('examtest', '0030_examtest_consumer_detail'), + ] + + operations = [ + migrations.AddField( + model_name='examtest', + name='qdimgs', + field=django.contrib.postgres.fields.jsonb.JSONField(default=list, verbose_name='签到图片'), + ), + migrations.AddField( + model_name='examtest', + name='xcimgs', + field=django.contrib.postgres.fields.jsonb.JSONField(default=list, verbose_name='现场图片'), + ), + ] diff --git a/test_server/examtest/migrations/0032_auto_20210613_2234.py b/test_server/examtest/migrations/0032_auto_20210613_2234.py new file mode 100644 index 0000000..761de4b --- /dev/null +++ b/test_server/examtest/migrations/0032_auto_20210613_2234.py @@ -0,0 +1,32 @@ +# Generated by Django 3.0.4 on 2021-06-13 14:34 + +import django.contrib.postgres.fields.jsonb +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('examtest', '0031_auto_20210613_2229'), + ] + + operations = [ + migrations.RemoveField( + model_name='examtest', + name='qdimgs', + ), + migrations.RemoveField( + model_name='examtest', + name='xcimgs', + ), + migrations.AddField( + model_name='exam', + name='qdimgs', + field=django.contrib.postgres.fields.jsonb.JSONField(default=list, verbose_name='签到图片'), + ), + migrations.AddField( + model_name='exam', + name='xcimgs', + field=django.contrib.postgres.fields.jsonb.JSONField(default=list, verbose_name='现场图片'), + ), + ] diff --git a/test_server/examtest/models.py b/test_server/examtest/models.py index 4a9b04d..8d92e04 100644 --- a/test_server/examtest/models.py +++ b/test_server/examtest/models.py @@ -20,7 +20,9 @@ class Exam(CommonModel): proctor_phone = models.CharField('监考人联系方式', max_length=100) create_admin = models.ForeignKey(UserProfile, on_delete=models.SET_NULL, null=True, blank=True, related_name='exam_create_admin') chance = models.IntegerField('考试机会', default=3) - + + qdimgs = JSONField('签到图片', default=list) + xcimgs = JSONField('现场图片', default=list) def __str__(self): return self.name @@ -49,6 +51,7 @@ class ExamTest(CommonModel): is_pass = models.BooleanField(default=True, verbose_name='是否通过') exam = models.ForeignKey(Exam, verbose_name='关联的正式考试', null=True, blank=True, related_name='examtest_exam', on_delete= models.SET_NULL) + class Meta: verbose_name = '模拟考试' verbose_name_plural = verbose_name diff --git a/test_server/examtest/views.py b/test_server/examtest/views.py index b3bdcc6..d3237b5 100644 --- a/test_server/examtest/views.py +++ b/test_server/examtest/views.py @@ -157,6 +157,13 @@ class ExamViewSet(ModelViewSet): return Response(ret) return Response({'error':'生成试卷失败'}) + @action(methods=['post'], detail = True ,perms_map=[{'post':'exam_update'}]) + def upimgs(self, request, *args, **kwargs): + obj = self.get_object() + obj.qdimgs = request.data.get('qdimgs', []) + obj.xcimgs = request.data.get('xcimgs', []) + obj.save() + return Response() class AnswerDetailView(APIView): @@ -392,8 +399,9 @@ class ExamTestViewSet(PageOrNot, ModelViewSet): filterset_fields = ['type','is_pass', 'exam'] def get_serializer_class(self): - if self.request.query_params.get('exam', None) or self.request.query_params.get('type') == '正式考试': - return ExamTestExamListSerializer + if self.request: + if self.request.query_params.get('exam', None) or self.request.query_params.get('type') == '正式考试': + return ExamTestExamListSerializer return ExamTestListSerializer def filter_queryset(self, queryset): @@ -535,6 +543,7 @@ class ExamTestViewSet(PageOrNot, ModelViewSet): candidate.create_admin = request.user candidate.save() return Response({"id":candidate.pk, "number":candidate.number}) + class PaperViewSet(ModelViewSet): """ From 0a357b3765e29c0ca4eb516b5a4b291e8ed6e6a9 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 14 Jun 2021 22:10:11 +0800 Subject: [PATCH 2/2] =?UTF-8?q?pc=E7=AB=AF=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_client/src/api/candidate.js | 9 ++ test_client/src/router/index.js | 10 +- test_client/src/views/exam/issue.vue | 126 +++++++++++++++++++++++++ test_mini/app.js | 4 +- test_mini/pages/admin/exam/detail.js | 29 +++++- test_mini/pages/admin/exam/detail.wxml | 49 +++++++++- test_mini/pages/main/main.wxml | 9 -- test_mini/pages/my/index.wxml | 15 ++- test_server/crm/models.py | 2 +- test_server/crm/serializers.py | 1 + 10 files changed, 231 insertions(+), 23 deletions(-) create mode 100644 test_client/src/api/candidate.js create mode 100644 test_client/src/views/exam/issue.vue diff --git a/test_client/src/api/candidate.js b/test_client/src/api/candidate.js new file mode 100644 index 0000000..4374232 --- /dev/null +++ b/test_client/src/api/candidate.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +export function getCandidateList(query) { + return request({ + url: '/crm/candidate/', + method: 'get', + params:query + }) +} \ No newline at end of file diff --git a/test_client/src/router/index.js b/test_client/src/router/index.js index af2b724..214f289 100644 --- a/test_client/src/router/index.js +++ b/test_client/src/router/index.js @@ -252,13 +252,19 @@ export const asyncRoutes = [ component: Layout, redirect: '/exammanage/index', name: 'Exammanage', - meta: { title: '考试管理', icon: ''}, + meta: { title: '考证管理', icon: 'component'}, children: [ { path: 'index', name: 'exam', component: () => import('@/views/exam/index.vue'), - meta: { title: '考试管理', icon: 'component', perms: ['exam_view'] } + meta: { title: '正式考试', perms: ['exam_view'] } + }, + { + path: 'issue', + name: 'issue', + component: () => import('@/views/exam/issue.vue'), + meta: { title: '出证记录', perms: ['candidate_view'] } }, ] }, diff --git a/test_client/src/views/exam/issue.vue b/test_client/src/views/exam/issue.vue new file mode 100644 index 0000000..d1a8618 --- /dev/null +++ b/test_client/src/views/exam/issue.vue @@ -0,0 +1,126 @@ + + + diff --git a/test_mini/app.js b/test_mini/app.js index 307bbe3..877e559 100644 --- a/test_mini/app.js +++ b/test_mini/app.js @@ -70,9 +70,9 @@ App({ globalData: { userInfo: {}, userinfo: {}, // 服务器传回的消费者信息 - //host: 'https://apitest.ahctc.cn', + host: 'https://apitest.ahctc.cn', mediahost: 'https://apitest.ahctc.cn', - host: 'http://127.0.0.1:8000', + //host: 'http://127.0.0.1:8000', //mediahost: 'http://127.0.0.1:8000', token : '', rlogin:true diff --git a/test_mini/pages/admin/exam/detail.js b/test_mini/pages/admin/exam/detail.js index e4eb023..3fee37e 100644 --- a/test_mini/pages/admin/exam/detail.js +++ b/test_mini/pages/admin/exam/detail.js @@ -6,7 +6,10 @@ Page({ * 页面的初始数据 */ data: { - exam:{}, + exam:{ + qdimgs:[], + xcimgs:[] + }, tests:[] }, @@ -16,7 +19,7 @@ Page({ onLoad: function (options) { if(options.id){ let id = options.id - that.data.exam.id = id + this.data.exam.id = id api.requesta('/examtest/examtest/', 'GET', {exam:id, pageoff:true}).then(res=>{ this.setData({ tests:res.data @@ -27,11 +30,31 @@ Page({ getExam: function(){ let id = this.data.exam.id api.requesta(`/examtest/exam/${id}/`, 'GET').then(res=>{ + let exam = res.data + for(var i=0;i - - - + + + + + + + + + 签到表图片 + + + + + + + + + + + + + + + + + + + + 现场照片 + + + + + + + + + + + + + + + diff --git a/test_mini/pages/main/main.wxml b/test_mini/pages/main/main.wxml index b80716f..1b2c954 100644 --- a/test_mini/pages/main/main.wxml +++ b/test_mini/pages/main/main.wxml @@ -63,15 +63,6 @@ - - - - - 考核名额监控 - - - - diff --git a/test_mini/pages/my/index.wxml b/test_mini/pages/my/index.wxml index 7659c07..9837a27 100644 --- a/test_mini/pages/my/index.wxml +++ b/test_mini/pages/my/index.wxml @@ -71,6 +71,15 @@ 个人防护用品检测(铅当量) + + + + + 考核名额监控 + + + + 管理员操作台 @@ -79,10 +88,10 @@ - - + diff --git a/test_server/crm/models.py b/test_server/crm/models.py index b712860..66b5e26 100644 --- a/test_server/crm/models.py +++ b/test_server/crm/models.py @@ -105,7 +105,7 @@ class SendCode(CommonModel): code = models.CharField(max_length=4, verbose_name= '验证码') class Candidate(CommonModel): - consumer = models.ForeignKey(Consumer, on_delete=models.CASCADE, related_name='candidate_consumer') + consumer = models.ForeignKey(Consumer, on_delete=models.DO_NOTHING, related_name='candidate_consumer') workscope = models.ForeignKey(WorkScope, on_delete=models.DO_NOTHING, related_name='candidate_workscope') diff --git a/test_server/crm/serializers.py b/test_server/crm/serializers.py index e5be1dd..e9e8a88 100644 --- a/test_server/crm/serializers.py +++ b/test_server/crm/serializers.py @@ -76,6 +76,7 @@ class ConsumerDetailSerializer(serializers.ModelSerializer): class CandidateSerializer(serializers.ModelSerializer): + create_admin_username = serializers.StringRelatedField(source='create_admin', read_only=True) class Meta: model = Candidate fields = '__all__' \ No newline at end of file