mirror of
https://github.com/zhtyyx/ioe.git
synced 2026-06-03 21:02:59 +08:00
181 lines
6.1 KiB
Python
181 lines
6.1 KiB
Python
"""
|
||
条码生成工具函数 - 不依赖于barcode库的替代实现
|
||
"""
|
||
import io
|
||
import os
|
||
import uuid
|
||
from PIL import Image, ImageDraw, ImageFont
|
||
import qrcode
|
||
from decimal import Decimal
|
||
|
||
|
||
def draw_code128_barcode(text, height=100, thickness=3, quiet_zone=10):
|
||
"""
|
||
绘制Code 128条码的简单实现
|
||
|
||
参数:
|
||
text: 条码文本
|
||
height: 条码高度
|
||
thickness: 条码线条粗细
|
||
quiet_zone: 条码两侧的空白区域
|
||
|
||
返回:
|
||
PIL.Image: 条码图片
|
||
"""
|
||
# 由于没有barcode库,我们用黑色矩形模拟条码图案
|
||
# 实际项目中应使用专业库或在这里实现完整的Code 128编码算法
|
||
|
||
# 创建一个白色图片
|
||
width = len(text) * 10 * thickness + 2 * quiet_zone
|
||
img = Image.new('RGB', (width, height), color='white')
|
||
draw = ImageDraw.Draw(img)
|
||
|
||
# 在空白区域中间处绘制交替的黑条
|
||
x = quiet_zone
|
||
for char in text:
|
||
# 根据字符ASCII值计算条码宽度(模拟)
|
||
stripe_width = (ord(char) % 3 + 1) * thickness
|
||
|
||
# 绘制黑条
|
||
draw.rectangle([(x, 0), (x + stripe_width, height)], fill='black')
|
||
x += stripe_width + thickness # 条之间的空白
|
||
|
||
# 尝试加载字体
|
||
try:
|
||
font_path = os.path.join('static', 'fonts', 'msyh.ttf')
|
||
font = ImageFont.truetype(font_path, 12)
|
||
except IOError:
|
||
font = ImageFont.load_default()
|
||
|
||
# 在条码下方显示文本
|
||
text_width = draw.textlength(text, font=font)
|
||
draw.text(((width - text_width) / 2, height - 15), text, fill='black', font=font)
|
||
|
||
return img
|
||
|
||
|
||
def generate_product_barcode_alt(product, price=None):
|
||
"""
|
||
生成商品条码图片 (替代实现)
|
||
|
||
参数:
|
||
product: 商品对象
|
||
price: 显示的价格
|
||
|
||
返回:
|
||
PIL.Image: 条码图片对象
|
||
"""
|
||
if not price:
|
||
price = product.retail_price
|
||
|
||
# 获取条码内容
|
||
barcode_content = product.barcode
|
||
if not barcode_content:
|
||
# 如果商品没有条码,使用商品ID作为条码
|
||
barcode_content = f"ID{product.id:08d}"
|
||
|
||
try:
|
||
# 生成条码
|
||
barcode_img = draw_code128_barcode(barcode_content, height=80)
|
||
|
||
# 创建包含商品信息的完整图片
|
||
width, height = barcode_img.size
|
||
new_height = height + 100 # 添加额外空间用于显示商品信息
|
||
|
||
# 创建新图片
|
||
complete_img = Image.new('RGB', (width, new_height), color='white')
|
||
complete_img.paste(barcode_img, (0, 0))
|
||
|
||
# 添加商品信息
|
||
draw = ImageDraw.Draw(complete_img)
|
||
|
||
# 尝试加载字体
|
||
try:
|
||
font_path = os.path.join('static', 'fonts', 'msyh.ttf')
|
||
title_font = ImageFont.truetype(font_path, 20)
|
||
info_font = ImageFont.truetype(font_path, 16)
|
||
except IOError:
|
||
# 使用默认字体
|
||
title_font = ImageFont.load_default()
|
||
info_font = ImageFont.load_default()
|
||
|
||
# 绘制商品名称
|
||
product_name = product.name
|
||
if len(product_name) > 20:
|
||
product_name = product_name[:18] + '...'
|
||
|
||
# 绘制信息
|
||
draw.text((10, height + 10), product_name, fill='black', font=title_font)
|
||
draw.text((10, height + 40), f"价格: ¥{price:.2f}", fill='black', font=info_font)
|
||
draw.text((10, height + 70), f"规格: {product.specification or '标准'}", fill='black', font=info_font)
|
||
|
||
return complete_img
|
||
|
||
except Exception as e:
|
||
# 生成错误时的默认图片
|
||
error_img = Image.new('RGB', (300, 150), color='white')
|
||
draw = ImageDraw.Draw(error_img)
|
||
draw.text((10, 10), f"条码生成错误: {str(e)}", fill='black')
|
||
draw.text((10, 30), f"商品: {product.name}", fill='black')
|
||
draw.text((10, 50), f"条码: {barcode_content}", fill='black')
|
||
return error_img
|
||
|
||
|
||
def generate_batch_barcode_alt(batch):
|
||
"""
|
||
生成批次条码图片 (替代实现)
|
||
|
||
参数:
|
||
batch: 批次对象
|
||
|
||
返回:
|
||
PIL.Image: 条码图片对象
|
||
"""
|
||
# 生成批次编号条码
|
||
batch_code = f"B{batch.id:06d}"
|
||
|
||
try:
|
||
# 生成条码
|
||
barcode_img = draw_code128_barcode(batch_code, height=80)
|
||
|
||
# 创建包含批次信息的完整图片
|
||
width, height = barcode_img.size
|
||
new_height = height + 100 # 添加额外空间用于显示批次信息
|
||
|
||
# 创建新图片
|
||
complete_img = Image.new('RGB', (width, new_height), color='white')
|
||
complete_img.paste(barcode_img, (0, 0))
|
||
|
||
# 添加批次信息
|
||
draw = ImageDraw.Draw(complete_img)
|
||
|
||
# 尝试加载字体
|
||
try:
|
||
font_path = os.path.join('static', 'fonts', 'msyh.ttf')
|
||
title_font = ImageFont.truetype(font_path, 20)
|
||
info_font = ImageFont.truetype(font_path, 16)
|
||
except IOError:
|
||
# 使用默认字体
|
||
title_font = ImageFont.load_default()
|
||
info_font = ImageFont.load_default()
|
||
|
||
# 绘制批次信息
|
||
product_name = batch.product.name
|
||
if len(product_name) > 20:
|
||
product_name = product_name[:18] + '...'
|
||
|
||
# 绘制信息
|
||
draw.text((10, height + 10), product_name, fill='black', font=title_font)
|
||
draw.text((10, height + 40), f"批次: {batch.batch_number}", fill='black', font=info_font)
|
||
draw.text((10, height + 70), f"生产日期: {batch.production_date.strftime('%Y-%m-%d')}", fill='black', font=info_font)
|
||
|
||
return complete_img
|
||
|
||
except Exception as e:
|
||
# 生成错误时的默认图片
|
||
error_img = Image.new('RGB', (300, 150), color='white')
|
||
draw = ImageDraw.Draw(error_img)
|
||
draw.text((10, 10), f"条码生成错误: {str(e)}", fill='black')
|
||
draw.text((10, 30), f"批次: {batch.batch_number}", fill='black')
|
||
draw.text((10, 50), f"商品: {batch.product.name}", fill='black')
|
||
return error_img |