feat: send_to_coder 统一走 CQI+JDI 队列, 单/批共用 tdata_list
- 入参只接 tdata_list (列表, 至少一条), 单条就是长度=1 - 每次先 CQI 清队列, 再按顺序 JDI 入 N 条 - 一次光电触发消费一条, 与"一行=一个产品"的业务语义对齐 - 不再保留单条 tdata, 开发期清理掉 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2b3aaf8879
commit
99e2909514
|
|
@ -18,7 +18,7 @@ class Tid2Serializer(serializers.Serializer):
|
||||||
|
|
||||||
|
|
||||||
class CoderSendSerializer(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_ip = serializers.IPAddressField(label='喷码IP')
|
||||||
coder_port = serializers.IntegerField(label='喷码端口', required=False, allow_null=True)
|
coder_port = serializers.IntegerField(label='喷码端口', required=False, allow_null=True)
|
||||||
coder_field = serializers.CharField(label='默认用户区名', required=False, allow_null=True)
|
coder_field = serializers.CharField(label='默认用户区名', required=False, allow_null=True)
|
||||||
|
|
|
||||||
|
|
@ -118,11 +118,13 @@ class LabelTemplateViewSet(CustomModelViewSet):
|
||||||
@action(methods=["post"], detail=True, serializer_class=CoderSendSerializer, perms_map={"post": "*"})
|
@action(methods=["post"], detail=True, serializer_class=CoderSendSerializer, perms_map={"post": "*"})
|
||||||
def send_to_coder(self, request, pk=None, *args, **kwargs):
|
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 上。
|
commands 中不含 '=' 的元素, 会绑定到默认 coder_field 上。
|
||||||
IP/端口/字段全部由请求 body 提供。
|
|
||||||
"""
|
"""
|
||||||
sr = CoderSendSerializer(data=request.data)
|
sr = CoderSendSerializer(data=request.data)
|
||||||
sr.is_valid(raise_exception=True)
|
sr.is_valid(raise_exception=True)
|
||||||
|
|
@ -133,19 +135,23 @@ class LabelTemplateViewSet(CustomModelViewSet):
|
||||||
port = vdata.get("coder_port") or 3100
|
port = vdata.get("coder_port") or 3100
|
||||||
field = vdata.get("coder_field") or "1"
|
field = vdata.get("coder_field") or "1"
|
||||||
|
|
||||||
commands = LabelTemplate.gen_commands(lt.id, None, vdata.get("tdata") or {})
|
batched = []
|
||||||
if not commands:
|
for tdata in vdata["tdata_list"]:
|
||||||
raise ParseError("模板未生成任何指令")
|
commands = LabelTemplate.gen_commands(lt.id, None, tdata)
|
||||||
|
if not commands:
|
||||||
fields = {}
|
raise ParseError("模板未生成任何指令")
|
||||||
for item in commands:
|
fields = {}
|
||||||
text = str(item)
|
for item in commands:
|
||||||
if "=" in text:
|
text = str(item)
|
||||||
k, v = text.split("=", 1)
|
if "=" in text:
|
||||||
fields[k.strip()] = v
|
k, v = text.split("=", 1)
|
||||||
else:
|
fields[k.strip()] = v
|
||||||
fields[field] = text
|
else:
|
||||||
|
fields[field] = text
|
||||||
|
batched.append(fields)
|
||||||
|
|
||||||
client = CoderClient(ip=ip, port=port)
|
client = CoderClient(ip=ip, port=port)
|
||||||
client.update_fields(fields)
|
client.clear_queue()
|
||||||
return Response({"sent": fields, "ip": ip, "port": port})
|
for fields in batched:
|
||||||
|
client.push_queue(fields)
|
||||||
|
return Response({"queued": len(batched), "fields": batched, "ip": ip, "port": port})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue