fix: correct targeted search logic for material/stock list to prevent unrelated results

This commit is contained in:
DXC
2026-03-19 09:49:21 +08:00
parent de887136a3
commit ebb7969807
23 changed files with 3723 additions and 0 deletions

View File

@ -0,0 +1,139 @@
import socket
import os
from io import BytesIO
from PIL import Image, ImageDraw
# 引入条形码生成库
try:
import barcode
from barcode.writer import ImageWriter
except ImportError:
print("❌ 错误: 请先安装 python-barcode (pip install python-barcode)")
exit()
class BarcodeStackTester:
# 打印机配置
PRINTER_IP = "192.168.9.205"
PRINTER_PORT = 9100
# 纸张配置: 40mm x 30mm @ 300 DPI
DOTS_PER_MM = 12
CANVAS_W = int(40 * DOTS_PER_MM) # 480px
CANVAS_H = int(30 * DOTS_PER_MM) # 360px
@staticmethod
def _generate_raw_barcode(content, bar_height_mm=4):
"""
生成原始条码图片 (不强制缩放宽度,让其自然生长)
"""
try:
# Code128 自动优化 (数字会被压缩所以20位数字其实不长)
writer = ImageWriter()
# module_width: 条码黑条的最小宽度(mm)。
# 0.2mm 在 300DPI 下约等于 2.4像素。这是一个比较清晰且节省空间的数值。
# 如果设得太大(如0.3)20位可能会超出40mm纸张。
options = {
"module_width": 0.2,
"module_height": bar_height_mm, # 条码高度
"quiet_zone": 2.0, # 两侧留白(mm)
"write_text": False, # 【关键】不写文字
"dpi": 300 # 对应打印机DPI
}
code_img = barcode.get('code128', content, writer=writer)
# 渲染到内存
buffer = BytesIO()
code_img.write(buffer, options=options)
buffer.seek(0)
return Image.open(buffer)
except Exception as e:
print(f"生成失败: {e}")
return None
def run_test(self):
# 1. 创建白色底图 (40x30mm)
canvas = Image.new('RGB', (self.CANVAS_W, self.CANVAS_H), color='white')
# 测试用例: 长度从小到大
test_lengths = [13, 15, 17, 20]
# 布局参数
current_y = 20 # 顶部起始留白 (px)
gap = 10 # 间距 (px)
print("-" * 50)
print("🚀 开始生成堆叠条码测试图...")
for length in test_lengths:
# 生成全7的内容
content = "7" * length
print(f" 正在处理: {length}位 -> {content}")
# 生成条码 (高度设为5mm左右方便在一张纸上放下4个)
bar_img = self._generate_raw_barcode(content, bar_height_mm=5)
if bar_img:
# 计算居中位置
# bar_img.width 是条码生成的自然宽度
x_pos = (self.CANVAS_W - bar_img.width) // 2
# 如果宽度超出了纸张 (x_pos < 0)说明40mm纸打不下这么多位
if x_pos < 0:
print(f" ⚠️ 警告: {length}位条码过宽 ({bar_img.width}px > {self.CANVAS_W}px),可能会被裁切!")
x_pos = 0
# 粘贴到画布
canvas.paste(bar_img, (x_pos, current_y))
# 更新Y坐标准备画下一个
current_y += bar_img.height + gap
else:
print(" 生成失败")
# 2. 保存预览图
preview_file = "test_stack_preview.jpg"
canvas.save(preview_file)
print(f"✅ 图片已生成: {preview_file} (请打开查看宽度是否超出)")
# 3. 发送打印 (二值化处理)
self._send_to_printer(canvas)
def _send_to_printer(self, img_rgb):
try:
# 转二值化 (白=1, 黑=0)
img_bw = img_rgb.convert('L').convert('1', dither=Image.Dither.NONE)
bitmap_data = img_bw.tobytes()
width_bytes = (img_bw.width + 7) // 8
height_dots = img_bw.height
# TSPL 指令
header = (
f"SIZE 40 mm, 30 mm\r\n"
"GAP 2 mm, 0 mm\r\n"
"CLS\r\n"
"DIRECTION 1\r\n"
).encode('gbk')
bitmap_cmd = f"BITMAP 0,0,{width_bytes},{height_dots},0,".encode('gbk')
footer = b"\r\nPRINT 1,1\r\n"
print("🖨️ 正在发送打印指令...")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.connect((self.PRINTER_IP, self.PRINTER_PORT))
s.sendall(header + bitmap_cmd + bitmap_data + footer)
s.close()
print("✅ 指令已发送")
except Exception as e:
print(f"❌ 打印失败: {e}")
if __name__ == "__main__":
tester = BarcodeStackTester()
tester.run_test()