Merge branch 'master' of https://e.coding.net/ctcdevteam/ehs/ehs_server
This commit is contained in:
commit
e331002538
|
@ -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='是否表示所属设备运行状态'),
|
||||
),
|
||||
]
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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"],
|
||||
|
|
|
@ -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='标识'),
|
||||
),
|
||||
]
|
|
@ -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='工序类型'),
|
||||
),
|
||||
]
|
|
@ -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='默认')
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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='关联工单'),
|
||||
),
|
||||
]
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
|
@ -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='路由名称'),
|
||||
),
|
||||
]
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
创建用户序列化
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue