From 99e290951425a24a29a401207d7b6abf9e159548 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 18 May 2026 15:57:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20send=5Fto=5Fcoder=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E8=B5=B0=20CQI+JDI=20=E9=98=9F=E5=88=97,=20=E5=8D=95/=E6=89=B9?= =?UTF-8?q?=E5=85=B1=E7=94=A8=20tdata=5Flist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 入参只接 tdata_list (列表, 至少一条), 单条就是长度=1 - 每次先 CQI 清队列, 再按顺序 JDI 入 N 条 - 一次光电触发消费一条, 与"一行=一个产品"的业务语义对齐 - 不再保留单条 tdata, 开发期清理掉 Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/cm/serializers.py | 2 +- apps/cm/views.py | 40 +++++++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/apps/cm/serializers.py b/apps/cm/serializers.py index f383e3ea..a3a4f548 100644 --- a/apps/cm/serializers.py +++ b/apps/cm/serializers.py @@ -18,7 +18,7 @@ class Tid2Serializer(serializers.Serializer): class CoderSendSerializer(serializers.Serializer): - tdata = serializers.JSONField(label='模板数据', required=False, default=dict) + tdata_list = serializers.ListField(child=serializers.JSONField(), label='模板数据列表', allow_empty=False) coder_ip = serializers.IPAddressField(label='喷码IP') coder_port = serializers.IntegerField(label='喷码端口', required=False, allow_null=True) coder_field = serializers.CharField(label='默认用户区名', required=False, allow_null=True) diff --git a/apps/cm/views.py b/apps/cm/views.py index a7bff705..e05e6eb6 100644 --- a/apps/cm/views.py +++ b/apps/cm/views.py @@ -118,11 +118,13 @@ class LabelTemplateViewSet(CustomModelViewSet): @action(methods=["post"], detail=True, serializer_class=CoderSendSerializer, perms_map={"post": "*"}) def send_to_coder(self, request, pk=None, *args, **kwargs): """ - 下发指令到伟迪捷 1880 喷码机 + 下发指令到伟迪捷 1880 喷码机 (统一走 CQI + JDI 队列模式) - 按模板 commands 用 tdata 格式化后, 解析为 <字段>=<内容> 对, 合并成单帧 JDA 下发。 + body 传 tdata_list (列表, 至少一条), 每条对应一个产品。 + 每次调用先 CQI 清空队列, 再按顺序 JDI 入队 N 条; + 喷码机每个外部触发(光电)消费一条, 喷一个产品。 + 每条 tdata 走模板 commands, 解析为 <字段>=<内容> 合并成一帧 JDI; commands 中不含 '=' 的元素, 会绑定到默认 coder_field 上。 - IP/端口/字段全部由请求 body 提供。 """ sr = CoderSendSerializer(data=request.data) sr.is_valid(raise_exception=True) @@ -133,19 +135,23 @@ class LabelTemplateViewSet(CustomModelViewSet): port = vdata.get("coder_port") or 3100 field = vdata.get("coder_field") or "1" - commands = LabelTemplate.gen_commands(lt.id, None, vdata.get("tdata") or {}) - if not commands: - raise ParseError("模板未生成任何指令") - - fields = {} - for item in commands: - text = str(item) - if "=" in text: - k, v = text.split("=", 1) - fields[k.strip()] = v - else: - fields[field] = text + batched = [] + for tdata in vdata["tdata_list"]: + commands = LabelTemplate.gen_commands(lt.id, None, tdata) + if not commands: + raise ParseError("模板未生成任何指令") + fields = {} + for item in commands: + text = str(item) + if "=" in text: + k, v = text.split("=", 1) + fields[k.strip()] = v + else: + fields[field] = text + batched.append(fields) client = CoderClient(ip=ip, port=port) - client.update_fields(fields) - return Response({"sent": fields, "ip": ip, "port": port}) + client.clear_queue() + for fields in batched: + client.push_queue(fields) + return Response({"queued": len(batched), "fields": batched, "ip": ip, "port": port})