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 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 from apps.system.models import User
# Create your models here. # Create your models here.
@ -156,3 +156,20 @@ class EInspect(CommonADModel):
inspect_time = models.DateTimeField("巡检时间") inspect_time = models.DateTimeField("巡检时间")
result = models.CharField(max_length=20, choices=INSPECT_RESULTS, verbose_name="巡检结果", help_text=str(INSPECT_RESULTS)) result = models.CharField(max_length=20, choices=INSPECT_RESULTS, verbose_name="巡检结果", help_text=str(INSPECT_RESULTS))
note = models.TextField("备注", null=True, blank=True) 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.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.system.models import Dept
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
from rest_framework import serializers from rest_framework import serializers
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import ValidationError
from rest_framework.exceptions import ParseError from rest_framework.exceptions import ParseError
from apps.wf.serializers import TicketSimpleSerializer
class EcateSerializer(CustomModelSerializer): class EcateSerializer(CustomModelSerializer):
@ -76,3 +77,19 @@ class EInspectSerializer(CustomModelSerializer):
class CdSerializer(serializers.Serializer): 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 django.urls import path, include
from rest_framework.routers import DefaultRouter 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/' API_BASE_URL = 'api/em/'
HTML_BASE_URL = 'dhtml/em/' HTML_BASE_URL = 'dhtml/em/'
@ -10,6 +10,7 @@ router.register('equipment', EquipmentViewSet, basename='equipment')
router.register('echeckrecord', EcheckRecordViewSet, basename='echeckrecord') router.register('echeckrecord', EcheckRecordViewSet, basename='echeckrecord')
router.register('einspect', EInspectViewSet, basename='einspect') router.register('einspect', EInspectViewSet, basename='einspect')
router.register('ecate', EcateViewSet, basename='ecate') router.register('ecate', EcateViewSet, basename='ecate')
router.register('repair', RepairViewSet, basename='repair')
urlpatterns = [ urlpatterns = [
path(API_BASE_URL, include(router.urls)), path(API_BASE_URL, include(router.urls)),
path(API_BASE_URL + 'cd/', CdView.as_view()), 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.utils import swagger_auto_schema
from drf_yasg import openapi from drf_yasg import openapi
from django.utils import timezone 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.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 apps.em.filters import EquipFilterSet
from rest_framework.exceptions import ParseError from rest_framework.exceptions import ParseError
from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin 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 rest_framework.views import APIView
from apps.utils.mixins import MyLoggingMixin from apps.utils.mixins import MyLoggingMixin
import importlib import importlib
from apps.wf.mixins import TicketMixin
from apps.wf.models import Ticket
from apps.system.models import User
# Create your views here. # Create your views here.
@ -189,3 +193,48 @@ class CdView(MyLoggingMixin, APIView):
m = importlib.import_module(module) m = importlib.import_module(module)
f = getattr(m, func) 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("请填写维修开始时间和维修工时")