feat: 维修记录初步完成

This commit is contained in:
caoqianming 2025-12-16 11:23:00 +08:00
parent 190f2f047d
commit 54f4aed729
5 changed files with 131 additions and 7 deletions

View File

@ -0,0 +1,40 @@
# Generated by Django 3.2.12 on 2025-12-15 07:16
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('wf', '0005_workflow_cate'),
('em', '0022_equipment_cd_req_addr'),
]
operations = [
migrations.CreateModel(
name='Repair',
fields=[
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('fault_description', models.TextField(verbose_name='故障描述')),
('fault_cate', models.TextField(blank=True, null=True, verbose_name='故障类别')),
('repair_start_time', models.DateTimeField(blank=True, null=True, verbose_name='维修开始时间')),
('repair_duration', models.DecimalField(decimal_places=1, default=0.0, max_digits=5, verbose_name='维修工时(小时)')),
('repair_description', models.TextField(blank=True, null=True, verbose_name='维修描述')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='repair_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('equipment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='repaire_equip', to='em.equipment', verbose_name='关联设备')),
('repair_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='维修人')),
('ticket', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='repair_ticket', to='wf.ticket', verbose_name='关联工单')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='repair_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
]

View File

@ -1,5 +1,5 @@
from django.db import models
from apps.utils.models import CommonBModel, CommonADModel
from apps.utils.models import CommonBModel, CommonADModel, CommonBDModel
from apps.system.models import User
# Create your models here.
@ -156,3 +156,20 @@ class EInspect(CommonADModel):
inspect_time = models.DateTimeField("巡检时间")
result = models.CharField(max_length=20, choices=INSPECT_RESULTS, verbose_name="巡检结果", help_text=str(INSPECT_RESULTS))
note = models.TextField("备注", null=True, blank=True)
class Repair(CommonADModel):
"""
TN:维修申请
"""
equipment = models.ForeignKey(Equipment, verbose_name="关联设备", on_delete=models.CASCADE, related_name="repaire_equip")
fault_description = models.TextField("故障描述")
fault_cate = models.TextField("故障类别", null=True, blank=True)
repair_user = models.ForeignKey("system.user", verbose_name="维修人", on_delete=models.CASCADE, null=True, blank=True)
repair_start_time = models.DateTimeField("维修开始时间", null=True, blank=True)
repair_duration = models.DecimalField("维修工时(小时)", max_digits=5, decimal_places=1, default=0.0)
repair_description = models.TextField("维修描述", null=True, blank=True)
ticket = models.OneToOneField('wf.ticket', verbose_name='关联工单',
on_delete=models.PROTECT, related_name='repair_ticket', null=True, blank=True)

View File

@ -1,10 +1,11 @@
from apps.utils.serializers import CustomModelSerializer
from apps.em.models import Equipment, EcheckRecord, EInspect, Ecate
from apps.em.models import Equipment, EcheckRecord, EInspect, Ecate, Repair
from apps.system.models import Dept
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework.exceptions import ParseError
from apps.wf.serializers import TicketSimpleSerializer
class EcateSerializer(CustomModelSerializer):
@ -75,4 +76,20 @@ class EInspectSerializer(CustomModelSerializer):
class CdSerializer(serializers.Serializer):
method = serializers.CharField(label="方法名")
method = serializers.CharField(label="方法名")
class RepairCreateSerializer(CustomModelSerializer):
class Meta:
model = Repair
fields = ["id", "equipment", "fault_description", "fault_cate"]
class RepairListSerializer(CustomModelSerializer):
equipment_fullname = serializers.StringRelatedField(source="equipment", read_only=True)
repair_user_name = serializers.CharField(source="repair_user.name", read_only=True)
ticket_ = TicketSimpleSerializer(source="ticket", read_only=True)
class Meta:
model = Repair
fields = "__all__"
read_only_fields = EXCLUDE_FIELDS

View File

@ -1,6 +1,6 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from apps.em.views import EquipmentViewSet, EcheckRecordViewSet, EInspectViewSet, EcateViewSet, CdView
from apps.em.views import EquipmentViewSet, EcheckRecordViewSet, EInspectViewSet, EcateViewSet, CdView, RepairViewSet
API_BASE_URL = 'api/em/'
HTML_BASE_URL = 'dhtml/em/'
@ -10,6 +10,7 @@ router.register('equipment', EquipmentViewSet, basename='equipment')
router.register('echeckrecord', EcheckRecordViewSet, basename='echeckrecord')
router.register('einspect', EInspectViewSet, basename='einspect')
router.register('ecate', EcateViewSet, basename='ecate')
router.register('repair', RepairViewSet, basename='repair')
urlpatterns = [
path(API_BASE_URL, include(router.urls)),
path(API_BASE_URL + 'cd/', CdView.as_view()),

View File

@ -2,9 +2,10 @@ from django.shortcuts import render
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from django.utils import timezone
from apps.em.models import Equipment, EcheckRecord, EInspect, Ecate
from apps.em.models import Equipment, EcheckRecord, EInspect, Ecate, Repair
from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet
from apps.em.serializers import EquipmentSerializer, EcheckRecordSerializer, EInspectSerializer, EcateSerializer, CdSerializer
from apps.em.serializers import (EquipmentSerializer, EcheckRecordSerializer,
EInspectSerializer, EcateSerializer, CdSerializer, RepairCreateSerializer, RepairListSerializer)
from apps.em.filters import EquipFilterSet
from rest_framework.exceptions import ParseError
from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin
@ -20,6 +21,9 @@ from apps.enp.services import get_last_envdata
from rest_framework.views import APIView
from apps.utils.mixins import MyLoggingMixin
import importlib
from apps.wf.mixins import TicketMixin
from apps.wf.models import Ticket
from apps.system.models import User
# Create your views here.
@ -188,4 +192,49 @@ class CdView(MyLoggingMixin, APIView):
module, func = m.rsplit(".", 1)
m = importlib.import_module(module)
f = getattr(m, func)
return Response(f(*args))
return Response(f(*args))
class RepairViewSet(TicketMixin, CustomModelViewSet):
"""
list:维修申请
维修申请
"""
queryset = Repair.objects.all()
create_serializer_class = RepairCreateSerializer
list_serializer_class = RepairListSerializer
retrieve_serializer_class = RepairListSerializer
select_related_fields = ["equipment", "repair_user", "create_by"]
filterset_fields = ["equipment", "repair_user", "ticket__state__type"]
search_fields = ["equipment__name", "equipment__number", "fault_description", "fault_cate", "repair_description"]
workflow_key = "wf_repair"
def gen_other_ticket_data(self, instance):
return {"equipment_fullname": str(instance.equipment)}
@staticmethod
def assgin(ticket: Ticket, transition, new_ticket_data: dict):
repair_user = new_ticket_data.get("repair_user", None)
fault_cate = new_ticket_data.get("fault_cate", None)
if repair_user and fault_cate:
repair = Repair.objects.get(ticket=ticket)
repair.repair_user = User.objects.get(id=repair_user)
repair.fault_cate = fault_cate
repair.save()
else:
raise ParseError("请分派维修人")
@staticmethod
def repair_completed(ticket: Ticket, transition, new_ticket_data: dict):
repair_start_time = new_ticket_data.get("repair_start_time", None)
repair_duration = new_ticket_data.get("repair_duration", None)
repair_description = new_ticket_data.get("repair_description", None)
if repair_start_time and repair_duration:
repair = Repair.objects.get(ticket=ticket)
repair.repair_start_time = repair_start_time
repair.repair_duration = repair_duration
repair.repair_description = repair_description
repair.save()
else:
raise ParseError("请填写维修开始时间和维修工时")