feat: 202312版本证书功能

This commit is contained in:
caoqianming 2024-01-02 14:40:24 +08:00
parent 301130d4bf
commit 542a64a52f
3 changed files with 91 additions and 52 deletions

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.12 on 2023-12-28 09:18
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('edu', '0004_auto_20231226_1517'),
]
operations = [
migrations.AddField(
model_name='certificate',
name='培训结束日期',
field=models.DateField(blank=True, null=True),
),
]

View File

@ -2,14 +2,16 @@ from django.db import models
from apps.system.models import CommonADModel, CommonAModel
# Create your models here.
class Course(CommonAModel):
name = models.CharField('课程名', max_length=20)
name = models.CharField("课程名", max_length=20)
class Certificate(CommonADModel):
证书方案 = models.CharField(max_length=20, default='202309')
证书方案 = models.CharField(max_length=20, default="202309")
字体方案 = models.PositiveSmallIntegerField(default=1)
姓名 = models.CharField(max_length=20)
性别 = models.CharField(max_length=10, default='', null=True, blank=True)
性别 = models.CharField(max_length=10, default="", null=True, blank=True)
证书编号 = models.CharField(max_length=20)
所属单位 = models.CharField(max_length=20, null=True, blank=True)
单位名称 = models.CharField(max_length=30, null=True, blank=True)
@ -23,5 +25,6 @@ class Certificate(CommonADModel):
是否需要北京标研培训合格 = models.BooleanField(default=False)
课程列表 = models.ManyToManyField(Course, blank=True)
培训日期 = models.DateField(null=True, blank=True)
培训结束日期 = models.DateField(null=True, blank=True)
发证日期 = models.DateField(null=True, blank=True)
证书地址 = models.CharField(max_length=100, null=True, blank=True)

View File

