feat: 添加route pack dag显示
This commit is contained in:
parent
2d7183f8dd
commit
a31faa0cda
|
@ -3,6 +3,7 @@ from apps.system.models import CommonAModel, Dictionary, CommonBModel, CommonADM
|
||||||
from rest_framework.exceptions import ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
from apps.utils.models import CommonBDModel
|
from apps.utils.models import CommonBDModel
|
||||||
from collections import defaultdict, deque
|
from collections import defaultdict, deque
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
class Process(CommonBModel):
|
class Process(CommonBModel):
|
||||||
"""
|
"""
|
||||||
|
@ -245,21 +246,23 @@ class Route(CommonADModel):
|
||||||
parent = models.ForeignKey('self', verbose_name='上级路线', on_delete=models.CASCADE, null=True, blank=True)
|
parent = models.ForeignKey('self', verbose_name='上级路线', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_routes(material: Material):
|
def get_routes(material: Material=None, routepack:RoutePack=None):
|
||||||
"""
|
"""
|
||||||
返回工艺路线带车间(不关联工艺包)
|
返回工艺路线带车间(不关联工艺包)
|
||||||
"""
|
"""
|
||||||
|
if material:
|
||||||
kwargs = {'material': material, 'routepack__isnull': True}
|
kwargs = {'material': material, 'routepack__isnull': True}
|
||||||
# 校验工艺路线是否正常
|
rqs = Route.objects.filter(
|
||||||
rq = Route.objects.filter(
|
|
||||||
**kwargs).order_by('sort', 'process__sort', 'create_time')
|
**kwargs).order_by('sort', 'process__sort', 'create_time')
|
||||||
if not rq.exists():
|
# if not rq.exists():
|
||||||
raise ParseError('未配置工艺路线')
|
# raise ParseError('未配置工艺路线')
|
||||||
if rq.first().material_in is None or rq.last().material_out is None or rq.last().material_out != rq.last().material:
|
# if rq.first().material_in is None or rq.last().material_out is None or rq.last().material_out != rq.last().material:
|
||||||
raise ParseError('首步缺少输入/最后一步缺少输出')
|
# raise ParseError('首步缺少输入/最后一步缺少输出')
|
||||||
if not rq.filter(is_count_utask=True).exists():
|
# if not rq.filter(is_count_utask=True).exists():
|
||||||
raise ParseError('未指定统计步骤')
|
# raise ParseError('未指定统计步骤')
|
||||||
return rq
|
elif routepack:
|
||||||
|
rqs = Route.objects.filter(routepack=routepack).order_by('sort', 'process__sort', 'create_time')
|
||||||
|
return rqs
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate_dag(cls, final_material_out:Material, rqs):
|
def validate_dag(cls, final_material_out:Material, rqs):
|
||||||
|
@ -345,6 +348,47 @@ class Route(CommonADModel):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_dag(cls, rqs):
|
||||||
|
# 收集所有相关批次和边
|
||||||
|
nodes_set = set()
|
||||||
|
edges = []
|
||||||
|
|
||||||
|
for rq in rqs:
|
||||||
|
source = rq.material_in.id
|
||||||
|
target = rq.material_out.id
|
||||||
|
nodes_set.update([source, target])
|
||||||
|
edges.append({
|
||||||
|
'source': source,
|
||||||
|
'target': target,
|
||||||
|
'label': rq.process.name,
|
||||||
|
})
|
||||||
|
|
||||||
|
# 去重边
|
||||||
|
unique_edges = {}
|
||||||
|
for edge in edges:
|
||||||
|
key = (edge['source'], edge['target'])
|
||||||
|
if key not in unique_edges:
|
||||||
|
unique_edges[key] = edge
|
||||||
|
# 将批次号排序
|
||||||
|
nodes_qs = Material.objects.filter(id__in=nodes_set).order_by("process__sort", "create_time")
|
||||||
|
|
||||||
|
# batch_to_id = {batch: idx for idx, batch in enumerate(nodes_list)}
|
||||||
|
# 构建节点数据,默认使用'rect'形状
|
||||||
|
nodes = [{
|
||||||
|
'id': item.id,
|
||||||
|
'label': str(item),
|
||||||
|
'shape': 'rect' # 可根据业务需求调整形状
|
||||||
|
} for item in nodes_qs]
|
||||||
|
|
||||||
|
# 构建边数据
|
||||||
|
edges_converted = [{
|
||||||
|
'source': edge['source'],
|
||||||
|
'target': edge['target'],
|
||||||
|
'label': edge['label']
|
||||||
|
} for edge in unique_edges.values()]
|
||||||
|
|
||||||
|
return {'nodes': nodes, 'edges': edges_converted}
|
||||||
class RouteMat(BaseModel):
|
class RouteMat(BaseModel):
|
||||||
route = models.ForeignKey(Route, verbose_name='关联路线', on_delete=models.CASCADE, related_name="routemat_route")
|
route = models.ForeignKey(Route, verbose_name='关联路线', on_delete=models.CASCADE, related_name="routemat_route")
|
||||||
material = models.ForeignKey(Material, verbose_name='辅助物料', on_delete=models.CASCADE)
|
material = models.ForeignKey(Material, verbose_name='辅助物料', on_delete=models.CASCADE)
|
|
@ -283,7 +283,9 @@ class RoutePackViewSet(CustomModelViewSet):
|
||||||
ins.save()
|
ins.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
@action(methods=['get'], detail=True, perms_map={'get': '*'})
|
||||||
|
def dag(self, request, *args, **kwargs):
|
||||||
|
return Response(Route.get_dag(rqs=Route.objects.filter(routepack=self.get_object())))
|
||||||
class RouteViewSet(CustomModelViewSet):
|
class RouteViewSet(CustomModelViewSet):
|
||||||
queryset = Route.objects.all()
|
queryset = Route.objects.all()
|
||||||
serializer_class = RouteSerializer
|
serializer_class = RouteSerializer
|
||||||
|
|
|
@ -167,9 +167,9 @@ class PmService:
|
||||||
else:
|
else:
|
||||||
# 获取产品的加工路线
|
# 获取产品的加工路线
|
||||||
if utask.routepack: # 指定工艺路线
|
if utask.routepack: # 指定工艺路线
|
||||||
rqs = Route.objects.filter(routepack=utask.routepack).order_by('sort', 'process__sort', 'create_time')
|
rqs = Route.get_routes(routepack=utask.routepack)
|
||||||
else:
|
else:
|
||||||
rqs = Route.get_routes(product)
|
rqs = Route.get_routes(material=product)
|
||||||
if not rqs.exists():
|
if not rqs.exists():
|
||||||
raise ParseError('未配置工艺路线')
|
raise ParseError('未配置工艺路线')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue