This commit is contained in:
zty 2025-02-17 15:35:24 +08:00
commit 7544efdc1e
9 changed files with 114 additions and 25 deletions

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.12 on 2025-02-17 06:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('em', '0021_auto_20241203_1531'),
]
operations = [
migrations.AddField(
model_name='equipment',
name='cd_req_addr',
field=models.TextField(blank=True, null=True, verbose_name='采集数据的请求地址'),
),
]

View File

@ -114,6 +114,7 @@ class Equipment(CommonBModel):
power_kw = models.FloatField("功率", null=True, blank=True)
coordinates = models.JSONField("坐标", default=dict, blank=True)
cd_req_addr = models.TextField("采集数据的请求地址", null=True, blank=True)
class Meta:
verbose_name = "设备信息"

View File

@ -15,8 +15,8 @@ from django.db import transaction
from apps.em.services import daoru_equipment
from rest_framework.response import Response
from django.conf import settings
from django.db.models import Count, Case, When, IntegerField, Max, OuterRef, Subquery
from datetime import datetime, timedelta
from django.db.models import Count, Case, When, IntegerField
from apps.enp.services import get_last_envdata
# Create your views here.
@ -75,20 +75,13 @@ class EquipmentViewSet(CustomModelViewSet):
if self.request.query_params.get("has_envdata", "no") == "yes":
now = timezone.localtime()
now_10_before = now - timezone.timedelta(minutes=10)
data_ids = [item["id"] for item in data]
from apps.enp.models import EnvData
from apps.enp.serializers import EnvDataSerializer
# 子查询获取每个 equipment_id 对应的最大时间戳
# 后面可以考虑从缓存里拿
last_time_subquery = EnvData.objects.filter(equipment_id=OuterRef("equipment_id"), timex__gte=now_10_before, timex__lte=now).order_by("-timex").values("timex")[:1]
# 主查询,获取每个 equipment_id 对应的完整记录
last_envdata_qs = EnvData.objects.filter(equipment_id__in=data_ids, timex=Subquery(last_time_subquery))
envdata = EnvDataSerializer(last_envdata_qs, many=True).data
envdata_dict = {item["equipment"]: item for item in envdata}
edata_dict = {}
if data:
data_ids = [item["id"] for item in data]
edata = get_last_envdata(data_ids, now_10_before, now)
edata_dict = {item["equipment"]: item for item in edata}
for item in data:
item["envdata"] = envdata_dict.get(item["id"], {})
item["envdata"] = edata_dict.get(item["id"], {})
return data
@action(methods=["get"], detail=False, perms_map={"get": "*"})

View File

@ -1 +1,26 @@
from openpyxl import load_workbook
from apps.enp.models import EnvData
from apps.enp.serializers import EnvDataSerializer
from datetime import datetime
def get_last_envdata(eIds: list, time_start: datetime, time_end: datetime):
eIds_str = ",".join([f"'{item}'" for item in eIds]) # 将 ID 列表格式化为字符串
time_start_str = time_start.strftime("%Y-%m-%d %H:%M:%S")
time_end_str = time_end.strftime("%Y-%m-%d %H:%M:%S")
esql = f'''
SELECT DISTINCT ON (equipment_id) *
FROM enp_envdata ee
WHERE equipment_id IN ({eIds_str})
AND timex AT TIME ZONE 'Asia/Shanghai' >= '{time_start_str}'
AND timex AT TIME ZONE 'Asia/Shanghai' <= '{time_end_str}'
ORDER BY equipment_id, timex DESC
'''
edata = EnvDataSerializer(EnvData.objects.raw(esql), many=True).data
# esql ='''SELECT DISTINCT ON (equipment_id) *
# FROM enp_envdata ee
# WHERE equipment_id IN %s
# AND timex AT TIME ZONE 'Asia/Shanghai' >= %s
# AND timex AT TIME ZONE 'Asia/Shanghai' <= %s
# ORDER BY equipment_id, timex DESC'''
# res = query_all_dict(esql, [tuple(data_ids), now_10_before_str, now_str])
return edata

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.12 on 2025-02-17 01:33
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('em', '0021_auto_20241203_1531'),
('qm', '0042_alter_ptest_testitem'),
]
operations = [
migrations.AddField(
model_name='ftestitem',
name='test_equip',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='em.equipment', verbose_name='检测设备'),
),
]

View File

