This commit is contained in:
zty 2024-12-13 15:29:13 +08:00
commit e331002538
18 changed files with 201 additions and 28 deletions

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.12 on 2024-12-11 09:36
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('enm', '0049_enstat_ammonia_consume'),
]
operations = [
migrations.AddField(
model_name='mpoint',
name='is_rep_ep0_running_state',
field=models.BooleanField(default=False, verbose_name='是否表示所属设备运行状态'),
),
]

View File

@ -41,6 +41,7 @@ class Mpoint(CommonBModel):
third_info = models.JSONField("第三方信息", default=dict, blank=True)
# {"from": "king", "n": "某名称","d": "某描述或备注","g": "某组", "t": "某类型", "id": 5001, "o": "其他信息"}
enp_field = models.CharField("关联enp采集字段", max_length=50, null=True, blank=True)
is_rep_ep0_running_state = models.BooleanField("是否表示所属设备运行状态", default=False)
is_rep_ep_running_state = models.BooleanField("是否表示所监测设备运行状态", default=False)
ep_monitored = models.ForeignKey("em.equipment", verbose_name="所监测设备", related_name="mp_ep_monitored", on_delete=models.SET_NULL, null=True, blank=True)
ep_rs_val = models.FloatField("状态量基准值", null=True, blank=True)

View File

@ -223,9 +223,10 @@ class MpointCache:
# 下面开始更新设备信号
ep_belong_id = current_cache_val.get("ep_belong")
ep_monitored_id = current_cache_val.get("ep_monitored")
if ep_monitored_id and mpoint_is_rep_ep_running_state and ep_belong_id != ep_monitored_id:
mpoint_is_rep_ep0_running_state = current_cache_val.get("is_rep_ep0_running_state", False)
if ep_monitored_id and mpoint_is_rep_ep_running_state:
set_eq_rs(ep_monitored_id, last_timex, last_mrs)
if ep_belong_id:
if ep_belong_id and mpoint_is_rep_ep0_running_state and ep_belong_id != ep_monitored_id:
set_eq_rs(ep_belong_id, last_timex, Equipment.RUNING)
mf_code = current_cache_val.get("mpoint_affect")

View File