@ -2,31 +2,30 @@ from PIL import ImageFont, ImageDraw, Image
from django.conf import settings
from apps.edu.models import Certificate
from datetime import date
font_dict = {
'font_1': "/media/cert/template/weibei.ttf",
'font_2': "/media/cert/template/SIMLI.TTF"
}
font_dict = {"font_1": "/media/cert/template/weibei.ttf", "font_2": "/media/cert/template/SIMLI.TTF"}
def make_img_x(instance: Certificate):
if instance.证书方案 == '202309':
if instance.证书方案 == "202309":
titles = []
if instance.是否内审员:
titles.append('内审员')
titles.append("内审员")
if instance.是否授权签字人:
titles.append('授权签字人')
titles.append("授权签字人")
if instance.是否质量负责人:
titles.append('质量负责人')
titles.append("质量负责人")
if instance.是否最高管理者:
titles.append('最高管理者')
instance.证书地址 = make_img(instance.证书编号, instance.姓名, ''.join(titles), font_dict[f'font_{instance.字体方案}'])
titles.append("最高管理者")
instance.证书地址 = make_img(instance.证书编号, instance.姓名, "".join(titles), font_dict[f"font_{instance.字体方案}"])
instance.save()
elif instance.证书方案 == '202312':
elif instance.证书方案 == "202312":
courses_list = [i.name for i in instance.课程列表.all()]
courses = ''.join(courses_list) + ''
instance.证书地址 = make_img_2(instance.证书编号, instance.姓名, instance.培训日期, instance.发证日期, courses, font_dict[f'font_{instance.字体方案}'])
courses = "".join(courses_list) + ""
instance.证书地址 = make_img_2(instance.证书编号, instance.姓名, instance.培训日期, instance.培训结束日期, instance.发证日期, courses, font_dict[f"font_{instance.字体方案}"])
instance.save()
def text_wrap(draw, text, font, max_width):
lines = []
@ -34,65 +33,84 @@ def text_wrap(draw, text, font, max_width):
words = list(text)
# 尝试将单词拼成一行,使其宽度不要超过最大宽度
while words:
line = ''
line = ""
# 当加上一个新单词不会让行宽超出最大宽度时就加上它
while words and draw.textlength(line + words[0], font=font) <= max_width:
line += words.pop(0)
lines.append(line.strip()) # 移除多余的空格
return lines
def make_img_2(number, name, att_date: date, issue_date: date, courses, font_name_path):
def make_img_2(number, name, att_date: date, att_date2: date, issue_date: date, courses, font_name_path):
# 打开底版图片
imageFile = settings.BASE_DIR + '/media/cert/template/background2.jpg'
imageFile = settings.BASE_DIR + "/media/cert/template/background2.jpg"
img = Image.open(imageFile)
# 选择字体与大小
font = ImageFont.truetype(settings.BASE_DIR+ font_name_path, 155)
font_courses = ImageFont.truetype(settings.BASE_DIR + "/media/cert/template/simkai.ttf", 100)
font_number = ImageFont.truetype(settings.BASE_DIR + "/media/cert/template/timesbd.ttf", 58)
font_day = ImageFont.truetype(settings.BASE_DIR + "/media/cert/template/Dengl.ttf", 68)
font = ImageFont.truetype(settings.BASE_DIR + font_name_path, 140)
font_courses = ImageFont.truetype(settings.BASE_DIR + "/media/cert/template/simkai.ttf", 90)
font_number = ImageFont.truetype(settings.BASE_DIR + "/media/cert/template/timesbd.ttf", 58)
font_day = ImageFont.truetype(settings.BASE_DIR + "/media/cert/template/siyuan.otf", 68)
font_day2 = ImageFont.truetype(settings.BASE_DIR + "/media/cert/template/siyuan.otf", 58)
position_number = (1730, 606)
position_name = (720, 840)
position_courses = (490, 1070)
position_a_y = (1530, 900)
position_a_m = (1870, 900)
position_a_d = (2170, 900)
position_i_y = (2010, 1910)
position_i_m = (2254, 1910)
position_i_d = (2446, 1910)
if len(name) <= 3:
position_name = (740, 840)
else:
position_name = (580, 840)
position_courses = (500, 1070)
position_note = (1990, 1600)
att_date_str = att_date.strftime("%Y年%m月%d")
issue_date_str = issue_date.strftime("%Y年%m月%d")
if att_date == att_date2:
date_str = f"同志于{att_date_str}参加了以下培训课程:"
else:
att_date2_str = att_date2.strftime("%Y年%m月%d")
date_str = f"同志于{att_date_str}-{att_date2_str}参加了以下培训课程:"
position_date = (1170, 900)
position_issue_date = (1990, 1910)
# position_a_y = (1530, 900)
# position_a_m = (1870, 900)
# position_a_d = (2170, 900)
# position_i_y = (2010, 1910)
# position_i_m = (2254, 1910)
# position_i_d = (2446, 1910)
color_name = (82, 68, 19)
color = (0,0,0)
color = (0, 0, 0)
draw = ImageDraw.Draw(img)
draw.text(position_name, name, color_name, font=font)
max_width = 2800 # 根据实际证书的内容区域来设置最大宽度
max_width = 2600 # 根据实际证书的内容区域来设置最大宽度
wrapped_courses = text_wrap(draw, courses, font_courses, max_width)
y_offset = 0
for line in wrapped_courses:
draw.text((position_courses[0], position_courses[1] + y_offset), line, (0,0,0), font=font_courses)
draw.text((position_courses[0], position_courses[1] + y_offset), line, (0, 0, 0), font=font_courses)
y_offset = y_offset + 180
draw.text(position_number, number, color_name, font=font_number)
draw.text(position_a_y, str(att_date.year), color, font=font_day)
draw.text(position_a_m, str(att_date.month), color, font=font_day)
draw.text(position_a_d, str(att_date.day), color, font=font_day)
draw.text(position_i_y, str(issue_date.year), color, font=font_day)
draw.text(position_i_m, str(issue_date.month), color, font=font_day)
draw.text(position_i_d, str(issue_date.day), color, font=font_day)
draw.text(position_date, date_str, color, font=font_day)
draw.text(position_note, "经考试成绩合格,特发此证。", color, font=font_day)
# draw.text(position_a_m, str(att_date.month), color, font=font_day)
# draw.text(position_a_d, str(att_date.day), color, font=font_day)
draw.text(position_issue_date, issue_date_str, color, font=font_day2)
# draw.text(position_i_y, str(issue_date.year), color, font=font_day)
# draw.text(position_i_m, str(issue_date.month), color, font=font_day)
# draw.text(position_i_d, str(issue_date.day), color, font=font_day)
# 保存图片
path = f"/media/cert/{number}.jpg"
img.save(settings.BASE_DIR + path)
img.save(settings.BASE_DIR + path)
return path
def make_img(number, name, title, font_name_path):
# 打开底版图片
imageFile = settings.BASE_DIR + '/media/cert/template/background.jpg'
imageFile = settings.BASE_DIR + "/media/cert/template/background.jpg"
img = Image.open(imageFile)
# 选择字体与大小
font = ImageFont.truetype(settings.BASE_DIR+ font_name_path, 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)
font = ImageFont.truetype(settings.BASE_DIR + font_name_path, 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 = """
# word = """
# 夜 归 小 朝
# 梦 鸟 舟 有 静
# 星 清 载 赤 安
@ -103,9 +121,9 @@ def make_img(number, name, title, font_name_path):
# ldc 2020-07-25
# """
word_number = number #"CTCZL20230001"
word_name = name #"曹前明"
word_title = title #"内审员、授权签字人、质量负责人、最高管理者"
word_number = number # "CTCZL20230001"
word_name = name # "曹前明"
word_title = title # "内审员、授权签字人、质量负责人、最高管理者"
# width = img.width
# height = img.height
# # 查看图片宽高
@ -114,12 +132,12 @@ def make_img(number, name, title, font_name_path):
position_name = (628, 860)
position_title = (900, 1230)
color_name = (82, 68, 19)
color = (0,0,0)
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
img.save(settings.BASE_DIR + path)
return path