@ -157,11 +157,11 @@ class Qct(CommonAModel):
@property
def qct_testitems(self):
return QctTestItem.objects.filter(qct=self)
return QctTestItem.objects.filter(qct=self).order_by("sort")
@property
def qct_defects(self):
return QctDefect.objects.filter(qct=self)
return QctDefect.objects.filter(qct=self).order_by("sort")
@property
def qct_mats(self):
@ -314,6 +314,7 @@ class FtestItem(BaseModel):
Ftest, verbose_name='关联检验', on_delete=models.CASCADE)
testitem = models.ForeignKey(
TestItem, verbose_name='质检项目', on_delete=models.CASCADE)
test_equip = models.ForeignKey(Equipment, verbose_name='检测设备', on_delete=models.SET_NULL, null=True, blank=True)
test_user = models.ForeignKey(User, verbose_name='操作人', on_delete=models.CASCADE, null=True, blank=True)
test_val = models.FloatField('测量值', null=True, blank=True)
addto_wpr = models.BooleanField('加入WPR作为信息', default=False)

View File

@ -317,7 +317,7 @@ class FtestItemProcessSerializer(CustomModelSerializer):
source='testitem.description', read_only=True)
class Meta:
model = FtestItem
fields = ["id", "testitem", "test_user", "test_val_json", "testitem_name", "testitem_description", "addto_wpr"]
fields = ["id", "testitem", "test_user", "test_val_json", "testitem_name", "testitem_description", "addto_wpr", "test_equip"]
class FtestProcessSerializer(CustomModelSerializer):
test_user_name = serializers.CharField(

View File

@ -13,9 +13,11 @@ def execute_raw_sql(sql: str, params=None):
cursor.execute(sql, params=params)
else:
cursor.execute(sql)
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
return columns, rows
if cursor.description:
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
return columns, rows
return [], []
def format_sqldata(columns, rows):
return [columns] + rows, [dict(zip(columns, row)) for row in rows]

View File

@ -228,7 +228,7 @@ def get_alldata_with_batch(batch: str):
# 六车间工段生产数据
# 六车间工段生产数据
mgroup_list = ["平头", "粘铁头", "粗中细磨", "抛光", "开槽"]
mgroup_list = ["平头", "粘铁头", "粗中细磨", "平磨", "掏管", "抛光", "开槽", "倒角"]
for mgroup_name in mgroup_list:
if mgroup_name == '粗中细磨':
mgroups = Mgroup.objects.filter(name__in=['粗磨', '粗中磨', '粗中细磨'])
@ -276,9 +276,38 @@ def get_alldata_with_batch(batch: str):
# data["六车间生产入库_日期"] = list(set(data["六车间生产入库_日期"]))
# data["六车间生产入库_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["六车间生产入库_日期"]])
# 成品检验数据
ftestwork_count_fields = FtestWork.count_fields()
ftestwork_qs = FtestWork.objects.filter(batch=batch)
# 六车间中检数据
ftestwork_qs = FtestWork.objects.filter(batch=batch, type="process")
if ftestwork_qs.exists():
data["六车间中检_日期"] = []
data['六车间中检_检验人'] = []
for item in ftestwork_qs:
last_time = item.update_time if item.update_time > last_time else last_time
if item.test_date:
data["六车间中检_日期"].append(item.test_date)
if item.test_user:
data['六车间中检_检验人'].append(item.test_user)
for field in ftestwork_count_fields:
if field == 'count_notok_json':
for k, v in getattr(item, field).items():
if f'六车间中检_{k}' not in data:
data[f'六车间中检_{k}'] = v
else:
data[f'六车间中检_{k}'] += v
else:
if getattr(item, field) > 0 or field in ["count", "count_ok"]:
if f'六车间中检_{field}' not in data:
data[f'六车间中检_{field}'] = getattr(item, field)
else:
data[f'六车间中检_{field}'] += getattr(item, field)
data["六车间中检_日期"] = list(set(data["六车间中检_日期"]))
data["六车间中检_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["六车间中检_日期"]])
data['六车间中检_检验人'] = list(set(data['六车间中检_检验人']))
data['六车间中检_检验人'] = ";".join([item.name for item in data['六车间中检_检验人']])
# 成品检验数据
ftestwork_qs = FtestWork.objects.filter(batch=batch, type="prod")
if ftestwork_qs.exists():
data["成品检验_日期"] = []
data['成品检验_检验人'] = []