@ -11,6 +11,7 @@ class MaterialFilter(filters.FilterSet):
fields = {
"id": ["exact", "in"],
"cate": ["exact", "in"],
"code": ["exact", "in", "isnull"],
"type": ["exact", "in"],
"is_hidden": ["exact"],
"is_assemb": ["exact"],

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.12 on 2024-12-12 03:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0043_srule'),
]
operations = [
migrations.AddField(
model_name='mgroup',
name='code',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='标识'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.12 on 2024-12-12 07:16
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0044_mgroup_code'),
]
operations = [
migrations.AddField(
model_name='process',
name='type',
field=models.PositiveSmallIntegerField(choices=[(10, '生产工序'), (20, '检验工序')], default=10, verbose_name='工序类型'),
),
]

View File

@ -8,8 +8,10 @@ class Process(CommonBModel):
"""
工序
"""
PRO_PROD = 10
RPO_TEST = 20
name = models.CharField('工序名称', max_length=100)
type = models.PositiveSmallIntegerField("工序类型", default=PRO_PROD, choices=((PRO_PROD, '生产工序'), (RPO_TEST, '检验工序')))
cate = models.CharField('大类', max_length=10, default='')
sort = models.PositiveSmallIntegerField('排序', default=1)
instruction = models.ForeignKey(
@ -118,6 +120,7 @@ class Mgroup(CommonBModel):
"""
name = models.CharField('名称', max_length=50)
code = models.CharField('标识', max_length=50, null=True, blank=True)
cate = models.CharField(
'分类', max_length=50, default='section', help_text='section/other') # section是工段
shift_rule = models.CharField('班次规则', max_length=10, default='默认')

View File

@ -59,6 +59,7 @@ class MgroupSerializer(CustomModelSerializer):
belong_dept_name = serializers.CharField(
source='belong_dept.name', read_only=True)
process_name = serializers.CharField(source='process.name', read_only=True)
process_type = serializers.CharField(source='process.type', read_only=True)
process_cate = serializers.CharField(source='process.cate', read_only=True)
class Meta:

View File

@ -102,7 +102,8 @@ class MgroupViewSet(CustomModelViewSet):
"process": ["exact"],
"cate": ["exact"],
"belong_dept__name": ["exact", "contains"],
"name": ["exact", "contains"]
"name": ["exact", "contains"],
"code": ["exact", "in", "isnull"]
}
search_fields = ['name']
ordering = ['sort', 'create_time']

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.12 on 2024-12-12 06:39
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('wf', '0002_alter_state_filter_dept'),
('qm', '0026_auto_20241121_1044'),
]
operations = [
migrations.AddField(
model_name='ftestwork',
name='ticket',
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ftestwork_ticket', to='wf.ticket', verbose_name='关联工单'),
),
]

View File

@ -152,6 +152,9 @@ class FtestWork(CommonBDModel):
submit_user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='提交人', null=True, blank=True)
note = models.TextField('备注', null=True, blank=True)
equipment = models.ForeignKey(Equipment, verbose_name='所属检验设备', on_delete=models.SET_NULL, null=True, blank=True)
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单',
on_delete=models.SET_NULL, related_name='ftestwork_ticket', null=True, blank=True,
db_constraint=False)
@classmethod
def count_fields(cls):

View File

@ -6,6 +6,18 @@ from django.utils import timezone
from apps.wf.models import Ticket
from apps.qm.models import NotOkOption
def ftestwork_submit_validate(ins: FtestWork):
wm:WMaterial = ins.wm
if ins.need_update_wm:
if wm.state == WMaterial.WM_TEST:
xcount = wm.count - ins.count
if xcount < 0:
raise ParseError("超过待检数量")
else:
xcount = wm.count - ins.count_notok
if xcount < 0:
raise ParseError("不合格数不可大于批次数量")
def ftestwork_submit(ins:FtestWork, user: User):
wm:WMaterial = ins.wm
@ -83,4 +95,22 @@ def ftestwork_submit(ins:FtestWork, user: User):
ins.save()
def bind_ftestwork(ticket: Ticket, transition, new_ticket_data: dict):
pass
ins = FtestWork.objects.get(id=new_ticket_data['t_id'])
if ins.submit_time is not None:
raise ParseError('该检验工作不可提交审批')
ftestwork_submit_validate(ins)
ticket_data = ticket.ticket_data
ticket_data.update({
't_model': 'ftestwork',
't_id': ins.id,
})
ticket.ticket_data = ticket_data
ticket.create_by = ins.create_by
ticket.save()
if ins.ticket is None:
ins.ticket = ticket
ins.save()
def ftestwork_audit_end(ticket: Ticket):
ins = FtestWork.objects.get(id=ticket.ticket_data['t_id'])
ftestwork_submit(ins, ticket.create_by)

View File

@ -0,0 +1,43 @@
# Generated by Django 3.2.12 on 2024-12-13 04:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0005_alter_permission_type'),
]
operations = [
migrations.AddField(
model_name='permission',
name='component',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='组件'),
),
migrations.AddField(
model_name='permission',
name='icon',
field=models.CharField(blank=True, max_length=30, null=True, verbose_name='图标'),
),
migrations.AddField(
model_name='permission',
name='is_fullpage',
field=models.BooleanField(default=False, verbose_name='是否全屏'),
),
migrations.AddField(
model_name='permission',
name='is_hidden',
field=models.BooleanField(default=False, verbose_name='是否隐藏'),
),
migrations.AddField(
model_name='permission',
name='path',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='路由'),
),
migrations.AddField(
model_name='permission',
name='route_name',
field=models.CharField(blank=True, max_length=30, null=True, verbose_name='路由名称'),
),
]

View File

@ -30,6 +30,13 @@ class Permission(ParentModel, BaseModel):
'类型', choices=menu_type_choices, default=30)
sort = models.PositiveSmallIntegerField('排序标记', default=1)
codes = models.JSONField('权限标识', default=list, null=True, blank=True)
route_name = models.CharField('路由名称', max_length=30, null=True, blank=True)
icon = models.CharField('图标', max_length=30, null=True, blank=True)
path = models.CharField('路由', max_length=100, null=True, blank=True)
component = models.CharField('组件', max_length=100, null=True, blank=True)
is_hidden = models.BooleanField('是否隐藏', default=False)
is_fullpage = models.BooleanField('是否全屏', default=False)
def __str__(self):
return self.name

View File

@ -17,6 +17,7 @@ from apps.third.tapis import dhapis
from rest_framework.validators import UniqueValidator
from django.conf import settings
from django.db.models import Q
from apps.utils.permission import get_user_perms_map
# from django_q.models import Task as QTask, Schedule as QSchedule
@ -334,6 +335,23 @@ class UserUpdateSerializer(CustomModelSerializer):
return super().update(instance, validated_data)
class UserFullInfoSerializer(CustomModelSerializer):
"""
用户信息序列化
"""
perms = serializers.SerializerMethodField()
belong_dept_name = serializers.CharField(source="belong_dept.name", read_only=True)
post_name = serializers.CharField(source="post.name", read_only=True)
class Meta:
model = User
fields = ['id', 'username', 'type', 'name', 'avatar', 'belong_dept',
'belong_dept_name', 'post', 'post_name', 'perms',
'is_superuser', 'wxmp_openid', 'wx_openid']
def get_perms(self, obj):
return get_user_perms_map(obj, update_cache=True)
class UserCreateSerializer(CustomModelSerializer):
"""
创建用户序列化

View File

@ -22,7 +22,7 @@ from apps.system.filters import DeptFilterSet, UserFilterSet
# from django_q.models import Task as QTask, Schedule as QSchedule
from apps.utils.mixins import (CustomCreateModelMixin, MyLoggingMixin)
from django.conf import settings
from apps.utils.permission import ALL_PERMS, get_user_perms_map
from apps.utils.permission import ALL_PERMS
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from server.celery import app as celery_app
from .models import (Dept, Dictionary, DictType, File, Permission, Post, PostRole, Role, User,
@ -35,7 +35,8 @@ from .serializers import (ApkSerializer, DeptCreateUpdateSerializer, DeptSeriali
PTaskSerializer, PTaskCreateUpdateSerializer, PTaskResultSerializer,
RoleCreateUpdateSerializer, RoleSerializer, TaskRunSerializer,
UserCreateSerializer, UserListSerializer, UserPostCreateSerializer,
UserPostSerializer, UserUpdateSerializer, MyScheduleCreateSerializer, MyScheduleSerializer)
UserPostSerializer, UserUpdateSerializer, UserFullInfoSerializer,
MyScheduleCreateSerializer, MyScheduleSerializer)
from rest_framework.viewsets import GenericViewSet
from cron_descriptor import get_description
import locale
@ -541,24 +542,7 @@ class UserViewSet(CustomModelViewSet):
获取登录用户信息
"""
user = request.user
perms = get_user_perms_map(user, update_cache=True)
data = {
'id': user.id,
'username': user.username,
'type': user.type,
'name': user.name,
'roles': user.roles.values_list('name', flat=True),
'avatar': user.avatar,
'perms': perms,
'belong_dept': user.belong_dept.id if user.belong_dept else None,
'post': user.post.id if user.post else None,
'belong_dept_name': user.belong_dept.name if user.belong_dept else '',
'post_name': user.post.name if user.post else '',
'is_superuser': user.is_superuser,
'wxmp_openid': user.wxmp_openid,
'wx_openid': user.wx_openid
}
return Response(data)
return Response(UserFullInfoSerializer(user).data)
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
def bind_wxmp(self, request, pk=None):

View File

@ -68,7 +68,7 @@ def get_team_x(sflog: SfLog):
teamId_list_len = len(teamId_list)
for i in range(len(rule_compare)-teamId_list_len+1):
if rule_compare[i:i+teamId_list_len] == teamId_list:
teamId = rule_compare[i+teamId_list_len+1]
teamId = rule_compare[i+teamId_list_len]
team = Team.objects.filter(id=teamId).first()
return team
return None
@ -86,7 +86,10 @@ def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.da
end_time = datetime.datetime.combine(current_date, end_time_o)
# 以下代码是解决跨天排班时生成当天班次缺少的bug
if start_time > end_time:
end_time += datetime.timedelta(days=1)
if end_time.hour == 0:
end_time += datetime.timedelta(days=1)
else:
start_time -= datetime.timedelta(days=1)
total_sec = (end_time - start_time).total_seconds()
# 创建SfLog记录
@ -105,7 +108,7 @@ def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.da
if team:
sflog.team = team
sflog.leader = team.leader
sflog.save(update_fields=['team'])
sflog.save()
current_date = current_date + datetime.timedelta(days=1)

View File

@ -94,6 +94,9 @@ def cal_exp_duration_sec(stlogId: str='', all=False, now: datetime=None):
end_time__lte=st_end) | sf_qs.filter(start_time__lte=st_start, end_time__gte=st_end)).order_by('start_time').distinct()
SfLogExp.objects.filter(stlog=stlog).exclude(sflog__in=sf_qs).delete()
for ind, sflog in enumerate(sf_qs):
if ind == 0:
stlog.sflog = sflog
stlog.save()
sflogexp, _ = SfLogExp.objects.get_or_create(stlog=stlog, sflog=sflog, defaults={
'stlog': stlog, 'sflog': sflog})
# 计算duration