feat: 标签模板增加打码器用户区配置, 支持同一信息内切换码型

LabelTemplate 新增 coder_field 字段(默认"1"), 喷码机一条信息里插入多个不同
码型的用户区时, 不同模板填不同用户区名即可打不同码型(条码/二维码/文本),
无需走 T 指令。coder.py 通讯编码放宽到 latin-1 并校验帧内控制字符。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
caoqianming 2026-05-15 15:08:25 +08:00
parent 1299bddc6a
commit dadfd9669a
4 changed files with 29 additions and 3 deletions

View File

@ -42,14 +42,23 @@ class CoderClient:
raise CoderError(f"打码器返回失败: {resp!r}")
raise CoderError(f"打码器响应不识别: {resp!r}")
@staticmethod
def _encode_payload(value: str, label: str) -> bytes:
if any(c in value for c in ("\x02", "\x03", "\x0a")):
raise CoderError(f"{label}含控制字符(STX/ETX/LF), 会破坏帧结构")
try:
return value.encode("latin-1")
except UnicodeEncodeError as e:
raise CoderError(f"{label}含喷码机不支持的字符: {e}")
def update_field(self, field_name: str, content: str) -> bool:
"""更新用户区: 02 55 <field> 0A <content> 03"""
frame = STX + b"\x55" + field_name.encode("ascii") + LF + content.encode("ascii") + ETX
frame = STX + b"\x55" + self._encode_payload(field_name, "用户区名") + LF + self._encode_payload(content, "喷印内容") + ETX
return self._check_ack(self._send(frame))
def select_message(self, message_name: str) -> bool:
"""选择信息: 02 4D <name> 03"""
frame = STX + b"\x4d" + message_name.encode("ascii") + ETX
frame = STX + b"\x4d" + self._encode_payload(message_name, "信息名") + ETX
return self._check_ack(self._send(frame))
def get_status(self) -> bytes:

View File

@ -0,0 +1,16 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cm', '0007_labeltemplate_coder'),
]
operations = [
migrations.AddField(
model_name='labeltemplate',
name='coder_field',
field=models.CharField(default='1', max_length=32, verbose_name='打码器用户区名'),
),
]

View File

@ -24,6 +24,7 @@ class LabelTemplate(BaseModel):
process_json = models.JSONField("工序", default=list, blank=True)
coder_ip = models.GenericIPAddressField("打码器IP", null=True, blank=True)
coder_port = models.PositiveIntegerField("打码器端口", default=3100)
coder_field = models.CharField("打码器用户区名", max_length=32, default="1")
@classmethod
def gen_commands(cls, label_template, label_template_name, tdata):

View File

@ -130,7 +130,7 @@ class LabelTemplateViewSet(CustomModelViewSet):
ip = vdata.get("coder_ip") or lt.coder_ip
port = vdata.get("coder_port") or lt.coder_port
field = vdata.get("coder_field") or "1"
field = vdata.get("coder_field") or lt.coder_field or "1"
if not ip:
raise ParseError("模板未配置打码器IP, 也未在请求中提供 coder_ip")