feat: 开始添加设备管理模块

This commit is contained in:
caoqianming 2023-05-22 15:55:32 +08:00
parent b1ded623fa
commit 936af7c4fe
15 changed files with 318 additions and 1 deletions

View File

@ -0,0 +1,33 @@
# Generated by Django 3.2.12 on 2023-05-22 07:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('bi', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='dataset',
name='description',
field=models.TextField(blank=True, default='', verbose_name='描述说明'),
),
migrations.AlterField(
model_name='dataset',
name='sql_query',
field=models.TextField(blank=True, default='', verbose_name='sql查询语句'),
),
migrations.AlterField(
model_name='report',
name='code',
field=models.CharField(blank=True, default='', max_length=100, verbose_name='标识'),
),
migrations.AlterField(
model_name='report',
name='js_function',
field=models.TextField(blank=True, default='', verbose_name='数据转化函数'),
),
]

0
apps/em/__init__.py Normal file
View File

3
apps/em/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
apps/em/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class EmConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.em'

20
apps/em/filters.py Normal file
View File

@ -0,0 +1,20 @@
from django_filters import rest_framework as filters
from apps.em.models import Equipment
from datetime import datetime, timedelta
class EquipFilterSet(filters.FilterSet):
tag = filters.CharFilter(method='filter_tag')
class Meta:
model = Equipment
fields = ['keeper', 'type', 'tag']
def filter_tag(self, queryset, name, value):
now = datetime.now()
day7_after = now + timedelta(days=7)
if value == 'near_check':
queryset = queryset.filter(
next_check_date__lte = datetime.date(day7_after))
elif value == 'out_check':
queryset = queryset.filter(
next_check_date__gt = datetime.date(now))
return queryset

View File

