feat: 增加wpm,qm,mtm三个app
This commit is contained in:
parent
0312de5cf5
commit
1d16949d8a
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 3.2.12 on 2023-06-15 08:27
|
# Generated by Django 3.2.12 on 2023-06-20 09:05
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
@ -11,27 +11,26 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
('em', '0001_initial'),
|
('em', '0001_initial'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
('system', '0002_myschedule'),
|
('system', '0002_myschedule'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Mgroup',
|
name='MpLog',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')),
|
('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='创建时间')),
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
('update_time', models.DateTimeField(auto_now=True, 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='删除标记')),
|
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||||
('name', models.CharField(max_length=50, verbose_name='名称')),
|
('tag_id', models.BigIntegerField(db_index=True, verbose_name='记录ID')),
|
||||||
('cate', models.CharField(default='section', max_length=50, verbose_name='分类')),
|
('tag_code', models.CharField(max_length=50, verbose_name='测点编号')),
|
||||||
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mgroup_belong_dept', to='system.dept', verbose_name='所属部门')),
|
('tag_update', models.DateTimeField(verbose_name='更新时间')),
|
||||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mgroup_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
('tag_val', models.FloatField(verbose_name='当前值')),
|
||||||
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mgroup_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': '测点集',
|
'abstract': False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
|
@ -49,135 +48,11 @@ class Migration(migrations.Migration):
|
||||||
('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='创建人')),
|
('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='创建人')),
|
||||||
('ep_belong', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mp_ep_belong', to='em.equipment', verbose_name='属于哪个设备')),
|
('ep_belong', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mp_ep_belong', to='em.equipment', verbose_name='属于哪个设备')),
|
||||||
('ep_monitored', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mp_ep_monitored', to='em.equipment', verbose_name='监测哪个设备')),
|
('ep_monitored', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mp_ep_monitored', to='em.equipment', verbose_name='监测哪个设备')),
|
||||||
('mgroup', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='enm.mgroup', 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={
|
options={
|
||||||
'abstract': False,
|
'abstract': False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
|
||||||
name='SfLog',
|
|
||||||
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='删除标记')),
|
|
||||||
('start_time', models.DateTimeField(verbose_name='值班开始')),
|
|
||||||
('end_time', models.DateTimeField(verbose_name='值班结束')),
|
|
||||||
('note', 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='sflog_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
|
||||||
('leader', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='班长')),
|
|
||||||
('mgroup', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='enm.mgroup', verbose_name='关联工段')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='StLog',
|
|
||||||
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='删除标记')),
|
|
||||||
('start_time', models.DateTimeField(verbose_name='停机开始')),
|
|
||||||
('end_time', models.DateTimeField(blank=True, null=True, verbose_name='停机结束')),
|
|
||||||
('duration', models.FloatField(blank=True, null=True, verbose_name='停机时长(h)')),
|
|
||||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stlog_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
|
||||||
('mgroup', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='enm.mgroup', verbose_name='关联工段')),
|
|
||||||
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stlog_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Team',
|
|
||||||
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='名称')),
|
|
||||||
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='team_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='team_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
|
||||||
('leader', models.ForeignKey(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='team_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='StSfLog',
|
|
||||||
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='删除标记')),
|
|
||||||
('is_current_down', models.BooleanField(default=False, verbose_name='是否本班停机')),
|
|
||||||
('reason', models.TextField(blank=True, null=True, verbose_name='停机原因')),
|
|
||||||
('sflog', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='enm.sflog', verbose_name='关联值班记录')),
|
|
||||||
('stlog', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='enm.stlog', verbose_name='关联停机记录')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'ordering': ['sflog__start_time'],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Shift',
|
|
||||||
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='名称')),
|
|
||||||
('start_time_o', models.TimeField(verbose_name='开始时间')),
|
|
||||||
('end_time_o', models.TimeField(verbose_name='结束时间')),
|
|
||||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='shift_create_by', 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='shift_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': '班次',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='sflog',
|
|
||||||
name='shift',
|
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='enm.shift', verbose_name='当班班次'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='sflog',
|
|
||||||
name='stlogs',
|
|
||||||
field=models.ManyToManyField(through='enm.StSfLog', to='enm.StLog', verbose_name='关联停机记录'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='sflog',
|
|
||||||
name='team',
|
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='enm.team', verbose_name='班组'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='sflog',
|
|
||||||
name='update_by',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sflog_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Product',
|
|
||||||
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(blank=True, max_length=50, null=True, verbose_name='编号')),
|
|
||||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='product_create_by', 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='product_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': '产品',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='MpointStat',
|
name='MpointStat',
|
||||||
fields=[
|
fields=[
|
||||||
|
@ -197,53 +72,4 @@ class Migration(migrations.Migration):
|
||||||
'abstract': False,
|
'abstract': False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
|
||||||
name='MpLog',
|
|
||||||
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='删除标记')),
|
|
||||||
('tag_id', models.BigIntegerField(db_index=True, verbose_name='记录ID')),
|
|
||||||
('tag_code', models.CharField(max_length=50, verbose_name='测点编号')),
|
|
||||||
('tag_update', models.DateTimeField(verbose_name='更新时间')),
|
|
||||||
('tag_val', models.FloatField(verbose_name='当前值')),
|
|
||||||
('mpoint', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='enm.mpoint', verbose_name='关联测点')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Goal',
|
|
||||||
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='删除标记')),
|
|
||||||
('year', models.PositiveSmallIntegerField(verbose_name='年')),
|
|
||||||
('goal_name', models.CharField(help_text='总产量/台时产量/单位产品分布电耗/', max_length=50, verbose_name='目标名称')),
|
|
||||||
('goal_val', models.FloatField(verbose_name='全年目标值')),
|
|
||||||
('goal_val_1', models.FloatField(verbose_name='1月份目标值')),
|
|
||||||
('goal_val_2', models.FloatField(verbose_name='2月份目标值')),
|
|
||||||
('goal_val_3', models.FloatField(verbose_name='3月份目标值')),
|
|
||||||
('goal_val_4', models.FloatField(verbose_name='4月份目标值')),
|
|
||||||
('goal_val_5', models.FloatField(verbose_name='5月份目标值')),
|
|
||||||
('goal_val_6', models.FloatField(verbose_name='6月份目标值')),
|
|
||||||
('goal_val_7', models.FloatField(verbose_name='7月份目标值')),
|
|
||||||
('goal_val_8', models.FloatField(verbose_name='8月份目标值')),
|
|
||||||
('goal_val_9', models.FloatField(verbose_name='9月份目标值')),
|
|
||||||
('goal_val_10', models.FloatField(verbose_name='10月份目标值')),
|
|
||||||
('goal_val_11', models.FloatField(verbose_name='11月份目标值')),
|
|
||||||
('goal_val_12', models.FloatField(verbose_name='12月份目标值')),
|
|
||||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='goal_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
|
||||||
('mgroup', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='enm.mgroup', verbose_name='关联工段')),
|
|
||||||
('product', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='enm.product', verbose_name='关联产品')),
|
|
||||||
('team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='enm.team', verbose_name='关联班组')),
|
|
||||||
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='goal_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Generated by Django 3.2.12 on 2023-06-20 09:05
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('enm', '0001_initial'),
|
||||||
|
('mtm', '0001_initial'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='mpoint',
|
||||||
|
name='mgroup',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='mtm.mgroup', verbose_name='所在集合'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='mpoint',
|
||||||
|
name='update_by',
|
||||||
|
field=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='最后编辑人'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='mplog',
|
||||||
|
name='mpoint',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='enm.mpoint', verbose_name='关联测点'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,44 +1,8 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from apps.utils.models import CommonBDModel, BaseModel, CommonADModel, CommonAModel, CommonBModel
|
from apps.utils.models import BaseModel, CommonBModel
|
||||||
|
|
||||||
class Product(CommonAModel):
|
|
||||||
"""
|
|
||||||
产品
|
|
||||||
"""
|
|
||||||
name = models.CharField('名称', max_length=50)
|
|
||||||
code = models.CharField('编号', max_length=50, null=True, blank=True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = '产品'
|
|
||||||
|
|
||||||
class Shift(CommonAModel):
|
|
||||||
"""班次
|
|
||||||
"""
|
|
||||||
name = models.CharField('名称', max_length=50)
|
|
||||||
start_time_o = models.TimeField('开始时间')
|
|
||||||
end_time_o = models.TimeField('结束时间')
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = '班次'
|
|
||||||
|
|
||||||
class Mgroup(CommonBModel):
|
|
||||||
"""测点集
|
|
||||||
"""
|
|
||||||
name = models.CharField('名称', max_length=50)
|
|
||||||
cate = models.CharField('分类', max_length=50, default='section') # section是工段
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = '测点集'
|
|
||||||
|
|
||||||
|
|
||||||
class Team(CommonBModel):
|
class Mpoint(CommonBModel):
|
||||||
"""班组
|
|
||||||
"""
|
|
||||||
name = models.CharField('名称', max_length=50)
|
|
||||||
leader = models.ForeignKey('system.user', verbose_name='班长', on_delete=models.CASCADE)
|
|
||||||
|
|
||||||
|
|
||||||
class Mpoint(CommonBDModel):
|
|
||||||
"""测点
|
"""测点
|
||||||
"""
|
"""
|
||||||
name = models.CharField('测点名称', max_length=50)
|
name = models.CharField('测点名称', max_length=50)
|
||||||
|
@ -47,7 +11,7 @@ class Mpoint(CommonBDModel):
|
||||||
cate = models.CharField('分类', max_length=50, default='elec')
|
cate = models.CharField('分类', max_length=50, default='elec')
|
||||||
ep_monitored = models.ForeignKey('em.equipment', verbose_name='监测哪个设备', related_name='mp_ep_monitored', on_delete=models.SET_NULL, null=True, blank=True)
|
ep_monitored = models.ForeignKey('em.equipment', verbose_name='监测哪个设备', related_name='mp_ep_monitored', on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
ep_belong = models.ForeignKey('em.equipment', verbose_name='属于哪个设备', related_name='mp_ep_belong', on_delete=models.SET_NULL, null=True, blank=True)
|
ep_belong = models.ForeignKey('em.equipment', verbose_name='属于哪个设备', related_name='mp_ep_belong', on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
mgroup = models.ForeignKey('enm.mgroup', verbose_name='所在集合', on_delete=models.SET_NULL, null=True, blank=True)
|
mgroup = models.ForeignKey('mtm.mgroup', verbose_name='所在集合', on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
|
||||||
|
|
||||||
class MpLog(BaseModel):
|
class MpLog(BaseModel):
|
||||||
|
@ -58,42 +22,7 @@ class MpLog(BaseModel):
|
||||||
tag_code = models.CharField('测点编号', max_length=50)
|
tag_code = models.CharField('测点编号', max_length=50)
|
||||||
tag_update = models.DateTimeField('更新时间')
|
tag_update = models.DateTimeField('更新时间')
|
||||||
tag_val = models.FloatField('当前值')
|
tag_val = models.FloatField('当前值')
|
||||||
|
|
||||||
class StLog(CommonADModel):
|
|
||||||
"""
|
|
||||||
停机记录
|
|
||||||
"""
|
|
||||||
mgroup = models.ForeignKey(Mgroup, verbose_name='关联工段', on_delete=models.CASCADE)
|
|
||||||
start_time = models.DateTimeField('停机开始')
|
|
||||||
end_time = models.DateTimeField('停机结束', null=True, blank=True)
|
|
||||||
duration = models.FloatField('停机时长(h)', null=True, blank=True)
|
|
||||||
|
|
||||||
|
|
||||||
class SfLog(CommonADModel):
|
|
||||||
"""值班记录
|
|
||||||
"""
|
|
||||||
mgroup = models.ForeignKey(Mgroup, verbose_name='关联工段', on_delete=models.CASCADE)
|
|
||||||
team = models.ForeignKey(Team, verbose_name='班组', on_delete=models.CASCADE)
|
|
||||||
shift = models.ForeignKey(Shift, verbose_name='当班班次', on_delete=models.CASCADE)
|
|
||||||
leader = models.ForeignKey('system.user', verbose_name='班长', on_delete=models.CASCADE)
|
|
||||||
start_time = models.DateTimeField('值班开始')
|
|
||||||
end_time = models.DateTimeField('值班结束')
|
|
||||||
note = models.TextField('生产情况记录', null=True, blank=True)
|
|
||||||
stlogs = models.ManyToManyField('enm.stlog', verbose_name='关联停机记录', through='enm.stsflog')
|
|
||||||
|
|
||||||
|
|
||||||
class StSfLog(BaseModel):
|
|
||||||
"""
|
|
||||||
停机-值班记录关联表
|
|
||||||
"""
|
|
||||||
stlog = models.ForeignKey(StLog, verbose_name='关联停机记录', on_delete=models.CASCADE)
|
|
||||||
sflog = models.ForeignKey(SfLog, verbose_name='关联值班记录', on_delete=models.CASCADE)
|
|
||||||
is_current_down = models.BooleanField('是否本班停机', default=False)
|
|
||||||
reason = models.TextField('停机原因', null=True, blank=True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
ordering = ['sflog__start_time']
|
|
||||||
|
|
||||||
|
|
||||||
class MpointStat(BaseModel):
|
class MpointStat(BaseModel):
|
||||||
"""测点统计表
|
"""测点统计表
|
||||||
|
@ -104,27 +33,4 @@ class MpointStat(BaseModel):
|
||||||
day = models.PositiveSmallIntegerField('日', null=True, blank=True)
|
day = models.PositiveSmallIntegerField('日', null=True, blank=True)
|
||||||
hour = models.PositiveSmallIntegerField('时', null=True, blank=True)
|
hour = models.PositiveSmallIntegerField('时', null=True, blank=True)
|
||||||
mpoint = models.ForeignKey(Mpoint, verbose_name='关联测点', on_delete=models.CASCADE)
|
mpoint = models.ForeignKey(Mpoint, verbose_name='关联测点', on_delete=models.CASCADE)
|
||||||
val = models.FloatField('统计值', default=0)
|
val = models.FloatField('统计值', default=0)
|
||||||
|
|
||||||
|
|
||||||
class Goal(CommonADModel):
|
|
||||||
"""目标
|
|
||||||
"""
|
|
||||||
mgroup = models.ForeignKey(Mgroup, verbose_name='关联工段', on_delete=models.CASCADE, null=True, blank=True)
|
|
||||||
product = models.ForeignKey(Product, verbose_name='关联产品', on_delete=models.CASCADE, null=True, blank=True)
|
|
||||||
team = models.ForeignKey(Team, verbose_name='关联班组', on_delete=models.CASCADE, null=True, blank=True)
|
|
||||||
year = models.PositiveSmallIntegerField('年')
|
|
||||||
goal_name = models.CharField('目标名称', max_length=50, help_text='总产量/台时产量/单位产品分布电耗/')
|
|
||||||
goal_val = models.FloatField('全年目标值')
|
|
||||||
goal_val_1 = models.FloatField('1月份目标值')
|
|
||||||
goal_val_2 = models.FloatField('2月份目标值')
|
|
||||||
goal_val_3 = models.FloatField('3月份目标值')
|
|
||||||
goal_val_4 = models.FloatField('4月份目标值')
|
|
||||||
goal_val_5 = models.FloatField('5月份目标值')
|
|
||||||
goal_val_6 = models.FloatField('6月份目标值')
|
|
||||||
goal_val_7 = models.FloatField('7月份目标值')
|
|
||||||
goal_val_8 = models.FloatField('8月份目标值')
|
|
||||||
goal_val_9 = models.FloatField('9月份目标值')
|
|
||||||
goal_val_10 = models.FloatField('10月份目标值')
|
|
||||||
goal_val_11 = models.FloatField('11月份目标值')
|
|
||||||
goal_val_12 = models.FloatField('12月份目标值')
|
|
|
@ -1,25 +1,8 @@
|
||||||
from apps.utils.serializers import CustomModelSerializer
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
from apps.enm.models import Mpoint, Mgroup, MpLog, Team, SfLog, StLog, StSfLog
|
from apps.enm.models import Mpoint, MpLog
|
||||||
from apps.system.models import Dept
|
from apps.utils.constants import EXCLUDE_FIELDS
|
||||||
from apps.system.serializers import DeptSimpleSerializer
|
|
||||||
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
class MgroupSerializer(CustomModelSerializer):
|
|
||||||
belong_dept = serializers.PrimaryKeyRelatedField(label="所属部门", queryset=Dept.objects.all(), required=True)
|
|
||||||
belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
|
|
||||||
class Meta:
|
|
||||||
model = Mgroup
|
|
||||||
fields = '__all__'
|
|
||||||
read_only_fields = EXCLUDE_FIELDS
|
|
||||||
|
|
||||||
class TeamSerializer(CustomModelSerializer):
|
|
||||||
leader_name = serializers.CharField(source='leader.name', read_only=True)
|
|
||||||
belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
|
|
||||||
class Meta:
|
|
||||||
model = Team
|
|
||||||
fields = '__all__'
|
|
||||||
read_only_fields = EXCLUDE_FIELDS
|
|
||||||
|
|
||||||
class MpointSerializer(CustomModelSerializer):
|
class MpointSerializer(CustomModelSerializer):
|
||||||
mgroup_name = serializers.CharField(source='mgroup.name', read_only=True)
|
mgroup_name = serializers.CharField(source='mgroup.name', read_only=True)
|
||||||
|
@ -37,39 +20,4 @@ class MpLogSerializer(CustomModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = MpLog
|
model = MpLog
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
read_only_fields = EXCLUDE_FIELDS + ['mpoint_name']
|
read_only_fields = EXCLUDE_FIELDS + ['mpoint_name']
|
||||||
|
|
||||||
|
|
||||||
class StLogSerializer(CustomModelSerializer):
|
|
||||||
mgroup_name = serializers.CharField(source='mgroup.name', read_only=True)
|
|
||||||
class Meta:
|
|
||||||
model = StLog
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
|
|
||||||
class SfLogSerializer(CustomModelSerializer):
|
|
||||||
mgroup_name = serializers.CharField(source='mgroup.name', read_only=True)
|
|
||||||
team_name = serializers.CharField(source='team.name', read_only=True)
|
|
||||||
shift_name = serializers.CharField(source='shift.name', read_only=True)
|
|
||||||
leader_name = serializers.CharField(source='leader.name', read_only=True)
|
|
||||||
class Meta:
|
|
||||||
model = SfLog
|
|
||||||
fields = '__all__'
|
|
||||||
read_only_fields = EXCLUDE_FIELDS
|
|
||||||
update_fields = ['start_time', 'end_time', 'note']
|
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
|
||||||
if hasattr(self.Meta, 'update_fields') and self.context['request'].method in ['PUT', 'PATCH']:
|
|
||||||
u_fields = self.Meta.update_fields
|
|
||||||
new_data = {key: data[key] for key in u_fields if key in data}
|
|
||||||
return super().to_internal_value(new_data)
|
|
||||||
return super().to_internal_value(data)
|
|
||||||
|
|
||||||
|
|
||||||
class StSfLogSerializer(CustomModelSerializer):
|
|
||||||
stlog_ = StLogSerializer(source='stlog', read_only=True)
|
|
||||||
sflog_ = SfLogSerializer(source='sflog', read_only=True)
|
|
||||||
class Meta:
|
|
||||||
model = StSfLog
|
|
||||||
fields = '__all__'
|
|
||||||
read_only_fields = EXCLUDE_FIELDS + ['stlog', 'sflog', 'is_current_down']
|
|
|
@ -103,4 +103,6 @@ def cal_mpointstats(is_now=1):
|
||||||
cal_mpointstat_hour.delay(mpoint.id, now.year, now.moth, now.day, now.hour)
|
cal_mpointstat_hour.delay(mpoint.id, now.year, now.moth, now.day, now.hour)
|
||||||
else:
|
else:
|
||||||
for mpoint in Mpoint.objects.all():
|
for mpoint in Mpoint.objects.all():
|
||||||
cal_mpointstat_hour.delay(mpoint.id, pre.year, pre.month, pre.day, pre.hour)
|
cal_mpointstat_hour.delay(mpoint.id, pre.year, pre.month, pre.day, pre.hour)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
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.enm.views import MpointViewSet, MgroupViewSet, TeamViewSet, MpLogViewSet, SfLogViewSet, StLogViewSet, StSfLogViewSet
|
from apps.enm.views import (MpointViewSet, MpLogViewSet)
|
||||||
|
|
||||||
API_BASE_URL = 'api/enm/'
|
API_BASE_URL = 'api/enm/'
|
||||||
HTML_BASE_URL = 'enm/'
|
HTML_BASE_URL = 'enm/'
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register('mpoint', MpointViewSet, basename='mpoint')
|
router.register('mpoint', MpointViewSet, basename='mpoint')
|
||||||
router.register('mgroup', MgroupViewSet, basename='mgroup')
|
|
||||||
router.register('team', TeamViewSet, basename='team')
|
|
||||||
router.register('mplog', MpLogViewSet, basename='mplog')
|
router.register('mplog', MpLogViewSet, basename='mplog')
|
||||||
router.register('sflog', SfLogViewSet, basename='sflog')
|
|
||||||
router.register('stlog', StLogViewSet, basename='stlog')
|
|
||||||
router.register('stsflog', StSfLogViewSet, basename='stsflog')
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path(API_BASE_URL, include(router.urls)),
|
path(API_BASE_URL, include(router.urls)),
|
||||||
]
|
]
|
|
@ -1,36 +1,8 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from apps.enm.models import Mpoint, Mgroup, Team, MpLog, SfLog, StLog, StSfLog
|
from apps.enm.models import Mpoint, MpLog
|
||||||
from apps.utils.viewsets import CustomModelViewSet, GenericViewSet
|
from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet
|
||||||
from rest_framework.mixins import ListModelMixin, UpdateModelMixin
|
from rest_framework.mixins import ListModelMixin
|
||||||
from apps.enm.serializers import MpointSerializer, TeamSerializer, MgroupSerializer, MpLogSerializer, SfLogSerializer, StLogSerializer, StSfLogSerializer
|
from apps.enm.serializers import (MpointSerializer, MpLogSerializer)
|
||||||
from rest_framework.exceptions import ParseError
|
|
||||||
from django.db import transaction
|
|
||||||
from django.db.models import Q
|
|
||||||
|
|
||||||
class MgroupViewSet(CustomModelViewSet):
|
|
||||||
"""
|
|
||||||
list:测点集
|
|
||||||
|
|
||||||
测点集
|
|
||||||
"""
|
|
||||||
queryset = Mgroup.objects.all()
|
|
||||||
serializer_class = MgroupSerializer
|
|
||||||
select_related_fields = ['create_by', 'belong_dept']
|
|
||||||
filterset_fields = ['belong_dept']
|
|
||||||
search_fields = ['number']
|
|
||||||
|
|
||||||
|
|
||||||
class TeamViewSet(CustomModelViewSet):
|
|
||||||
"""
|
|
||||||
list:班组
|
|
||||||
|
|
||||||
班组
|
|
||||||
"""
|
|
||||||
queryset = Team.objects.all()
|
|
||||||
serializer_class = TeamSerializer
|
|
||||||
select_related_fields = ['belong_dept', 'leader']
|
|
||||||
filterset_fields = ['belong_dept']
|
|
||||||
search_fields = ['name']
|
|
||||||
|
|
||||||
|
|
||||||
class MpointViewSet(CustomModelViewSet):
|
class MpointViewSet(CustomModelViewSet):
|
||||||
|
@ -46,7 +18,7 @@ class MpointViewSet(CustomModelViewSet):
|
||||||
search_fields = ['number', 'code']
|
search_fields = ['number', 'code']
|
||||||
|
|
||||||
|
|
||||||
class MpLogViewSet(ListModelMixin, GenericViewSet):
|
class MpLogViewSet(ListModelMixin, CustomGenericViewSet):
|
||||||
"""
|
"""
|
||||||
list:测点原始记录
|
list:测点原始记录
|
||||||
|
|
||||||
|
@ -55,64 +27,4 @@ class MpLogViewSet(ListModelMixin, GenericViewSet):
|
||||||
queryset = MpLog.objects.all()
|
queryset = MpLog.objects.all()
|
||||||
serializer_class = MpLogSerializer
|
serializer_class = MpLogSerializer
|
||||||
select_related_fields = ['mpoint']
|
select_related_fields = ['mpoint']
|
||||||
filterset_fields = ['mpoint']
|
filterset_fields = ['mpoint']
|
||||||
|
|
||||||
|
|
||||||
class StLogViewSet(ListModelMixin, GenericViewSet):
|
|
||||||
"""
|
|
||||||
list:停机记录
|
|
||||||
|
|
||||||
停机记录
|
|
||||||
"""
|
|
||||||
queryset = StLog.objects.all()
|
|
||||||
serializer_class = StLogSerializer
|
|
||||||
select_related_fields = ['mgroup']
|
|
||||||
filterset_fields = ['mgroup']
|
|
||||||
ordering = ['-start_time']
|
|
||||||
|
|
||||||
|
|
||||||
class SfLogViewSet(CustomModelViewSet):
|
|
||||||
"""
|
|
||||||
list:值班记录
|
|
||||||
|
|
||||||
值班记录
|
|
||||||
"""
|
|
||||||
queryset = SfLog.objects.all()
|
|
||||||
serializer_class = SfLogSerializer
|
|
||||||
select_related_fields = ['mgroup', 'shift', 'team', 'leader']
|
|
||||||
filterset_fields = ['mgroup', 'shift', 'team', 'leader', 'team__belong_dept']
|
|
||||||
search_fields = ['note']
|
|
||||||
|
|
||||||
@transaction.atomic
|
|
||||||
def perform_create(self, serializer):
|
|
||||||
ins = serializer.save()
|
|
||||||
# 查看并比对停机记录
|
|
||||||
stls = StLog.objects.filter(mroup=ins.mgroup)
|
|
||||||
stls_ = (stls.filter(start_time__gte=ins.start_time, start_time__lt=ins.end_time)|
|
|
||||||
stls.exclude(end_time=None).filter(start_time__lte=ins.start_time, end_time__gt=ins.end_time)|
|
|
||||||
stls.exclude(end_time=None).filter(end_time__gte=ins.start_time, end_time__lt=ins.end_time))
|
|
||||||
for i in stls_:
|
|
||||||
StSfLog.objects.get_or_create(stlog=i, sflog=ins, defaults={'stlog': i, 'sflog': ins})
|
|
||||||
stsflog = StSfLog.objects.filter(stlog=i).order_by('-sflog__start_time').first()
|
|
||||||
if stsflog:
|
|
||||||
stsflog.is_current_down = True
|
|
||||||
stsflog.save()
|
|
||||||
|
|
||||||
|
|
||||||
class StSfLogViewSet(ListModelMixin, UpdateModelMixin, GenericViewSet):
|
|
||||||
"""
|
|
||||||
list:值班停机关系
|
|
||||||
|
|
||||||
值班停机关系
|
|
||||||
"""
|
|
||||||
queryset = StSfLog.objects.all()
|
|
||||||
serializer_class = StSfLogSerializer
|
|
||||||
select_related_fields = ['stlog', 'sflog']
|
|
||||||
filterset_fields = ['stlog', 'sflog']
|
|
||||||
search_fields = ['reason']
|
|
||||||
|
|
||||||
def filter_queryset(self, queryset):
|
|
||||||
params = self.request.query_params
|
|
||||||
if 'stlog' not in params or 'sflog' not in params:
|
|
||||||
raise ParseError('请指定所属停机或值班记录')
|
|
||||||
return super().filter_queryset(queryset)
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
|
@ -0,0 +1,6 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class MtmConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'apps.mtm'
|
|
@ -0,0 +1,121 @@
|
||||||
|
# Generated by Django 3.2.12 on 2023-06-20 09:05
|
||||||
|
|
||||||
|
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='Material',
|
||||||
|
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(blank=True, max_length=50, null=True, verbose_name='标识')),
|
||||||
|
('type', models.PositiveSmallIntegerField(choices=[(10, '成品'), (20, '半成品'), (30, '主要原料'), (40, '辅助材料'), (50, '加工工具'), (60, '辅助工装')], default=1, help_text="((10, '成品'), (20, '半成品'), (30, '主要原料'), (40, '辅助材料'), (50, '加工工具'), (60, '辅助工装'))", verbose_name='物料类型')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='material_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('qitems', models.ManyToManyField(blank=True, to='system.Dictionary', verbose_name='质检项目')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='material_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': '物料表',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Team',
|
||||||
|
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='名称')),
|
||||||
|
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='team_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='team_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('leader', models.ForeignKey(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='team_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Shift',
|
||||||
|
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='名称')),
|
||||||
|
('start_time_o', models.TimeField(verbose_name='开始时间')),
|
||||||
|
('end_time_o', models.TimeField(verbose_name='结束时间')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='shift_create_by', 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='shift_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': '班次',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Mgroup',
|
||||||
|
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='名称')),
|
||||||
|
('cate', models.CharField(default='section', help_text='section/other', max_length=50, verbose_name='分类')),
|
||||||
|
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mgroup_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='mgroup_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('product', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='mtm.material', verbose_name='主要产品')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mgroup_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': '测点集',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Goal',
|
||||||
|
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='删除标记')),
|
||||||
|
('year', models.PositiveSmallIntegerField(verbose_name='年')),
|
||||||
|
('goal_val', models.FloatField(verbose_name='全年目标值')),
|
||||||
|
('goal_val_1', models.FloatField(verbose_name='1月份目标值')),
|
||||||
|
('goal_val_2', models.FloatField(verbose_name='2月份目标值')),
|
||||||
|
('goal_val_3', models.FloatField(verbose_name='3月份目标值')),
|
||||||
|
('goal_val_4', models.FloatField(verbose_name='4月份目标值')),
|
||||||
|
('goal_val_5', models.FloatField(verbose_name='5月份目标值')),
|
||||||
|
('goal_val_6', models.FloatField(verbose_name='6月份目标值')),
|
||||||
|
('goal_val_7', models.FloatField(verbose_name='7月份目标值')),
|
||||||
|
('goal_val_8', models.FloatField(verbose_name='8月份目标值')),
|
||||||
|
('goal_val_9', models.FloatField(verbose_name='9月份目标值')),
|
||||||
|
('goal_val_10', models.FloatField(verbose_name='10月份目标值')),
|
||||||
|
('goal_val_11', models.FloatField(verbose_name='11月份目标值')),
|
||||||
|
('goal_val_12', models.FloatField(verbose_name='12月份目标值')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='goal_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('goal_cate', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.dictionary', verbose_name='目标种类')),
|
||||||
|
('mgroup', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.mgroup', verbose_name='关联工段')),
|
||||||
|
('product', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='关联产品')),
|
||||||
|
('team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.team', verbose_name='关联班组')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='goal_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,78 @@
|
||||||
|
from django.db import models
|
||||||
|
from apps.system.models import CommonAModel, Dictionary, CommonBModel, CommonADModel
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
|
class Material(CommonAModel):
|
||||||
|
MA_TYPE_GOOD = 10
|
||||||
|
MA_TYPE_HALFGOOD = 20
|
||||||
|
MA_TYPE_MAINSO = 30
|
||||||
|
MA_TYPE_HELPSO = 40
|
||||||
|
MA_TYPE_TOOL = 50
|
||||||
|
MA_TYPE_HELPTOOL = 60
|
||||||
|
type_choices=(
|
||||||
|
(MA_TYPE_GOOD, '成品'),
|
||||||
|
(MA_TYPE_HALFGOOD, '半成品'),
|
||||||
|
(MA_TYPE_MAINSO, '主要原料'),
|
||||||
|
(MA_TYPE_HELPSO, '辅助材料'),
|
||||||
|
(MA_TYPE_TOOL, '加工工具'),
|
||||||
|
(MA_TYPE_HELPTOOL, '辅助工装')
|
||||||
|
)
|
||||||
|
name = models.CharField('名称', max_length=50)
|
||||||
|
code = models.CharField('标识', max_length=50, null=True, blank=True)
|
||||||
|
type = models.PositiveSmallIntegerField('物料类型', choices= type_choices, default=1, help_text=str(type_choices))
|
||||||
|
qitems = models.ManyToManyField(Dictionary, verbose_name='质检项目', blank=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = '物料表'
|
||||||
|
|
||||||
|
|
||||||
|
class Shift(CommonAModel):
|
||||||
|
"""班次
|
||||||
|
"""
|
||||||
|
name = models.CharField('名称', max_length=50)
|
||||||
|
start_time_o = models.TimeField('开始时间')
|
||||||
|
end_time_o = models.TimeField('结束时间')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = '班次'
|
||||||
|
|
||||||
|
|
||||||
|
class Team(CommonBModel):
|
||||||
|
"""班组
|
||||||
|
"""
|
||||||
|
name = models.CharField('名称', max_length=50)
|
||||||
|
leader = models.ForeignKey('system.user', verbose_name='班长', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
|
class Mgroup(CommonBModel):
|
||||||
|
"""测点集
|
||||||
|
"""
|
||||||
|
name = models.CharField('名称', max_length=50)
|
||||||
|
cate = models.CharField('分类', max_length=50, default='section', help_text='section/other') # section是工段
|
||||||
|
product = models.ForeignKey(Material, verbose_name='主要产品', on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = '测点集'
|
||||||
|
|
||||||
|
|
||||||
|
class Goal(CommonADModel):
|
||||||
|
"""目标
|
||||||
|
"""
|
||||||
|
mgroup = models.ForeignKey(Mgroup, verbose_name='关联工段', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
product = models.ForeignKey(Material, verbose_name='关联产品', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
team = models.ForeignKey(Team, verbose_name='关联班组', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
year = models.PositiveSmallIntegerField('年')
|
||||||
|
goal_cate = models.ForeignKey(Dictionary, verbose_name='目标种类', on_delete=models.CASCADE)
|
||||||
|
goal_val = models.FloatField('全年目标值')
|
||||||
|
goal_val_1 = models.FloatField('1月份目标值')
|
||||||
|
goal_val_2 = models.FloatField('2月份目标值')
|
||||||
|
goal_val_3 = models.FloatField('3月份目标值')
|
||||||
|
goal_val_4 = models.FloatField('4月份目标值')
|
||||||
|
goal_val_5 = models.FloatField('5月份目标值')
|
||||||
|
goal_val_6 = models.FloatField('6月份目标值')
|
||||||
|
goal_val_7 = models.FloatField('7月份目标值')
|
||||||
|
goal_val_8 = models.FloatField('8月份目标值')
|
||||||
|
goal_val_9 = models.FloatField('9月份目标值')
|
||||||
|
goal_val_10 = models.FloatField('10月份目标值')
|
||||||
|
goal_val_11 = models.FloatField('11月份目标值')
|
||||||
|
goal_val_12 = models.FloatField('12月份目标值')
|
|
@ -0,0 +1,34 @@
|
||||||
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
|
from apps.mtm.models import Shift, Material, Mgroup, Team
|
||||||
|
from apps.utils.constants import EXCLUDE_FIELDS
|
||||||
|
from rest_framework import serializers
|
||||||
|
from apps.system.models import Dept
|
||||||
|
|
||||||
|
class ShiftSerializer(CustomModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Shift
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = EXCLUDE_FIELDS
|
||||||
|
|
||||||
|
class MaterialSerializer(CustomModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Material
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = EXCLUDE_FIELDS
|
||||||
|
|
||||||
|
class MgroupSerializer(CustomModelSerializer):
|
||||||
|
belong_dept = serializers.PrimaryKeyRelatedField(label="所属部门", queryset=Dept.objects.all(), required=True)
|
||||||
|
belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = Mgroup
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = EXCLUDE_FIELDS
|
||||||
|
|
||||||
|
class TeamSerializer(CustomModelSerializer):
|
||||||
|
belong_dept = serializers.PrimaryKeyRelatedField(label="所属部门", queryset=Dept.objects.all(), required=True)
|
||||||
|
leader_name = serializers.CharField(source='leader.name', read_only=True)
|
||||||
|
belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = Team
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = EXCLUDE_FIELDS
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
|
@ -0,0 +1,17 @@
|
||||||
|
from django.urls import path, include
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
|
from apps.mtm.views import MgroupViewSet, ShiftViewSet, TeamViewSet, MaterialViewSet
|
||||||
|
|
||||||
|
API_BASE_URL = 'api/mtm/'
|
||||||
|
HTML_BASE_URL = 'mtm/'
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register('mgroup', MgroupViewSet, basename='mgroup')
|
||||||
|
router.register('team', TeamViewSet, basename='team')
|
||||||
|
router.register('material', MaterialViewSet, basename='material')
|
||||||
|
router.register('shift', ShiftViewSet, basename='shift')
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path(API_BASE_URL, include(router.urls)),
|
||||||
|
]
|
|
@ -0,0 +1,57 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
from rest_framework.mixins import ListModelMixin
|
||||||
|
|
||||||
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
||||||
|
from apps.mtm.models import Material, Mgroup, Shift, Team
|
||||||
|
from apps.mtm.serializers import MaterialSerializer, MgroupSerializer, ShiftSerializer, TeamSerializer
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
|
class MaterialViewSet(ListModelMixin, CustomGenericViewSet):
|
||||||
|
"""
|
||||||
|
list:产品
|
||||||
|
|
||||||
|
产品
|
||||||
|
"""
|
||||||
|
queryset = Material.objects.all()
|
||||||
|
serializer_class = MaterialSerializer
|
||||||
|
filterset_fields = ['code']
|
||||||
|
search_fields = ['name', 'code']
|
||||||
|
ordering = ['id']
|
||||||
|
|
||||||
|
|
||||||
|
class ShiftViewSet(ListModelMixin, CustomGenericViewSet):
|
||||||
|
"""
|
||||||
|
list:班次
|
||||||
|
|
||||||
|
班次
|
||||||
|
"""
|
||||||
|
queryset = Shift.objects.all()
|
||||||
|
serializer_class = ShiftSerializer
|
||||||
|
search_fields = ['name']
|
||||||
|
ordering = ['id']
|
||||||
|
|
||||||
|
|
||||||
|
class MgroupViewSet(CustomModelViewSet):
|
||||||
|
"""
|
||||||
|
list:测点集
|
||||||
|
|
||||||
|
测点集
|
||||||
|
"""
|
||||||
|
queryset = Mgroup.objects.all()
|
||||||
|
serializer_class = MgroupSerializer
|
||||||
|
select_related_fields = ['create_by', 'belong_dept']
|
||||||
|
filterset_fields = ['belong_dept']
|
||||||
|
search_fields = ['number']
|
||||||
|
|
||||||
|
|
||||||
|
class TeamViewSet(CustomModelViewSet):
|
||||||
|
"""
|
||||||
|
list:班组
|
||||||
|
|
||||||
|
班组
|
||||||
|
"""
|
||||||
|
queryset = Team.objects.all()
|
||||||
|
serializer_class = TeamSerializer
|
||||||
|
select_related_fields = ['belong_dept', 'leader']
|
||||||
|
filterset_fields = ['belong_dept']
|
||||||
|
search_fields = ['name']
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
|
@ -0,0 +1,6 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class QmConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'apps.qm'
|
|
@ -0,0 +1,60 @@
|
||||||
|
# Generated by Django 3.2.12 on 2023-06-20 09:05
|
||||||
|
|
||||||
|
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 = [
|
||||||
|
('mtm', '0001_initial'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('system', '0002_myschedule'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TestItem',
|
||||||
|
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=100, verbose_name='名称')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='testitem_create_by', 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='testitem_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='QuaStat',
|
||||||
|
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.CharField(default='day', help_text='year/month/day', max_length=50, verbose_name='统计维度')),
|
||||||
|
('year', models.PositiveSmallIntegerField(verbose_name='年')),
|
||||||
|
('month', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='月')),
|
||||||
|
('day', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='日')),
|
||||||
|
('val_avg', models.FloatField(verbose_name='平均值')),
|
||||||
|
('num_test', models.PositiveSmallIntegerField(verbose_name='检测次数')),
|
||||||
|
('num_ok', models.PositiveSmallIntegerField(verbose_name='合格次数')),
|
||||||
|
('rate_pass', models.FloatField(verbose_name='合格率')),
|
||||||
|
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quastat_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='quastat_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='关联产物')),
|
||||||
|
('testitem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qm.testitem', verbose_name='质检项目')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quastat_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,26 @@
|
||||||
|
from django.db import models
|
||||||
|
from apps.system.models import CommonAModel
|
||||||
|
from apps.utils.models import CommonBDModel
|
||||||
|
from apps.mtm.models import Material
|
||||||
|
|
||||||
|
class TestItem(CommonAModel):
|
||||||
|
"""
|
||||||
|
检验项目
|
||||||
|
"""
|
||||||
|
name = models.CharField('名称', max_length=100)
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
|
class QuaStat(CommonBDModel):
|
||||||
|
"""
|
||||||
|
质量数据统计表 需要有belong_dept
|
||||||
|
"""
|
||||||
|
type = models.CharField('统计维度', max_length=50, default='day', help_text='year/month/day')
|
||||||
|
year = models.PositiveSmallIntegerField('年')
|
||||||
|
month = models.PositiveSmallIntegerField('月', null=True, blank=True)
|
||||||
|
day = models.PositiveSmallIntegerField('日', null=True, blank=True)
|
||||||
|
product = models.ForeignKey(Material, verbose_name='关联产物', on_delete=models.CASCADE)
|
||||||
|
testitem = models.ForeignKey(TestItem, verbose_name='质检项目', on_delete=models.CASCADE)
|
||||||
|
val_avg = models.FloatField('平均值')
|
||||||
|
num_test = models.PositiveSmallIntegerField('检测次数')
|
||||||
|
num_ok = models.PositiveSmallIntegerField('合格次数')
|
||||||
|
rate_pass = models.FloatField('合格率')
|
|
@ -0,0 +1,24 @@
|
||||||
|
from apps.qm.models import QuaStat, TestItem
|
||||||
|
from apps.utils.constants import EXCLUDE_FIELDS
|
||||||
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
|
from rest_framework import serializers
|
||||||
|
from apps.system.models import Dept, Dictionary
|
||||||
|
|
||||||
|
class TestItemSerializer(CustomModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = TestItem
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = EXCLUDE_FIELDS
|
||||||
|
|
||||||
|
class QuaStatSerializer(CustomModelSerializer):
|
||||||
|
year = serializers.IntegerField(label='年', required=True)
|
||||||
|
month = serializers.IntegerField(label='月', required=True)
|
||||||
|
day = serializers.IntegerField(label='天', required=True)
|
||||||
|
belong_dept = serializers.PrimaryKeyRelatedField(label="所属部门", queryset=Dept.objects.all(), required=True)
|
||||||
|
belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
|
||||||
|
product_name = serializers.CharField(source='product.name', read_only=True)
|
||||||
|
qitem_name = serializers.CharField(source='qitem.name', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = QuaStat
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = EXCLUDE_FIELDS + ['type', 'rate_pass']
|
|
@ -0,0 +1,73 @@
|
||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
from celery import shared_task
|
||||||
|
from apps.qm.models import QuaStat
|
||||||
|
from apps.utils.tasks import CustomTask
|
||||||
|
from django.db.models import Sum, F, ExpressionWrapper, FloatField
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task(base=CustomTask)
|
||||||
|
def cal_quastat(quastatId: str):
|
||||||
|
# 可以直接使用sql语言
|
||||||
|
# query = """
|
||||||
|
# SELECT field1, SUM(field2 * field3) AS field2_field3_sum, SUM(field1) AS field1_sum,
|
||||||
|
# SUM(field2 * field3) / SUM(field1) AS result
|
||||||
|
# FROM your_table_name
|
||||||
|
# GROUP BY field1
|
||||||
|
# """
|
||||||
|
ins = QuaStat.objects.get(id=quastatId)
|
||||||
|
# 月统计
|
||||||
|
params = {
|
||||||
|
'testitem': ins.testitem,
|
||||||
|
'product': ins.product,
|
||||||
|
'belong_dept': ins.belong_dept,
|
||||||
|
'year': ins.year,
|
||||||
|
'month': ins.month
|
||||||
|
}
|
||||||
|
results_month = QuaStat.objects.filter(**params).values('belong_dept', 'product',
|
||||||
|
'testitem', 'year', 'month').annotate(
|
||||||
|
avg_val_total=Sum(F('avg_val')*F('num_test')),
|
||||||
|
num_test_1=Sum('num_test'),
|
||||||
|
num_ok_1=Sum('num_ok')).annotate(
|
||||||
|
avg_val_1=ExpressionWrapper(F('avg_val_total')/F('num_test_1'), output_field=FloatField()),
|
||||||
|
rate_pass_1=ExpressionWrapper(F('num_ok_1')/F('num_test_1'), output_field=FloatField())
|
||||||
|
)
|
||||||
|
for r1 in results_month:
|
||||||
|
stat_params = {
|
||||||
|
'avg_val': r1['avg_val_1'],
|
||||||
|
'num_test': r1['num_test_1'],
|
||||||
|
'num_ok': r1['num_ok_1'],
|
||||||
|
'rate_pass': r1['rate_pass_1']
|
||||||
|
}
|
||||||
|
qua, is_created = QuaStat.objects.get_or_create(
|
||||||
|
**params, **{'type': 'month'}, defaults={**params, **{'type': 'month'}, **stat_params}
|
||||||
|
)
|
||||||
|
if not is_created:
|
||||||
|
for k in stat_params:
|
||||||
|
setattr(qua, k, stat_params[k])
|
||||||
|
qua.save()
|
||||||
|
|
||||||
|
# 年统计
|
||||||
|
params.pop('month')
|
||||||
|
|
||||||
|
results_year = QuaStat.objects.filter(**params).values('belong_dept', 'product',
|
||||||
|
'testitem', 'year').annotate(
|
||||||
|
avg_val_total=Sum(F('avg_val')*F('num_test')),
|
||||||
|
num_test_1=Sum('num_test'),
|
||||||
|
num_ok_1=Sum('num_ok')).annotate(
|
||||||
|
avg_val_1=ExpressionWrapper(F('avg_val_total')/F('num_test_1'), output_field=FloatField()),
|
||||||
|
rate_pass_1=ExpressionWrapper(F('num_ok_1')/F('num_test_1'), output_field=FloatField())
|
||||||
|
)
|
||||||
|
for r1 in results_year:
|
||||||
|
stat_params = {
|
||||||
|
'avg_val': r1['avg_val_1'],
|
||||||
|
'num_test': r1['num_test_1'],
|
||||||
|
'num_ok': r1['num_ok_1'],
|
||||||
|
'rate_pass': r1['rate_pass_1']
|
||||||
|
}
|
||||||
|
qua, is_created = QuaStat.objects.get_or_create(
|
||||||
|
**params, **{'type': 'year'}, defaults={**params, **{'type': 'year'}, **stat_params}
|
||||||
|
)
|
||||||
|
if not is_created:
|
||||||
|
for k in stat_params:
|
||||||
|
setattr(qua, k, stat_params[k])
|
||||||
|
qua.save()
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
|
@ -0,0 +1,14 @@
|
||||||
|
from django.urls import path, include
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
|
from apps.qm.views import QuaStatViewSet, TestItemViewSet
|
||||||
|
|
||||||
|
API_BASE_URL = 'api/qm/'
|
||||||
|
HTML_BASE_URL = 'qm/'
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register('quastat', QuaStatViewSet, basename='quastat')
|
||||||
|
router.register('testitem', TestItemViewSet, basename='testitem')
|
||||||
|
urlpatterns = [
|
||||||
|
path(API_BASE_URL, include(router.urls)),
|
||||||
|
]
|
|
@ -0,0 +1,37 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
from rest_framework.mixins import ListModelMixin, CreateModelMixin
|
||||||
|
from apps.qm.models import QuaStat, TestItem
|
||||||
|
from apps.qm.serializers import QuaStatSerializer, TestItemSerializer
|
||||||
|
from apps.qm.tasks import cal_quastat
|
||||||
|
|
||||||
|
from apps.utils.viewsets import CustomGenericViewSet
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
|
class TestItemViewSet(ListModelMixin, CustomGenericViewSet):
|
||||||
|
"""
|
||||||
|
list:质检项目
|
||||||
|
|
||||||
|
质检项目
|
||||||
|
"""
|
||||||
|
queryset = TestItem.objects.all()
|
||||||
|
serializer_class = TestItemSerializer
|
||||||
|
filterset_fields = []
|
||||||
|
ordering = ['id']
|
||||||
|
|
||||||
|
class QuaStatViewSet(ListModelMixin, CreateModelMixin, CustomGenericViewSet):
|
||||||
|
"""
|
||||||
|
list:质量分析报告
|
||||||
|
|
||||||
|
质量分析报告
|
||||||
|
"""
|
||||||
|
queryset = QuaStat.objects.all()
|
||||||
|
serializer_class = QuaStatSerializer
|
||||||
|
filterset_fields = ['type', 'year', 'month', 'day', 'product', 'testitem', 'belong_dept']
|
||||||
|
select_related_fields = ['belong_dept', 'product', 'testitem']
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
ins = serializer.save()
|
||||||
|
ins.rate_pass = ins.num_ok/ ins.num_test
|
||||||
|
ins.save()
|
||||||
|
# 计算月和年的统计
|
||||||
|
cal_quastat.delay(ins.id)
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
|
@ -0,0 +1,6 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class WpmConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'apps.wpm'
|
|
@ -0,0 +1,88 @@
|
||||||
|
# Generated by Django 3.2.12 on 2023-06-20 09:05
|
||||||
|
|
||||||
|
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 = [
|
||||||
|
('mtm', '0001_initial'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SfLog',
|
||||||
|
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='删除标记')),
|
||||||
|
('start_time', models.DateTimeField(verbose_name='值班开始')),
|
||||||
|
('end_time', models.DateTimeField(verbose_name='值班结束')),
|
||||||
|
('note', models.TextField(blank=True, null=True, verbose_name='其他备注')),
|
||||||
|
('qua_data', models.JSONField(blank=True, null=True, verbose_name='质检数据')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sflog_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('leader', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='班长')),
|
||||||
|
('mgroup', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.mgroup', verbose_name='关联工段')),
|
||||||
|
('shift', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.shift', verbose_name='当班班次')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='StLog',
|
||||||
|
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='删除标记')),
|
||||||
|
('start_time', models.DateTimeField(verbose_name='停机开始')),
|
||||||
|
('end_time', models.DateTimeField(blank=True, null=True, verbose_name='停机结束')),
|
||||||
|
('duration', models.FloatField(blank=True, null=True, verbose_name='停机时长(h)')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stlog_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('mgroup', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.mgroup', verbose_name='关联工段')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stlog_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='StSfLog',
|
||||||
|
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='删除标记')),
|
||||||
|
('is_current_down', models.BooleanField(default=False, verbose_name='是否本班停机')),
|
||||||
|
('reason', models.TextField(blank=True, null=True, verbose_name='停机原因')),
|
||||||
|
('sflog', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.sflog', verbose_name='关联值班记录')),
|
||||||
|
('stlog', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.stlog', verbose_name='关联停机记录')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ['sflog__start_time'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='sflog',
|
||||||
|
name='stlogs',
|
||||||
|
field=models.ManyToManyField(through='wpm.StSfLog', to='wpm.StLog', verbose_name='关联停机记录'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='sflog',
|
||||||
|
name='team',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.team', verbose_name='班组'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='sflog',
|
||||||
|
name='update_by',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sflog_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,40 @@
|
||||||
|
from django.db import models
|
||||||
|
from apps.system.models import CommonADModel, BaseModel
|
||||||
|
from apps.mtm.models import Mgroup, Team, Shift
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
|
class StLog(CommonADModel):
|
||||||
|
"""
|
||||||
|
停机记录
|
||||||
|
"""
|
||||||
|
mgroup = models.ForeignKey(Mgroup, verbose_name='关联工段', on_delete=models.CASCADE)
|
||||||
|
start_time = models.DateTimeField('停机开始')
|
||||||
|
end_time = models.DateTimeField('停机结束', null=True, blank=True)
|
||||||
|
duration = models.FloatField('停机时长(h)', null=True, blank=True)
|
||||||
|
|
||||||
|
|
||||||
|
class SfLog(CommonADModel):
|
||||||
|
"""值班记录
|
||||||
|
"""
|
||||||
|
mgroup = models.ForeignKey(Mgroup, verbose_name='关联工段', on_delete=models.CASCADE)
|
||||||
|
team = models.ForeignKey(Team, verbose_name='班组', on_delete=models.CASCADE)
|
||||||
|
shift = models.ForeignKey(Shift, verbose_name='当班班次', on_delete=models.CASCADE)
|
||||||
|
leader = models.ForeignKey('system.user', verbose_name='班长', on_delete=models.CASCADE)
|
||||||
|
start_time = models.DateTimeField('值班开始')
|
||||||
|
end_time = models.DateTimeField('值班结束')
|
||||||
|
note = models.TextField('其他备注', null=True, blank=True)
|
||||||
|
stlogs = models.ManyToManyField('wpm.stlog', verbose_name='关联停机记录', through='wpm.stsflog')
|
||||||
|
qua_data = models.JSONField('质检数据', null=True, blank=True)
|
||||||
|
|
||||||
|
|
||||||
|
class StSfLog(BaseModel):
|
||||||
|
"""
|
||||||
|
停机-值班记录关联表
|
||||||
|
"""
|
||||||
|
stlog = models.ForeignKey(StLog, verbose_name='关联停机记录', on_delete=models.CASCADE)
|
||||||
|
sflog = models.ForeignKey(SfLog, verbose_name='关联值班记录', on_delete=models.CASCADE)
|
||||||
|
is_current_down = models.BooleanField('是否本班停机', default=False)
|
||||||
|
reason = models.TextField('停机原因', null=True, blank=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['sflog__start_time']
|
|
@ -0,0 +1,52 @@
|
||||||
|
from apps.utils.constants import EXCLUDE_FIELDS
|
||||||
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from apps.wpm.models import SfLog, StLog, StSfLog
|
||||||
|
from apps.system.models import Dictionary
|
||||||
|
|
||||||
|
class StLogSerializer(CustomModelSerializer):
|
||||||
|
mgroup_name = serializers.CharField(source='mgroup.name', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = StLog
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class SfLogSerializer(CustomModelSerializer):
|
||||||
|
mgroup_name = serializers.CharField(source='mgroup.name', read_only=True)
|
||||||
|
team_name = serializers.CharField(source='team.name', read_only=True)
|
||||||
|
shift_name = serializers.CharField(source='shift.name', read_only=True)
|
||||||
|
leader_name = serializers.CharField(source='leader.name', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = SfLog
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = EXCLUDE_FIELDS + ['leader', 'qua_data']
|
||||||
|
update_fields = ['start_time', 'end_time', 'note']
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
attrs['leader'] = attrs['mgroup'].leader
|
||||||
|
return super().validate(attrs)
|
||||||
|
|
||||||
|
def to_internal_value(self, data):
|
||||||
|
if hasattr(self.Meta, 'update_fields') and self.context['request'].method in ['PUT', 'PATCH']:
|
||||||
|
u_fields = self.Meta.update_fields
|
||||||
|
new_data = {key: data[key] for key in u_fields if key in data}
|
||||||
|
return super().to_internal_value(new_data)
|
||||||
|
return super().to_internal_value(data)
|
||||||
|
|
||||||
|
|
||||||
|
class StSfLogSerializer(CustomModelSerializer):
|
||||||
|
stlog_ = StLogSerializer(source='stlog', read_only=True)
|
||||||
|
sflog_ = SfLogSerializer(source='sflog', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = StSfLog
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = EXCLUDE_FIELDS + ['stlog', 'sflog', 'is_current_down']
|
||||||
|
|
||||||
|
class QItemDataSerializer(serializers.Serializer):
|
||||||
|
qitem = serializers.PrimaryKeyRelatedField(label='检测项目', queryset=Dictionary.objects.filter(type__code='qitem'))
|
||||||
|
val = serializers.FloatField(label='值')
|
||||||
|
|
||||||
|
|
||||||
|
class SfLogQuaSerializer(serializers.Serializer):
|
||||||
|
qua_data = QItemDataSerializer(many=True)
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
|
@ -0,0 +1,17 @@
|
||||||
|
from django.urls import path, include
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
|
from apps.wpm.views import SfLogViewSet, StLogViewSet, StSfLogViewSet
|
||||||
|
|
||||||
|
|
||||||
|
API_BASE_URL = 'api/wpm/'
|
||||||
|
HTML_BASE_URL = 'wpm/'
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register('sflog', SfLogViewSet, basename='sflog')
|
||||||
|
router.register('stlog', StLogViewSet, basename='stlog')
|
||||||
|
router.register('stsflog', StSfLogViewSet, basename='stsflog')
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path(API_BASE_URL, include(router.urls)),
|
||||||
|
]
|
|
@ -0,0 +1,88 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
from rest_framework.mixins import ListModelMixin, UpdateModelMixin
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from django.db import transaction
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.exceptions import ParseError
|
||||||
|
|
||||||
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
||||||
|
from apps.wpm.models import SfLog, StLog, StSfLog
|
||||||
|
from apps.wpm.serializers import SfLogQuaSerializer, SfLogSerializer, StLogSerializer, StSfLogSerializer
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
|
class StLogViewSet(ListModelMixin, CustomGenericViewSet):
|
||||||
|
"""
|
||||||
|
list:停机记录
|
||||||
|
|
||||||
|
停机记录
|
||||||
|
"""
|
||||||
|
queryset = StLog.objects.all()
|
||||||
|
serializer_class = StLogSerializer
|
||||||
|
select_related_fields = ['mgroup']
|
||||||
|
filterset_fields = ['mgroup']
|
||||||
|
ordering = ['-start_time']
|
||||||
|
|
||||||
|
|
||||||
|
class SfLogViewSet(CustomModelViewSet):
|
||||||
|
"""
|
||||||
|
list:值班记录
|
||||||
|
|
||||||
|
值班记录
|
||||||
|
"""
|
||||||
|
queryset = SfLog.objects.all()
|
||||||
|
serializer_class = SfLogSerializer
|
||||||
|
select_related_fields = ['mgroup', 'shift', 'team', 'leader']
|
||||||
|
filterset_fields = ['mgroup', 'shift', 'team', 'leader', 'team__belong_dept']
|
||||||
|
search_fields = ['note']
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
ins = serializer.save()
|
||||||
|
# 查看并比对停机记录
|
||||||
|
stls = StLog.objects.filter(mroup=ins.mgroup)
|
||||||
|
stls_ = (stls.filter(start_time__gte=ins.start_time, start_time__lt=ins.end_time)|
|
||||||
|
stls.exclude(end_time=None).filter(start_time__lte=ins.start_time, end_time__gt=ins.end_time)|
|
||||||
|
stls.exclude(end_time=None).filter(end_time__gte=ins.start_time, end_time__lt=ins.end_time))
|
||||||
|
for i in stls_:
|
||||||
|
StSfLog.objects.get_or_create(stlog=i, sflog=ins, defaults={'stlog': i, 'sflog': ins})
|
||||||
|
stsflog = StSfLog.objects.filter(stlog=i).order_by('-sflog__start_time').first()
|
||||||
|
if stsflog:
|
||||||
|
stsflog.is_current_down = True
|
||||||
|
stsflog.save()
|
||||||
|
|
||||||
|
@action(methods=['put'], detail=True, perms_map={'put': 'sflogqua.update'}, serializer_class=SfLogQuaSerializer)
|
||||||
|
def qua_data(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
质量数据录入
|
||||||
|
|
||||||
|
质量数据录入
|
||||||
|
"""
|
||||||
|
sflog = self.get_object()
|
||||||
|
sr = SfLogQuaSerializer(data=request.data)
|
||||||
|
sr.is_valid(raise_exception=True)
|
||||||
|
vdata = sr.validated_data
|
||||||
|
qua_data = vdata['qua_data']
|
||||||
|
qua_data_new = []
|
||||||
|
for i in qua_data:
|
||||||
|
qua_data_new.append({'qitem': i['qitem'].id, 'qitem_name': i['qitem'].name, 'val': i['val']})
|
||||||
|
sflog.qua_data = qua_data_new
|
||||||
|
sflog.save()
|
||||||
|
return Response()
|
||||||
|
|
||||||
|
class StSfLogViewSet(ListModelMixin, UpdateModelMixin, CustomGenericViewSet):
|
||||||
|
"""
|
||||||
|
list:值班停机关系
|
||||||
|
|
||||||
|
值班停机关系
|
||||||
|
"""
|
||||||
|
queryset = StSfLog.objects.all()
|
||||||
|
serializer_class = StSfLogSerializer
|
||||||
|
select_related_fields = ['stlog', 'sflog']
|
||||||
|
filterset_fields = ['stlog', 'sflog']
|
||||||
|
search_fields = ['reason']
|
||||||
|
|
||||||
|
def filter_queryset(self, queryset):
|
||||||
|
params = self.request.query_params
|
||||||
|
if 'stlog' not in params or 'sflog' not in params:
|
||||||
|
raise ParseError('请指定所属停机或值班记录')
|
||||||
|
return super().filter_queryset(queryset)
|
|
@ -98,6 +98,9 @@ INSTALLED_APPS = [
|
||||||
'apps.opm',
|
'apps.opm',
|
||||||
'apps.bi',
|
'apps.bi',
|
||||||
'apps.em',
|
'apps.em',
|
||||||
|
'apps.mtm',
|
||||||
|
'apps.wpm',
|
||||||
|
'apps.qm',
|
||||||
'apps.enm'
|
'apps.enm'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,9 @@ urlpatterns = [
|
||||||
path('', include('apps.vm.urls')),
|
path('', include('apps.vm.urls')),
|
||||||
path('', include('apps.bi.urls')),
|
path('', include('apps.bi.urls')),
|
||||||
path('', include('apps.em.urls')),
|
path('', include('apps.em.urls')),
|
||||||
|
path('', include('apps.mtm.urls')),
|
||||||
|
path('', include('apps.wpm.urls')),
|
||||||
|
path('', include('apps.qm.urls')),
|
||||||
path('', include('apps.enm.urls')),
|
path('', include('apps.enm.urls')),
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue