Merge branch 'master' of https://e.coding.net/ctcdevteam/ehs/ehs_server
This commit is contained in:
commit
7544efdc1e
|
@ -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='采集数据的请求地址'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -114,6 +114,7 @@ class Equipment(CommonBModel):
|
||||||
power_kw = models.FloatField("功率", null=True, blank=True)
|
power_kw = models.FloatField("功率", null=True, blank=True)
|
||||||
|
|
||||||
coordinates = models.JSONField("坐标", default=dict, blank=True)
|
coordinates = models.JSONField("坐标", default=dict, blank=True)
|
||||||
|
cd_req_addr = models.TextField("采集数据的请求地址", null=True, blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "设备信息"
|
verbose_name = "设备信息"
|
||||||
|
|
|
@ -15,8 +15,8 @@ from django.db import transaction
|
||||||
from apps.em.services import daoru_equipment
|
from apps.em.services import daoru_equipment
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import Count, Case, When, IntegerField, Max, OuterRef, Subquery
|
from django.db.models import Count, Case, When, IntegerField
|
||||||
from datetime import datetime, timedelta
|
from apps.enp.services import get_last_envdata
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
@ -75,20 +75,13 @@ class EquipmentViewSet(CustomModelViewSet):
|
||||||
if self.request.query_params.get("has_envdata", "no") == "yes":
|
if self.request.query_params.get("has_envdata", "no") == "yes":
|
||||||
now = timezone.localtime()
|
now = timezone.localtime()
|
||||||
now_10_before = now - timezone.timedelta(minutes=10)
|
now_10_before = now - timezone.timedelta(minutes=10)
|
||||||
|
edata_dict = {}
|
||||||
|
if data:
|
||||||
data_ids = [item["id"] for item in data]
|
data_ids = [item["id"] for item in data]
|
||||||
from apps.enp.models import EnvData
|
edata = get_last_envdata(data_ids, now_10_before, now)
|
||||||
from apps.enp.serializers import EnvDataSerializer
|
edata_dict = {item["equipment"]: item for item in edata}
|
||||||
|
|
||||||
# 子查询获取每个 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}
|
|
||||||
for item in data:
|
for item in data:
|
||||||
item["envdata"] = envdata_dict.get(item["id"], {})
|
item["envdata"] = edata_dict.get(item["id"], {})
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@action(methods=["get"], detail=False, perms_map={"get": "*"})
|
@action(methods=["get"], detail=False, perms_map={"get": "*"})
|
||||||
|
|
|
@ -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
|
|
@ -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='检测设备'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -157,11 +157,11 @@ class Qct(CommonAModel):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def qct_testitems(self):
|
def qct_testitems(self):
|
||||||
return QctTestItem.objects.filter(qct=self)
|
return QctTestItem.objects.filter(qct=self).order_by("sort")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def qct_defects(self):
|
def qct_defects(self):
|
||||||
return QctDefect.objects.filter(qct=self)
|
return QctDefect.objects.filter(qct=self).order_by("sort")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def qct_mats(self):
|
def qct_mats(self):
|
||||||
|
@ -314,6 +314,7 @@ class FtestItem(BaseModel):
|
||||||
Ftest, verbose_name='关联检验', on_delete=models.CASCADE)
|
Ftest, verbose_name='关联检验', on_delete=models.CASCADE)
|
||||||
testitem = models.ForeignKey(
|
testitem = models.ForeignKey(
|
||||||
TestItem, verbose_name='质检项目', on_delete=models.CASCADE)
|
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_user = models.ForeignKey(User, verbose_name='操作人', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
test_val = models.FloatField('测量值', null=True, blank=True)
|
test_val = models.FloatField('测量值', null=True, blank=True)
|
||||||
addto_wpr = models.BooleanField('加入WPR作为信息', default=False)
|
addto_wpr = models.BooleanField('加入WPR作为信息', default=False)
|
||||||
|
|
|
@ -317,7 +317,7 @@ class FtestItemProcessSerializer(CustomModelSerializer):
|
||||||
source='testitem.description', read_only=True)
|
source='testitem.description', read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = FtestItem
|
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):
|
class FtestProcessSerializer(CustomModelSerializer):
|
||||||
test_user_name = serializers.CharField(
|
test_user_name = serializers.CharField(
|
||||||
|
|
|
@ -13,9 +13,11 @@ def execute_raw_sql(sql: str, params=None):
|
||||||
cursor.execute(sql, params=params)
|
cursor.execute(sql, params=params)
|
||||||
else:
|
else:
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
|
if cursor.description:
|
||||||
columns = [desc[0] for desc in cursor.description]
|
columns = [desc[0] for desc in cursor.description]
|
||||||
rows = cursor.fetchall()
|
rows = cursor.fetchall()
|
||||||
return columns, rows
|
return columns, rows
|
||||||
|
return [], []
|
||||||
|
|
||||||
def format_sqldata(columns, rows):
|
def format_sqldata(columns, rows):
|
||||||
return [columns] + rows, [dict(zip(columns, row)) for row in rows]
|
return [columns] + rows, [dict(zip(columns, row)) for row in rows]
|
||||||
|
|
|
@ -228,7 +228,7 @@ def get_alldata_with_batch(batch: str):
|
||||||
# 六车间工段生产数据
|
# 六车间工段生产数据
|
||||||
|
|
||||||
# 六车间工段生产数据
|
# 六车间工段生产数据
|
||||||
mgroup_list = ["平头", "粘铁头", "粗中细磨", "抛光", "开槽"]
|
mgroup_list = ["平头", "粘铁头", "粗中细磨", "平磨", "掏管", "抛光", "开槽", "倒角"]
|
||||||
for mgroup_name in mgroup_list:
|
for mgroup_name in mgroup_list:
|
||||||
if mgroup_name == '粗中细磨':
|
if mgroup_name == '粗中细磨':
|
||||||
mgroups = Mgroup.objects.filter(name__in=['粗磨', '粗中磨', '粗中细磨'])
|
mgroups = Mgroup.objects.filter(name__in=['粗磨', '粗中磨', '粗中细磨'])
|
||||||
|
@ -276,9 +276,38 @@ def get_alldata_with_batch(batch: str):
|
||||||
# data["六车间生产入库_日期"] = list(set(data["六车间生产入库_日期"]))
|
# data["六车间生产入库_日期"] = list(set(data["六车间生产入库_日期"]))
|
||||||
# data["六车间生产入库_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["六车间生产入库_日期"]])
|
# data["六车间生产入库_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["六车间生产入库_日期"]])
|
||||||
|
|
||||||
# 成品检验数据
|
|
||||||
ftestwork_count_fields = FtestWork.count_fields()
|
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():
|
if ftestwork_qs.exists():
|
||||||
data["成品检验_日期"] = []
|
data["成品检验_日期"] = []
|
||||||
data['成品检验_检验人'] = []
|
data['成品检验_检验人'] = []
|
||||||
|
|
Loading…
Reference in New Issue