feat: 更新证书查询创建图片后端
This commit is contained in:
		
							parent
							
								
									adeb7256dc
								
							
						
					
					
						commit
						5e747884dc
					
				| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
from django.contrib import admin
 | 
			
		||||
 | 
			
		||||
# Register your models here.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
from django.apps import AppConfig
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EduConfig(AppConfig):
 | 
			
		||||
    default_auto_field = 'django.db.models.BigAutoField'
 | 
			
		||||
    name = 'apps.edu'
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
# Generated by Django 3.2.12 on 2023-08-23 06:57
 | 
			
		||||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
import django.utils.timezone
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Certificate',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
 | 
			
		||||
                ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
 | 
			
		||||
                ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
 | 
			
		||||
                ('姓名', models.CharField(max_length=20)),
 | 
			
		||||
                ('性别', models.CharField(default='男', max_length=10)),
 | 
			
		||||
                ('证书编号', models.CharField(max_length=20)),
 | 
			
		||||
                ('所属单位', models.CharField(max_length=20)),
 | 
			
		||||
                ('单位名称', models.CharField(max_length=30)),
 | 
			
		||||
                ('职务', models.CharField(max_length=20)),
 | 
			
		||||
                ('手机号', models.CharField(max_length=11)),
 | 
			
		||||
                ('是否内审员', models.BooleanField(default=False)),
 | 
			
		||||
                ('是否授权签字人', models.BooleanField(default=False)),
 | 
			
		||||
                ('是否质量负责人', models.BooleanField(default=False)),
 | 
			
		||||
                ('是否最高管理者', models.BooleanField(default=False)),
 | 
			
		||||
                ('是否需要集团证书', models.BooleanField(default=False)),
 | 
			
		||||
                ('是否需要北京标研培训合格', models.BooleanField(default=False)),
 | 
			
		||||
                ('证书地址', models.CharField(blank=True, max_length=100, null=True)),
 | 
			
		||||
                ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='certificate_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
 | 
			
		||||
                ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='certificate_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                'abstract': False,
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
# Generated by Django 3.2.12 on 2023-08-23 07:29
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('edu', '0001_initial'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name='certificate',
 | 
			
		||||
            name='性别',
 | 
			
		||||
            field=models.CharField(blank=True, default='男', max_length=10, null=True),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name='certificate',
 | 
			
		||||
            name='手机号',
 | 
			
		||||
            field=models.CharField(blank=True, max_length=11, null=True),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name='certificate',
 | 
			
		||||
            name='职务',
 | 
			
		||||
            field=models.CharField(blank=True, max_length=20, null=True),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
from django.db import models
 | 
			
		||||
from apps.system.models import CommonADModel
 | 
			
		||||
# Create your models here.
 | 
			
		||||
 | 
			
		||||
class Certificate(CommonADModel):
 | 
			
		||||
    姓名 = models.CharField(max_length=20)
 | 
			
		||||
    性别 = models.CharField(max_length=10, default='男', null=True, blank=True)
 | 
			
		||||
    证书编号 = models.CharField(max_length=20)
 | 
			
		||||
    所属单位 = models.CharField(max_length=20)
 | 
			
		||||
    单位名称 = models.CharField(max_length=30)
 | 
			
		||||
    职务 = models.CharField(max_length=20, null=True, blank=True)
 | 
			
		||||
    手机号 = models.CharField(max_length=11, null=True, blank=True)
 | 
			
		||||
    是否内审员 = models.BooleanField(default=False)
 | 
			
		||||
    是否授权签字人 = models.BooleanField(default=False)
 | 
			
		||||
    是否质量负责人 = models.BooleanField(default=False)
 | 
			
		||||
    是否最高管理者 = models.BooleanField(default=False)
 | 
			
		||||
    是否需要集团证书 = models.BooleanField(default=False)
 | 
			
		||||
    是否需要北京标研培训合格 = models.BooleanField(default=False)
 | 
			
		||||
    证书地址 = models.CharField(max_length=100, null=True, blank=True)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
from rest_framework import serializers
 | 
			
		||||
from apps.edu.models import Certificate
 | 
			
		||||
 | 
			
		||||
class CertificateSerializer(serializers.ModelSerializer):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = Certificate
 | 
			
		||||
        fields = '__all__'
 | 
			
		||||
        read_only_fields = ['create_time', 'update_time', 'create_by', 'update_by', 'is_deleted']
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
from PIL import ImageFont, ImageDraw, Image
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
 | 
			
		||||
def make_img(number, name, title):
 | 
			
		||||
    # 打开底版图片
 | 
			
		||||
    imageFile =  settings.BASE_DIR +   '/media/cert/template/background.jpg'
 | 
			
		||||
    img = Image.open(imageFile)
 | 
			
		||||
    # 选择字体与大小
 | 
			
		||||
    font = ImageFont.truetype(settings.BASE_DIR+ "/media/cert/template/weibei.ttf", 155)
 | 
			
		||||
    font_title = ImageFont.truetype(settings.BASE_DIR +   "/media/cert/template/siyuan.otf", 76)
 | 
			
		||||
    font_number = ImageFont.truetype(settings.BASE_DIR +   "/media/cert/template/timesbd.ttf", 58)
 | 
			
		||||
    # print(font)
 | 
			
		||||
    # 在图片上添加文字
 | 
			
		||||
    # word = """     
 | 
			
		||||
    # 夜  归  小  朝
 | 
			
		||||
    # 梦  鸟  舟  有  静
 | 
			
		||||
    # 星  清  载  赤  安
 | 
			
		||||
    # 河  风  我  羽  心
 | 
			
		||||
    # 一  同  湖  暮  野
 | 
			
		||||
    # 壶  桨  旋  落
 | 
			
		||||
    # 茶  驻  停  霞
 | 
			
		||||
 | 
			
		||||
    # ldc 2020-07-25
 | 
			
		||||
    # """
 | 
			
		||||
    word_number = number #"CTCZL20230001"
 | 
			
		||||
    word_name = name #"曹前明"
 | 
			
		||||
    word_title = title #"内审员、授权签字人、质量负责人、最高管理者"
 | 
			
		||||
    # width = img.width
 | 
			
		||||
    # height = img.height
 | 
			
		||||
    # # 查看图片宽高
 | 
			
		||||
    # print(width,height)
 | 
			
		||||
    position_number = (1772, 645)
 | 
			
		||||
    position_name = (628, 860)
 | 
			
		||||
    position_title = (900, 1230)
 | 
			
		||||
    color_name = (82, 68, 19)
 | 
			
		||||
    color = (0,0,0)
 | 
			
		||||
    draw = ImageDraw.Draw(img)
 | 
			
		||||
    draw.text(position_name, word_name, color_name, font=font)
 | 
			
		||||
    draw.text(position_title, word_title, color, font=font_title)
 | 
			
		||||
    draw.text(position_number, word_number, color_name, font=font_number)
 | 
			
		||||
    # 保存图片
 | 
			
		||||
    path = f"/media/cert/{number}.jpg"
 | 
			
		||||
    img.save(settings.BASE_DIR +   path)
 | 
			
		||||
    return path
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
from django.test import TestCase
 | 
			
		||||
 | 
			
		||||
# Create your tests here.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
from django.urls import path, include
 | 
			
		||||
from rest_framework import routers
 | 
			
		||||
from apps.edu.views import CertificateViewSet
 | 
			
		||||
 | 
			
		||||
API_BASE_URL = 'api/edu/'
 | 
			
		||||
HTML_BASE_URL = 'edu/'
 | 
			
		||||
router = routers.DefaultRouter()
 | 
			
		||||
router.register('certificate', CertificateViewSet, basename="certificate")
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path(API_BASE_URL, include(router.urls))
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,83 @@
 | 
			
		|||
from django.shortcuts import render
 | 
			
		||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
 | 
			
		||||
from apps.system.mixins import CreateUpdateCustomMixin
 | 
			
		||||
from apps.edu.serializers import CertificateSerializer
 | 
			
		||||
from apps.edu.models import Certificate
 | 
			
		||||
from rest_framework.decorators import action
 | 
			
		||||
from django.db import transaction
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from rest_framework.exceptions import ParseError
 | 
			
		||||
from rest_framework.response import Response
 | 
			
		||||
from openpyxl import load_workbook
 | 
			
		||||
from apps.edu.services import make_img
 | 
			
		||||
from rest_framework.serializers import Serializer
 | 
			
		||||
from django.db import transaction
 | 
			
		||||
# Create your views here.
 | 
			
		||||
 | 
			
		||||
class CertificateViewSet(CreateUpdateCustomMixin, ModelViewSet):
 | 
			
		||||
    perms_map = {'get': '*', 'post': 'certificate',
 | 
			
		||||
                 'put': 'certificate', 'delete': 'certificate'}
 | 
			
		||||
    queryset = Certificate.objects.all()
 | 
			
		||||
    serializer_class = CertificateSerializer
 | 
			
		||||
    pagination_class = None
 | 
			
		||||
    search_fields = ['姓名', '证书编号', '所属单位']
 | 
			
		||||
    filterset_fields = ['是否内审员','是否授权签字人', '是否质量负责人', '是否最高管理者']
 | 
			
		||||
    ordering = ['-create_time']
 | 
			
		||||
 | 
			
		||||
    def retrieve(self, request, *args, **kwargs):
 | 
			
		||||
        regen_img = request.query_params.get('regen_img', False)
 | 
			
		||||
        instance = self.get_object()
 | 
			
		||||
        if instance.证书地址 is None or regen_img:
 | 
			
		||||
            titles = []
 | 
			
		||||
            if instance.是否内审员:
 | 
			
		||||
                titles.append('内审员')
 | 
			
		||||
            elif instance.是否授权签字人:
 | 
			
		||||
                titles.append('授权签字人')
 | 
			
		||||
            elif instance.是否质量负责人:
 | 
			
		||||
                titles.append('质量负责人')
 | 
			
		||||
            elif instance.是否最高管理者:
 | 
			
		||||
                titles.append('最高管理者')
 | 
			
		||||
            instance.证书地址 = make_img(instance.证书编号, instance.姓名, '、'.join(titles))
 | 
			
		||||
            instance.save()
 | 
			
		||||
        serializer = self.get_serializer(instance)
 | 
			
		||||
        return Response(serializer.data)
 | 
			
		||||
    
 | 
			
		||||
    def make_data(self, data, sheet, i):
 | 
			
		||||
        data['证书编号'] = sheet['b'+str(i)].value
 | 
			
		||||
        data['所属单位'] = sheet['c'+str(i)].value
 | 
			
		||||
        data['单位名称'] = sheet['d'+str(i)].value
 | 
			
		||||
        data['姓名'] = sheet['e'+str(i)].value
 | 
			
		||||
        data['性别'] = sheet['f'+str(i)].value
 | 
			
		||||
        data['职务'] = sheet['g'+str(i)].value
 | 
			
		||||
        data['手机号'] = sheet['h'+str(i)].value
 | 
			
		||||
        data['是否内审员'] = True if sheet['i'+str(i)].value else False
 | 
			
		||||
        data['是否授权签字人'] = True if sheet['j'+str(i)].value else False
 | 
			
		||||
        data['是否质量负责人'] = True if sheet['k'+str(i)].value else False
 | 
			
		||||
        data['是否最高管理者'] = True if sheet['l'+str(i)].value else False
 | 
			
		||||
        data['是否需要集团证书'] = True if sheet['m'+str(i)].value else False
 | 
			
		||||
        data['是否需要北京标研培训合格'] = True if sheet['n'+str(i)].value else False
 | 
			
		||||
        return data
 | 
			
		||||
 | 
			
		||||
    @action(methods=['post'], detail=False, perms_map = {'post':'certificate'}, serializer_class=Serializer)
 | 
			
		||||
    def imp(self, request, *args, **kwargs):
 | 
			
		||||
        """导入表格
 | 
			
		||||
 | 
			
		||||
        导入表格
 | 
			
		||||
        """
 | 
			
		||||
        path = request.data.get('path', '')
 | 
			
		||||
        full_path = settings.BASE_DIR + path
 | 
			
		||||
        if not path.endswith('.xlsx'):
 | 
			
		||||
            raise ParseError('请提供xlsx格式文件')
 | 
			
		||||
        wb = load_workbook(full_path, data_only=True)
 | 
			
		||||
        sheet = wb.worksheets[0]
 | 
			
		||||
        i = 3
 | 
			
		||||
        while sheet['b'+str(i)].value:
 | 
			
		||||
            data = {}
 | 
			
		||||
            data = self.make_data(data, sheet, i)
 | 
			
		||||
            obj, created = Certificate.objects.update_or_create(defaults=data, 证书编号=data['证书编号'])
 | 
			
		||||
            if created:
 | 
			
		||||
                print(f'已创建证书-{data["姓名"]}-{data["证书编号"]}')
 | 
			
		||||
            else:
 | 
			
		||||
                print(f'已更新证书-{data["姓名"]}-{data["证书编号"]}')
 | 
			
		||||
            i = i + 1
 | 
			
		||||
        return Response()
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +50,8 @@ INSTALLED_APPS = [
 | 
			
		|||
    'apps.vod',
 | 
			
		||||
    'apps.consulting',
 | 
			
		||||
    'apps.exam',
 | 
			
		||||
    'apps.ops'
 | 
			
		||||
    'apps.ops',
 | 
			
		||||
    'apps.edu'
 | 
			
		||||
     
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,6 +62,7 @@ urlpatterns = [
 | 
			
		|||
    path('api/consulting/', include('apps.consulting.urls')),
 | 
			
		||||
    path('', include('apps.ops.urls')),
 | 
			
		||||
    path('', include('apps.exam.urls')),
 | 
			
		||||
    path('', include('apps.edu.urls')),
 | 
			
		||||
    
 | 
			
		||||
    path('api/docs/', include_docs_urls(title="接口文档",authentication_classes=[], permission_classes=[])),
 | 
			
		||||
    url(r'^api/swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue