From dadfd9669acaa0e5a8ca48c760083f6822a71f86 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 15 May 2026 15:08:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=A0=87=E7=AD=BE=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=89=93=E7=A0=81=E5=99=A8=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=8C=BA=E9=85=8D=E7=BD=AE,=20=E6=94=AF=E6=8C=81=E5=90=8C?= =?UTF-8?q?=E4=B8=80=E4=BF=A1=E6=81=AF=E5=86=85=E5=88=87=E6=8D=A2=E7=A0=81?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LabelTemplate 新增 coder_field 字段(默认"1"), 喷码机一条信息里插入多个不同 码型的用户区时, 不同模板填不同用户区名即可打不同码型(条码/二维码/文本), 无需走 T 指令。coder.py 通讯编码放宽到 latin-1 并校验帧内控制字符。 Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/cm/coder.py | 13 +++++++++++-- .../migrations/0008_labeltemplate_coder_field.py | 16 ++++++++++++++++ apps/cm/models.py | 1 + apps/cm/views.py | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 apps/cm/migrations/0008_labeltemplate_coder_field.py diff --git a/apps/cm/coder.py b/apps/cm/coder.py index b267ab75..cbb86f95 100644 --- a/apps/cm/coder.py +++ b/apps/cm/coder.py @@ -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 0A 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 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: diff --git a/apps/cm/migrations/0008_labeltemplate_coder_field.py b/apps/cm/migrations/0008_labeltemplate_coder_field.py new file mode 100644 index 00000000..df87507c --- /dev/null +++ b/apps/cm/migrations/0008_labeltemplate_coder_field.py @@ -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='打码器用户区名'), + ), + ] diff --git a/apps/cm/models.py b/apps/cm/models.py index 9fe98f11..315eb27c 100644 --- a/apps/cm/models.py +++ b/apps/cm/models.py @@ -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): diff --git a/apps/cm/views.py b/apps/cm/views.py index cf472190..b8e562d8 100644 --- a/apps/cm/views.py +++ b/apps/cm/views.py @@ -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")