ioe/inventory/utils/barcode_api.py
2025-04-27 14:50:32 +08:00

181 lines
6.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
条码生成工具函数 - 不依赖于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