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 3b5afdc..bf26603 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 @@
+
+
+
+
+ 刷新重置
+
+
+
+
+ {{ scope.row.number }}
+
+
+ {{ scope.row.consumer_name }}
+
+
+ {{ scope.row.ID_number }}
+
+
+ {{ scope.row.workscope_name }}
+
+
+ {{ scope.row.company_name }}
+
+
+ {{ scope.row.start_date }}
+
+
+ {{ scope.row.end_date }}
+
+
+
+ {{ scope.row.create_admin_username }}
+
+
+
+
+ 查看证书
+
+
+
+
+
+
+
+
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..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,11 +19,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
- })
- })
+ this.data.exam.id = id
api.requesta('/examtest/examtest/', 'GET', {exam:id, pageoff:true}).then(res=>{
this.setData({
tests:res.data
@@ -28,6 +27,34 @@ 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
-
-
-
- {{exam.name}}
-
-
+
+
+
+ {{exam.name}}
+
+
工作类别:{{exam.workscope_name}}
-
+
考试地点:{{exam.place}}
-
+
开关时间:{{exam.opentime}}-{{exam.closetime}}
监考人:{{exam.proctor_name}}-{{exam.proctor_phone}}
+
+
+
+
+
+
+
+
+ 签到表图片
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 现场照片
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- 共{{tests.length}}次考试记录
-
-
-
- 到底了
-
-
-
\ 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/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_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/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 4d345cb..f2f55cb 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__'
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):
"""