diff --git a/test_mini/pages/admin/exam/detail.js b/test_mini/pages/admin/exam/detail.js index 89702dd..912872b 100644 --- a/test_mini/pages/admin/exam/detail.js +++ b/test_mini/pages/admin/exam/detail.js @@ -81,5 +81,26 @@ Page({ */ onShareAppMessage: function () { + }, + issue: function(e){ + let id = e.currentTarget.dataset.id; // 考试id + wx.showLoading({ + title: '证书颁发中...', + }) + api.requesta(`/examtest/examtest/${id}/issue/`, 'POST').then(res=>{ + wx.hideLoading() + let index = e.currentTarget.dataset.index; + this.setData({ + ['tests[' + index + '].candidate_']:res.data + }) + wx.showToast({ + title: '证书颁发成功', + }) + }) + }, + godetail: function(e){ + wx.navigateTo({ + url: '/pages/test/detail?id='+e.currentTarget.dataset.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 e345b57..dc2d019 100644 --- a/test_mini/pages/admin/exam/detail.wxml +++ b/test_mini/pages/admin/exam/detail.wxml @@ -42,10 +42,14 @@ 得分:{{item.score}} + + 证书编号: + {{item.candidate_.number}} + - - - + + + diff --git a/test_mini/project.config.json b/test_mini/project.config.json index bc25de0..c6db745 100644 --- a/test_mini/project.config.json +++ b/test_mini/project.config.json @@ -38,7 +38,7 @@ "minifyWXSS": true }, "compileType": "miniprogram", - "libVersion": "2.16.1", + "libVersion": "2.15.0", "appid": "wxf1e9471c93f05ad6", "projectname": "test_mini", "debugOptions": { diff --git a/test_server/crm/migrations/0031_auto_20210606_0853.py b/test_server/crm/migrations/0031_auto_20210606_0853.py new file mode 100644 index 0000000..4898bd6 --- /dev/null +++ b/test_server/crm/migrations/0031_auto_20210606_0853.py @@ -0,0 +1,73 @@ +# Generated by Django 3.0.4 on 2021-06-06 00:53 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('examtest', '0030_examtest_consumer_detail'), + ('crm', '0030_auto_20210414_2200'), + ] + + operations = [ + migrations.AlterModelOptions( + name='candidate', + options={'verbose_name': '证书', 'verbose_name_plural': '证书'}, + ), + migrations.RemoveField( + model_name='candidate', + name='report_number', + ), + migrations.AddField( + model_name='candidate', + name='ID_number', + field=models.CharField(blank=True, max_length=60, null=True, verbose_name='身份证号'), + ), + migrations.AddField( + model_name='candidate', + name='compnay_name', + field=models.CharField(blank=True, max_length=60, null=True, verbose_name='单位'), + ), + migrations.AddField( + model_name='candidate', + name='consumer_name', + field=models.CharField(blank=True, max_length=60, null=True, verbose_name='姓名'), + ), + migrations.AddField( + model_name='candidate', + name='deptname', + field=models.CharField(blank=True, max_length=60, null=True, verbose_name='部门'), + ), + migrations.AddField( + model_name='candidate', + name='end_date', + field=models.DateField(blank=True, null=True, verbose_name='有效期止'), + ), + migrations.AddField( + model_name='candidate', + name='examtest', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='candidate_examtest', to='examtest.ExamTest', verbose_name='关联考试'), + ), + migrations.AddField( + model_name='candidate', + name='number', + field=models.CharField(blank=True, max_length=60, null=True, verbose_name='报告单号'), + ), + migrations.AddField( + model_name='candidate', + name='start_date', + field=models.DateField(blank=True, null=True, verbose_name='有效期始'), + ), + migrations.AddField( + model_name='candidate', + name='workscope_name', + field=models.CharField(blank=True, max_length=60, null=True, verbose_name='证书工作类别'), + ), + migrations.AlterField( + model_name='candidate', + name='workscope', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='candidate_workscope', to='examtest.WorkScope'), + ), + ] diff --git a/test_server/crm/migrations/0032_auto_20210606_2153.py b/test_server/crm/migrations/0032_auto_20210606_2153.py new file mode 100644 index 0000000..bb8ce47 --- /dev/null +++ b/test_server/crm/migrations/0032_auto_20210606_2153.py @@ -0,0 +1,20 @@ +# Generated by Django 3.0.4 on 2021-06-06 13:53 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('examtest', '0030_examtest_consumer_detail'), + ('crm', '0031_auto_20210606_0853'), + ] + + operations = [ + migrations.AlterField( + model_name='candidate', + name='examtest', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='examtest.ExamTest', verbose_name='关联考试'), + ), + ] diff --git a/test_server/crm/migrations/0033_auto_20210606_2209.py b/test_server/crm/migrations/0033_auto_20210606_2209.py new file mode 100644 index 0000000..088b080 --- /dev/null +++ b/test_server/crm/migrations/0033_auto_20210606_2209.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.4 on 2021-06-06 14:09 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('crm', '0032_auto_20210606_2153'), + ] + + operations = [ + migrations.RenameField( + model_name='candidate', + old_name='compnay_name', + new_name='company_name', + ), + ] diff --git a/test_server/crm/models.py b/test_server/crm/models.py index 29cb903..856d105 100644 --- a/test_server/crm/models.py +++ b/test_server/crm/models.py @@ -114,16 +114,16 @@ class Candidate(CommonModel): workscope_name = models.CharField('证书工作类别', max_length=60, null=True, blank=True) consumer_name = models.CharField('姓名', max_length=60, null=True, blank=True) ID_number = models.CharField('身份证号', max_length=60, null=True, blank=True) - compnay_name = models.CharField('单位', max_length=60, null=True, blank=True) + company_name = models.CharField('单位', max_length=60, null=True, blank=True) deptname = models.CharField('部门', max_length=60, null=True, blank=True) issue_date = models.DateField('发证日期', null=True, blank=True) start_date = models.DateField('有效期始', null=True, blank=True) end_date = models.DateField('有效期止', null=True, blank=True) - examtest = models.OneToOneField(to='examtest.examtest', verbose_name='关联考试', null=True, blank=True, on_delete=models.DO_NOTHING, related_name='candidate_examtest') + examtest = models.OneToOneField(to='examtest.examtest', verbose_name='关联考试', null=True, blank=True, on_delete=models.DO_NOTHING) class Meta: verbose_name = '证书' verbose_name_plural = verbose_name def __str__(self): - return self.number + return self.consumer.username diff --git a/test_server/examtest/serializers.py b/test_server/examtest/serializers.py index 2829ea3..acd7597 100644 --- a/test_server/examtest/serializers.py +++ b/test_server/examtest/serializers.py @@ -222,4 +222,35 @@ class ExamTestDetailSerializer(serializers.ModelSerializer): """ Perform necessary eager loading of data. """ queryset = queryset.select_related('consumer','paper', 'workscope', 'exam') queryset = queryset.prefetch_related('answerdetail_examtest') + return queryset + + + +class ExamTestExamListSerializer(serializers.ModelSerializer): + """ + 正式考试列表序列化 + """ + start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") + end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") + workscope_name = serializers.StringRelatedField(source='workscope', read_only=True) + took_format = serializers.SerializerMethodField() + candidate_ = serializers.SerializerMethodField() + + class Meta: + model = ExamTest + exclude = ('detail',) + + def get_took_format(self, obj): + m, s = divmod(obj.took, 60) + h, m = divmod(m, 60) + return "%02d:%02d:%02d" % (h, m, s) + + def get_candidate_(self, obj): + candidate = obj.candidate if hasattr(obj, 'candidate') else None + if candidate: + return {'id':obj.candidate.id, 'number':obj.candidate.number} + @staticmethod + def setup_eager_loading(queryset): + """ Perform necessary eager loading of data. """ + queryset = queryset.select_related('candidate') return queryset \ No newline at end of file diff --git a/test_server/examtest/views.py b/test_server/examtest/views.py index 0230ec5..0acfcc1 100644 --- a/test_server/examtest/views.py +++ b/test_server/examtest/views.py @@ -27,7 +27,7 @@ from .exports import export_test, exportw_test from .models import AnswerDetail, Banner, ExamTest, Exam from .models_paper import Paper, PaperQuestions, TestRule, WorkScope from .serializers import ( - AnswerDetailCreateSerializer, AnswerDetailSerializer, BannerSerializer, + AnswerDetailCreateSerializer, AnswerDetailSerializer, BannerSerializer, ExamTestExamListSerializer, ExamTestListSerializer, MoniTestSerializer, PaperDetailSerializer, PaperQuestionsCreateSerializer, PaperSerializer, TestRuleSerializer, WorkScopeSerializer, ExamCreateUpdateSerializer, ExamListSerializer, ExamTestDetailSerializer) @@ -383,7 +383,7 @@ class ExamTestViewSet(PageOrNot, ModelViewSet): perms_map = [{'get': 'examtest_view'},{'post': '*'}, {'delete':'examtest_delete'}] pagination_class = CommonPagination queryset = ExamTest.objects.filter(is_delete=0).all() - serializer_class = ExamTestListSerializer + serializer_class = ExamTestExamListSerializer ordering_fields = ('id','create_time','took','score') ordering = ['-create_time'] search_fields = ('consumer__name', 'consumer__company__name') @@ -504,28 +504,30 @@ class ExamTestViewSet(PageOrNot, ModelViewSet): 颁发证书 ''' obj = self.get_object() - try: - candidate = Candidate.objects.get_or_create(examtest=obj) + candidate = obj.candidate if hasattr(obj, 'candidate') else None + # if not obj.is_pass: + # return Response({'error':'考试未通过'}) + if candidate: return Response({'error':'证书已存在'}) - except: - candidates = Candidate.objects.filter(consumer=obj.consumer, workscope=obj.workscope, number__isnull=True) - if candidates.exists(): - candidate = candidates(1) - else: - candidate = Candidate.objects.create(consumer=obj.consumer, workscope=obj.workscope) - count = Candidate.objects.filter(number__isnull=True).count() - candidate.examtest = obj - now = timezone.now() - candidate.issue_date = now - candidate.start_date = now - candidate.end_date = now + timedelta(years=3) - candidate.workscope_name = obj.workscope.name - candidate.consumer_name = obj.consumer_detail.consumer_name - candidate.ID_number = obj.consumer_detail.ID_number - candidate.company_name = obj.consumer_detail.company_name - candidate.deptname = obj.consumer_detail.deptname - candidate.number='SL'+ str(now.year)[-2:] + str(count+1).zfill(6) - return Response() + candidates = Candidate.objects.filter(consumer=obj.consumer, workscope=obj.workscope, number__isnull=True) + if candidates.exists(): + candidate = candidates[0] + else: + candidate = Candidate.objects.create(consumer=obj.consumer, workscope=obj.workscope) + count = Candidate.objects.exclude(number__isnull=True).count() + candidate.examtest = obj + now = timezone.now() + candidate.issue_date = now + candidate.start_date = now + candidate.end_date = now + timedelta(days=3*365) + candidate.workscope_name = obj.workscope.name + candidate.consumer_name = obj.consumer_detail['name'] + candidate.ID_number = obj.consumer_detail['ID_number'] + candidate.company_name = obj.consumer_detail['company_name'] + candidate.deptname = obj.consumer_detail['deptname'] + candidate.number='SL'+ str(now.year)[-2:] + str(count+1).zfill(6) + candidate.save() + return Response({"id":candidate.pk, "number":candidate.number}) class PaperViewSet(ModelViewSet): """ diff --git a/test_server/tmp/~$amtest.docx b/test_server/tmp/~$amtest.docx deleted file mode 100644 index 913aee8..0000000 Binary files a/test_server/tmp/~$amtest.docx and /dev/null differ