feat: 自动发证功能

This commit is contained in:
caoqianming 2024-04-10 22:08:48 +08:00
parent a01e339dde
commit 14340fe0c6
5 changed files with 86 additions and 47 deletions

View File

@ -159,6 +159,20 @@
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="自动发证" prop="auto_issue">
<el-switch v-model="exam.auto_issue"></el-switch>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="证书模板">
<el-select v-model="exam.cert_template" placeholder="证书模板" clearable>
<el-option v-for="item in certTemplateOptions" :key="item.value">{{ item.label }}</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-divider></el-divider>
<el-row>
@ -180,7 +194,9 @@
<el-form-item label="培训名称" prop="train_name">
<el-input v-model="exam.train_name" placeholder="培训名称" />
</el-form-item>
<el-form-item label="培训开始" prop="train_start_date">
<el-row>
<el-col :span="12">
<el-form-item label="培训开始" prop="train_start_date">
<el-date-picker
v-model="exam.train_start_date"
type="date"
@ -189,7 +205,9 @@
style="width:100%">
</el-date-picker>
</el-form-item>
<el-form-item label="培训结束" prop="train_end_date">
</el-col>
<el-col :span="12">
<el-form-item label="培训结束" prop="train_end_date">
<el-date-picker
v-model="exam.train_end_date"
type="date"
@ -198,6 +216,10 @@
style="width:100%"
></el-date-picker>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogVisible=false">取消</el-button>
@ -224,6 +246,7 @@ const defaultexam = {
closetime: null,
chance:3,
only_vip:false,
cert_template:null,
auto_issue:false
};
const listQuery = {
@ -240,6 +263,10 @@ export default {
id: "",
name: "",
},
certTemplateOptions:[
{value: 1, label: "模板1"},
{value: 2, label: "模板2"}
],
listQuery:listQuery,
tableData: {count:0},
listLoading: true,

View File

@ -12,7 +12,7 @@
<!-- <img class="logo" src="../../assets/logo.png" /> -->
</div>
<div class="title-container">
<h3 class="title">小程序后台管理</h3>
<h3 class="title">中科辐射小程序后台管理</h3>
</div>
<el-form-item prop="username">
<span class="svg-container">

View File

@ -701,10 +701,12 @@ def candidate(request):
if request.GET.get('id', None):
try:
candidate = Candidate.objects.get(id=request.GET.get('id'), number__isnull=False)
examtest = candidate.examtest
candidate.msg = get_msg_from_id(candidate.ID_number)
candidate.exam_year = candidate.examtest_date.year
candidate.exam_month = candidate.examtest_date.month
if candidate.workscope and candidate.workscope.name in ['放射工作人员(上岗)', '放射工作人员(在岗)']:
# if candidate.workscope and candidate.workscope.name in ['放射工作人员(上岗)', '放射工作人员(在岗)']:
if examtest and examtest.exam.cert_template==2:
candidate.date1 = candidate.train_start_date.strftime("%Y年%m月%d")
candidate.date2 = candidate.train_end_date.strftime("%Y年%m月%d")
candidate.date3 = candidate.issue_date.strftime("%Y年%m月%d")

View File

@ -0,0 +1,42 @@
from .models import ExamTest
from crm.models import Candidate
from django.utils import timezone
from datetime import timedelta
from rest_framework.exceptions import ParseError
from rbac.models import UserProfile
def issue(obj: ExamTest, create_admin: UserProfile = None):
if create_admin is None:
create_admin = obj.exam.create_admin
workscope = obj.workscope
candidate = obj.candidate if hasattr(obj, 'candidate') else None
if obj.is_pass and candidate is None:
candidates = Candidate.objects.filter(consumer=obj.consumer, workscope=workscope, number__isnull=True)
if candidates.exists():
candidate = candidates[0]
else:
candidate = Candidate.objects.create(consumer=obj.consumer, workscope=workscope)
candidate.examtest = obj
now = timezone.now()
candidate.issue_date = now
candidate.start_date = now
candidate.end_date = now + timedelta(days=workscope.issue_year*365) # 有效期
candidate.examtest_date = obj.start_time.date()
candidate.workscope_name = 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.train_name = obj.exam.train_name
candidate.train_start_date = obj.exam.train_start_date
candidate.train_end_date = obj.exam.train_end_date
candidate.save()
cert_template = obj.exam.cert_template
# if cert_template == 2 or (cert_template is None and workscope.name in ['放射工作人员(上岗)', '放射工作人员(在岗)']): # 如果是放射工作人员处理方式
if cert_template == 2:
count = Candidate.objects.filter(create_admin=create_admin, issue_date__year=now.year, issue_date__month=now.month).count()
candidate.number='HNHK'+ str(now.year) + str(now.month).zfill(2) + str(count+1).zfill(4)
else:
candidate.number='SL'+ str(now.year)[-2:] + str(candidate.pk).zfill(6)
candidate.create_admin = create_admin
candidate.save()
return {"id":candidate.pk, "number":candidate.number, "path":None}

View File

@ -37,6 +37,8 @@ from utils.pagination import PageOrNot
from rest_framework.exceptions import ParseError
from django.db import transaction
from examtest.exports import gen_candidate
from .services import issue
from django.db import transaction
# Create your views here.
class ExamViewSet(ModelViewSet):
@ -546,6 +548,7 @@ class ExamTestViewSet(PageOrNot, ModelViewSet):
ret['pass_rate'] = round(((queryset.filter(is_pass=True).count())/ret['total'])*100) if ret['total'] else 0
return Response(ret)
@transaction.atomic
def create(self, request, *args, **kwargs):
serializer = MoniTestSerializer(data = request.data)
if serializer.is_valid():
@ -566,8 +569,12 @@ class ExamTestViewSet(PageOrNot, ModelViewSet):
serializer_detail.save()
# 关联正式考试如有
if request.data.get('exam', None):
instance.exam = Exam.objects.get(pk=request.data['exam'])
exam = Exam.objects.get(pk=request.data['exam'])
instance.exam = exam
instance.save()
# 自动发证
if exam.auto_issue and instance.is_pass:
issue(instance)
return Response(MoniTestSerializer(instance).data,status=status.HTTP_200_OK)
else:
return Response(serializer_detail.errors)
@ -604,48 +611,9 @@ class ExamTestViewSet(PageOrNot, ModelViewSet):
'''
颁发证书
'''
obj = self.get_object()
workscope = obj.workscope
candidate = obj.candidate if hasattr(obj, 'candidate') else None
if not obj.is_pass:
return Response({'error':'考试未通过'})
if candidate:
return Response({'error':'证书已存在'})
candidates = Candidate.objects.filter(consumer=obj.consumer, workscope=workscope, number__isnull=True)
if candidates.exists():
candidate = candidates[0]
else:
candidate = Candidate.objects.create(consumer=obj.consumer, workscope=workscope)
candidate.examtest = obj
now = timezone.now()
candidate.issue_date = now
candidate.start_date = now
candidate.end_date = now + timedelta(days=workscope.issue_year*365) # 有效期
candidate.examtest_date = obj.start_time.date()
candidate.workscope_name = 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.train_name = obj.exam.train_name
candidate.train_start_date = obj.exam.train_start_date
candidate.train_end_date = obj.exam.train_end_date
candidate.save()
if workscope.name in ['放射工作人员(上岗)', '放射工作人员(在岗)']: # 如果是放射工作人员处理方式
count = Candidate.objects.filter(create_admin=request.user, issue_date__year=now.year, issue_date__month=now.month).count()
candidate.number='HNHK'+ str(now.year) + str(now.month).zfill(2) + str(count+1).zfill(4)
else:
candidate.number='SL'+ str(now.year)[-2:] + str(candidate.pk).zfill(6)
candidate.create_admin = request.user
candidate.save()
path = None
# 生成word证书
# path = None
# if workscope.name in ['放射工作人员(上岗)', '放射工作人员(在岗)']: # 如果是放射工作人员处理方式
# path = gen_candidate(candidate)
# candidate.path = path
# candidate.save()
return Response({"id":candidate.pk, "number":candidate.number, "path":path})
obj: ExamTest = self.get_object()
res_dict = issue(obj, request.user)
return Response(res_dict)
class PaperViewSet(PageOrNot, ModelViewSet):