@ -0,0 +1,69 @@
# Generated by Django 3.2.12 on 2023-05-22 07:53
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('system', '0002_myschedule'),
]
operations = [
migrations.CreateModel(
name='Equipment',
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='删除标记')),
('type', models.PositiveSmallIntegerField(choices=[(10, '生产设备'), (20, '计量检测工具')], default=10, verbose_name='类型')),
('name', models.CharField(max_length=50, verbose_name='设备名称')),
('number', models.CharField(max_length=50, unique=True, verbose_name='设备编号')),
('model', models.CharField(blank=True, default='', max_length=60, verbose_name='规格型号')),
('factory', models.CharField(blank=True, default='', max_length=50, verbose_name='生产厂')),
('production_date', models.DateField(blank=True, null=True, verbose_name='生产日期')),
('buy_date', models.DateField(blank=True, null=True, verbose_name='购置日期')),
('state', models.PositiveIntegerField(choices=[(10, '完好'), (20, '限用'), (30, '在修'), (40, '禁用'), (50, '报废')], default=10, verbose_name='设备状态')),
('parameter', models.TextField(blank=True, default='', verbose_name='技术参数')),
('place', models.CharField(blank=True, default='', max_length=50, verbose_name='安装/存放位置')),
('count', models.PositiveIntegerField(default=1, verbose_name='数量')),
('description', models.CharField(default='', max_length=200, null=True, verbose_name='描述')),
('cycle', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='校准或检定周期(月)')),
('check_date', models.DateField(blank=True, null=True, verbose_name='最近校准检查日期')),
('next_check_date', models.DateField(blank=True, null=True, verbose_name='预计下次校准检查日期')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='equipment_belong_dept', to='system.dept', verbose_name='所属部门')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='equipment_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('keeper', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='责任人')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='equipment_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '设备信息',
'verbose_name_plural': '设备信息',
},
),
migrations.CreateModel(
name='Mpoint',
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='删除标记')),
('name', models.CharField(max_length=50, verbose_name='测点名称')),
('code', models.CharField(max_length=50, verbose_name='测点编号')),
('unit', models.CharField(max_length=50, verbose_name='单位')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mpoint_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('equipment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='em.equipment', verbose_name='关联设备')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mpoint_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
]

View File

90
apps/em/models.py Normal file
View File

@ -0,0 +1,90 @@
from django.db import models
from apps.utils.models import CommonBModel, CommonADModel, CommonAModel
from apps.system.models import User
# Create your models here.
class Equipment(CommonBModel):
"""
设备台账信息
其中belong_dept是责任部门
"""
EQUIP_STATE_OK = 10
EQUIP_STATE_LIMIT = 20
EQUIP_STATE_FIX = 30
EQUIP_STATE_DISABLE = 40
EQUIP_STATE_SCRAP = 50
state_choices = (
(EQUIP_STATE_OK, '完好'),
(EQUIP_STATE_LIMIT, '限用'),
(EQUIP_STATE_FIX, '在修'),
(EQUIP_STATE_DISABLE, '禁用'),
(EQUIP_STATE_SCRAP, '报废')
)
EQUIP_TYPE_PRO = 10
EQUIP_TYPE_MEA = 20
type_choices = (
(10, '生产设备'),
(20, '计量检测工具')
)
# mgmtype_choices = (
# (1, 'A'),
# (2, 'B'),
# (3, 'C')
# )
# way_choices = (
# (1, '外检'),
# (2, '自检'),
# )
# usetype_choices = (
# (1, '专用'),
# (2, '公用'),
# )
type = models.PositiveSmallIntegerField('类型', choices=type_choices, default=10)
name = models.CharField('设备名称', max_length=50)
number = models.CharField('设备编号', max_length=50, unique=True)
model = models.CharField('规格型号', max_length=60, default='', blank=True)
factory = models.CharField('生产厂', max_length=50, default='', blank=True)
production_date = models.DateField('生产日期', null=True, blank=True)
buy_date = models.DateField('购置日期', null=True, blank=True)
state = models.PositiveIntegerField('设备状态', choices=state_choices, default=EQUIP_STATE_OK)
parameter = models.TextField('技术参数', default='', blank=True)
place = models.CharField('安装/存放位置', max_length=50, default='', blank=True)
count = models.PositiveIntegerField('数量', default=1)
keeper = models.ForeignKey(User, verbose_name='责任人', on_delete=models.CASCADE, null=True, blank=True)
description = models.CharField('描述', max_length=200, default='', null=True)
# 以下是计量检测设备单独字段
# mgmtype = models.IntegerField('管理类别', choices=mgmtype_choices, default=1)
# usetype = models.IntegerField('使用类别', choices=usetype_choices, default=1)
# way = models.IntegerField('校准或检定方式', choices=way_choices, default=1)
# standard = models.CharField('溯源标准或依据', max_length=200, default='', blank=True)
cycle = models.PositiveSmallIntegerField('校准或检定周期(月)', null=True, blank=True)
check_date = models.DateField('最近校准检查日期', blank=True, null=True)
next_check_date = models.DateField('预计下次校准检查日期',blank=True, null=True)
class Meta:
verbose_name = '设备信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.number + '-' + self.name
# class EcheckRecord(CommonADModel):
# """
# 校准鉴定记录
# """
# equipment = models.ForeignKey(Equipment, verbose_name='关联设备', on_delete=models.CASCADE)
# check_date = models.DateField('校准检查日期')
# result = models.CharField('结果', max_length=200, blank=True, null=True)
class Mpoint(CommonAModel):
"""测点
"""
equipment = models.ForeignKey(Equipment, verbose_name='关联设备', on_delete=models.CASCADE)
name = models.CharField('测点名称', max_length=50)
code = models.CharField('测点编号', max_length=50)
unit = models.CharField('单位', max_length=50)

19
apps/em/serializers.py Normal file
View File

@ -0,0 +1,19 @@
from apps.utils.serializers import CustomModelSerializer
from apps.em.models import Equipment, Mpoint
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
from rest_framework import serializers
class EquipmentSerializer(CustomModelSerializer):
keeper_name = serializers.CharField(source='keeper.name')
belong_dept_name = serializers.CharField(source='belong_dept.name')
class Meta:
model = Equipment
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS + ['check_date', 'next_check_date', 'keeper_name', 'belong_dept_name']
class MpointSerializer(CustomModelSerializer):
class Meta:
model = Mpoint
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS

3
apps/em/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

13
apps/em/urls.py Normal file
View File

@ -0,0 +1,13 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from apps.em.views import EquipmentViewSet, MpointViewSet
API_BASE_URL = 'api/em/'
HTML_BASE_URL = 'em/'
router = DefaultRouter()
router.register('equipment', EquipmentViewSet, basename='equipment')
router.register('mpoint', MpointViewSet, basename='mpoint')
urlpatterns = [
path(API_BASE_URL, include(router.urls)),
]

27
apps/em/views.py Normal file
View File

@ -0,0 +1,27 @@
from django.shortcuts import render
from apps.em.models import Equipment, Mpoint
from apps.utils.viewsets import CustomModelViewSet
from apps.em.serializers import EquipmentSerializer, MpointSerializer
from apps.em.filters import EquipFilterSet
from rest_framework.exceptions import ParseError
# Create your views here.
class EquipmentViewSet(CustomModelViewSet):
queryset = Equipment.objects.all()
serializer_class = EquipmentSerializer
select_related_fields = ['create_by', 'belong_dept', 'keeper']
search_fields = ['number', 'name']
filterset_class = EquipFilterSet
def filter_queryset(self, queryset):
if not self.detail and not self.request.query_params.get('type', None):
raise ParseError('请指定设备类型')
return super().filter_queryset(queryset)
class MpointViewSet(CustomModelViewSet):
queryset = Mpoint.objects.all()
serializer_class = MpointSerializer
select_related_fields = ['create_by']
filterset_fields = ['equipment']
search_fields = ['number', 'code']

32
docs/nengguan.md Normal file
View File

@ -0,0 +1,32 @@
# 能管系统设计说明书
## 设备管理
### 用能设备
编号、名称、设备类别、责任部门、设备重要性、设备描述、基本技术参数、原始采购信息(制造和安装)、重要技术参数、设备逻辑和物理位置。
设备信息变更记录-具体信息待定
设备档案查询-根据查询人岗位及权限不同,查询功能不同-待定 **意义是?**
用能设备可关联计量器具,用于监测设备状态
**计量器具与测点的关系?**
### 计量器具
基本技术参数、原始采购信息(制造和安装)、重要技术参数、**库存信息?**
检验校准记录-记录结果-是否需要上传相关文件
### 设备监测
重点设备状态监测
设备名称、设备当前状态、与设备启停等关联的测点名称、测点值、测点单位
形成状态变动记录,可提示或报警 **何时?**
## 实时监控
### 综合看板

View File

@ -63,7 +63,8 @@ INSTALLED_APPS = [
'apps.vm',
'apps.rpm',
'apps.opm',
'apps.bi'
'apps.bi',
'apps.em'
]
MIDDLEWARE = [

View File

@ -55,6 +55,7 @@ urlpatterns = [
path('', include('apps.opm.urls')),
path('', include('apps.vm.urls')),
path('', include('apps.bi.urls')),
path('', include('apps.em.urls')),