diff --git a/apps/ecm/BeiHangGrpc.proto b/apps/ecm/BeiHangGrpc.proto new file mode 100644 index 00000000..d3d96ef5 --- /dev/null +++ b/apps/ecm/BeiHangGrpc.proto @@ -0,0 +1,38 @@ +//python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./BeiHangGrpc.proto +syntax = "proto3"; + +option java_generic_services = true; +option java_multiple_files = true; +option java_package = "com.lyzh.aiservice.grpc"; +option java_outer_classname = "BeiHangProto"; + +service Helmet_Reg { + rpc sendHelmet_Info(JinYu_Request) returns (BHhelmet_Response){} +} + +message JinYu_Request { + int64 zzid = 1; //业务唯一ID + string imgsbase64 = 2 ; //图像Base64字符串 + string imgUrl = 3 ; //图像oss链接Url +} + +message BHhelmet_Response { + int64 zzid = 1; //业务唯一ID + repeated HelmetInfo helmetinfoList = 2; //0:带安全帽 1:未带安全帽 +} + +message Point { + double x = 1; //x坐标 + double y = 2; //y坐标 +} + +message Rectangle { + Point uleft = 1; //左上 + Point lright = 2; //右下 +} + +message HelmetInfo { + int64 head_helmet = 1; //戴头盔 + double conf = 2; //置信度 + Rectangle coord = 3; //矩形坐标 +} \ No newline at end of file diff --git a/apps/ecm/BeiHangGrpc_pb2.py b/apps/ecm/BeiHangGrpc_pb2.py new file mode 100644 index 00000000..e662c3f6 --- /dev/null +++ b/apps/ecm/BeiHangGrpc_pb2.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: BeiHangGrpc.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x11\x42\x65iHangGrpc.proto\"A\n\rJinYu_Request\x12\x0c\n\x04zzid\x18\x01 \x01(\x03\x12\x12\n\nimgsbase64\x18\x02 \x01(\t\x12\x0e\n\x06imgUrl\x18\x03 \x01(\t\"F\n\x11\x42Hhelmet_Response\x12\x0c\n\x04zzid\x18\x01 \x01(\x03\x12#\n\x0ehelmetinfoList\x18\x02 \x03(\x0b\x32\x0b.HelmetInfo\"\x1d\n\x05Point\x12\t\n\x01x\x18\x01 \x01(\x01\x12\t\n\x01y\x18\x02 \x01(\x01\":\n\tRectangle\x12\x15\n\x05uleft\x18\x01 \x01(\x0b\x32\x06.Point\x12\x16\n\x06lright\x18\x02 \x01(\x0b\x32\x06.Point\"J\n\nHelmetInfo\x12\x13\n\x0bhead_helmet\x18\x01 \x01(\x03\x12\x0c\n\x04\x63onf\x18\x02 \x01(\x01\x12\x19\n\x05\x63oord\x18\x03 \x01(\x0b\x32\n.Rectangle2E\n\nHelmet_Reg\x12\x37\n\x0fsendHelmet_Info\x12\x0e.JinYu_Request\x1a\x12.BHhelmet_Response\"\x00\x42,\n\x17\x63om.lyzh.aiservice.grpcB\x0c\x42\x65iHangProtoP\x01\x88\x01\x01\x62\x06proto3') + + +_JINYU_REQUEST = DESCRIPTOR.message_types_by_name['JinYu_Request'] +_BHHELMET_RESPONSE = DESCRIPTOR.message_types_by_name['BHhelmet_Response'] +_POINT = DESCRIPTOR.message_types_by_name['Point'] +_RECTANGLE = DESCRIPTOR.message_types_by_name['Rectangle'] +_HELMETINFO = DESCRIPTOR.message_types_by_name['HelmetInfo'] +JinYu_Request = _reflection.GeneratedProtocolMessageType('JinYu_Request', (_message.Message,), { + 'DESCRIPTOR': _JINYU_REQUEST, + '__module__': 'BeiHangGrpc_pb2' + # @@protoc_insertion_point(class_scope:JinYu_Request) +}) +_sym_db.RegisterMessage(JinYu_Request) + +BHhelmet_Response = _reflection.GeneratedProtocolMessageType('BHhelmet_Response', (_message.Message,), { + 'DESCRIPTOR': _BHHELMET_RESPONSE, + '__module__': 'BeiHangGrpc_pb2' + # @@protoc_insertion_point(class_scope:BHhelmet_Response) +}) +_sym_db.RegisterMessage(BHhelmet_Response) + +Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), { + 'DESCRIPTOR': _POINT, + '__module__': 'BeiHangGrpc_pb2' + # @@protoc_insertion_point(class_scope:Point) +}) +_sym_db.RegisterMessage(Point) + +Rectangle = _reflection.GeneratedProtocolMessageType('Rectangle', (_message.Message,), { + 'DESCRIPTOR': _RECTANGLE, + '__module__': 'BeiHangGrpc_pb2' + # @@protoc_insertion_point(class_scope:Rectangle) +}) +_sym_db.RegisterMessage(Rectangle) + +HelmetInfo = _reflection.GeneratedProtocolMessageType('HelmetInfo', (_message.Message,), { + 'DESCRIPTOR': _HELMETINFO, + '__module__': 'BeiHangGrpc_pb2' + # @@protoc_insertion_point(class_scope:HelmetInfo) +}) +_sym_db.RegisterMessage(HelmetInfo) + +_HELMET_REG = DESCRIPTOR.services_by_name['Helmet_Reg'] +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\027com.lyzh.aiservice.grpcB\014BeiHangProtoP\001\210\001\001' + _JINYU_REQUEST._serialized_start = 21 + _JINYU_REQUEST._serialized_end = 86 + _BHHELMET_RESPONSE._serialized_start = 88 + _BHHELMET_RESPONSE._serialized_end = 158 + _POINT._serialized_start = 160 + _POINT._serialized_end = 189 + _RECTANGLE._serialized_start = 191 + _RECTANGLE._serialized_end = 249 + _HELMETINFO._serialized_start = 251 + _HELMETINFO._serialized_end = 325 + _HELMET_REG._serialized_start = 327 + _HELMET_REG._serialized_end = 396 +# @@protoc_insertion_point(module_scope) diff --git a/apps/ecm/BeiHangGrpc_pb2_grpc.py b/apps/ecm/BeiHangGrpc_pb2_grpc.py new file mode 100644 index 00000000..a9e672e4 --- /dev/null +++ b/apps/ecm/BeiHangGrpc_pb2_grpc.py @@ -0,0 +1,67 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +import BeiHangGrpc_pb2 as BeiHangGrpc__pb2 + + +class Helmet_RegStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.sendHelmet_Info = channel.unary_unary( + '/Helmet_Reg/sendHelmet_Info', + request_serializer=BeiHangGrpc__pb2.JinYu_Request.SerializeToString, + response_deserializer=BeiHangGrpc__pb2.BHhelmet_Response.FromString, + ) + + +class Helmet_RegServicer(object): + """Missing associated documentation comment in .proto file.""" + + def sendHelmet_Info(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_Helmet_RegServicer_to_server(servicer, server): + rpc_method_handlers = { + 'sendHelmet_Info': grpc.unary_unary_rpc_method_handler( + servicer.sendHelmet_Info, + request_deserializer=BeiHangGrpc__pb2.JinYu_Request.FromString, + response_serializer=BeiHangGrpc__pb2.BHhelmet_Response.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'Helmet_Reg', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + # This class is part of an EXPERIMENTAL API. + + +class Helmet_Reg(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def sendHelmet_Info(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/Helmet_Reg/sendHelmet_Info', + BeiHangGrpc__pb2.JinYu_Request.SerializeToString, + BeiHangGrpc__pb2.BHhelmet_Response.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/apps/ecm/Jinyu_Client.py b/apps/ecm/Jinyu_Client.py new file mode 100644 index 00000000..32bbf6ee --- /dev/null +++ b/apps/ecm/Jinyu_Client.py @@ -0,0 +1,31 @@ + +import grpc + +# import base64 + +from . import BeiHangGrpc_pb2_grpc +from . import BeiHangGrpc_pb2 + + +if __name__ == "__main__": + IP = '127.0.0.1:9000' + + channel = grpc.insecure_channel(IP) # 监听频道 + stub = BeiHangGrpc_pb2_grpc.Helmet_RegStub(channel) # 客户端使用Stub类发送请求,参数为频道,为了绑定链接 + image_id = 3 + + # 本地图像输入 + # image_path = "./onnx/image/single3.jpg" + # with open(image_path, 'rb') as f: + # image_base64 = str(base64.b64encode(f.read()), encoding='utf-8') + # request = BeiHangGrpc_pb2.JinYu_Request(zzid=image_id,imgsbase64=image_base64) + + # URL输入 + imgUrl = "XXXXX.jpg" + request = BeiHangGrpc_pb2.JinYu_Request(zzid=image_id, imgUrl=imgUrl) + try: + response = stub.sendHelmet_Info(request) + print("network success! \n") + print(response) + except Exception: + print("network error! \n") diff --git a/apps/ecm/tasks.py b/apps/ecm/tasks.py index 851b4296..0cf00cdf 100644 --- a/apps/ecm/tasks.py +++ b/apps/ecm/tasks.py @@ -1,30 +1,38 @@ from __future__ import absolute_import, unicode_literals +from threading import Thread from celery import shared_task from apps.am.models import Area from apps.third.clients import xxClient +from apps.third.models import TDevice from apps.third.tapis import xxapis +def update_count_people(i: Area): + if i.third_info.get('xx_rail', None): + railId = i.third_info['xx_rail']['id'] + json = {"railId": railId, "type": ""} + _, res = xxClient.request(**xxapis['rail_ibeacon_list'], json=json) + blt_list = res['recordList'] + macs = [] + for i in blt_list: + macs.append(i['mac']) + i.count_people = TDevice.objects.filter( + type=TDevice.DEVICE_BLT, obj_cate='people', code__in=macs).exclude(employee=None).count() + i.save() + if i.count_people >= i.count_people_max: + # 触发超员事件 + pass + elif i.count_people < i.count_people_min: + # 触发缺员事件 + pass + + @shared_task def cal_area_count(): """ 计算区域内人员数量 """ for i in Area.objects.filter(type=Area.AREA_TYPE_FIX): - if i.third_info.get('xx_rail', None): - railId = i.third_info['xx_rail']['id'] - json = {"railId": railId, "type": ""} - _, res = xxClient.request(**xxapis['rail_ibeacon_list'], json=json) - total_count = res['totalCount'] - if total_count >= i.count_people_max: - # 触发超员事件 - i.count_people = total_count - i.save() - pass - elif total_count < i.count_people_min: - # 触发缺员事件 - i.count_people_min = total_count - i.save() - pass \ No newline at end of file + Thread(target=update_count_people, args=(i,)).start() diff --git a/apps/hrm/serializers.py b/apps/hrm/serializers.py index 728abcc1..45cdfcc9 100755 --- a/apps/hrm/serializers.py +++ b/apps/hrm/serializers.py @@ -22,7 +22,7 @@ class EmployeeSimpleSerializer(CustomModelSerializer): class Meta: model = Employee - fields = ['id', 'type', 'name', 'belong_dept', 'belong_dept_name', 'post', 'post_name'] + fields = ['id', 'type', 'name', 'belong_dept', 'belong_dept_name', 'post', 'post_name', 'photo'] class EmployeeBaseSerializer(CustomModelSerializer): @@ -58,6 +58,10 @@ class EmployeeCreateUpdateSerializer(EmployeeBaseSerializer): @transaction.atomic def create(self, validated_data): instance = super().create(validated_data) + if instance.user: # 同步更新账户里的手机号 + user = instance.user + user.phone = instance.phone + user.save() if settings.DAHUA_ENABLED and dhClient: dahua_data = HrmService.sync_dahua_employee(ep=instance) third_info = instance.third_info @@ -69,6 +73,10 @@ class EmployeeCreateUpdateSerializer(EmployeeBaseSerializer): def update(self, instance, validated_data): old_photo = instance.photo instance = super().update(instance, validated_data) + if instance.user: # 同步更新账户里的手机号 + user = instance.user + user.phone = instance.phone + user.save() if settings.DAHUA_ENABLED and dhClient: dahua_data = HrmService.sync_dahua_employee(ep=instance, old_photo=old_photo) third_info = instance.third_info diff --git a/apps/system/models.py b/apps/system/models.py index dbad3208..3684e570 100755 --- a/apps/system/models.py +++ b/apps/system/models.py @@ -1,3 +1,4 @@ +from django.contrib.auth.models import UserManager import enum from django.db import models from django.contrib.auth.models import AbstractUser @@ -111,11 +112,10 @@ class PostRole(BaseModel): on_delete=models.CASCADE, null=True, blank=True) -from django.contrib.auth.models import UserManager - class SoftDeletableUserManager(SoftDeletableManagerMixin, UserManager): pass + class User(AbstractUser, CommonBModel): """ 用户 diff --git a/apps/system/views.py b/apps/system/views.py index b5b26750..2fd61748 100755 --- a/apps/system/views.py +++ b/apps/system/views.py @@ -305,7 +305,7 @@ class DeptViewSet(CustomModelViewSet): 部门-增删改查 """ - queryset = Dept.objects.filter(type__in=['dept', 'company']) + queryset = Dept.objects.all() serializer_class = DeptSerializer create_serializer_class = DeptCreateUpdateSerializer update_serializer_class = DeptCreateUpdateSerializer @@ -313,6 +313,14 @@ class DeptViewSet(CustomModelViewSet): filterset_fields = ['type'] search_fields = ['name'] + def get_queryset(self): + type = self.request.query_params.get('type', None) + if type: + queryset = Dept.objects.filter(type='rparty') + else: + queryset = Dept.objects.filter(type__in=['dept', 'company']) + return queryset + class RoleViewSet(CustomModelViewSet): """角色-增删改查 diff --git a/apps/third/serializers.py b/apps/third/serializers.py index 9c2a422f..85932dd2 100755 --- a/apps/third/serializers.py +++ b/apps/third/serializers.py @@ -11,6 +11,8 @@ class PicSerializer(serializers.Serializer): class TDeviceSerializer(CustomModelSerializer): + area_name = serializers.CharField(source='area.name', read_only=True) + class Meta: model = TDevice fields = '__all__' diff --git a/apps/third/views_d.py b/apps/third/views_d.py index a5887777..e4075bd5 100644 --- a/apps/third/views_d.py +++ b/apps/third/views_d.py @@ -52,7 +52,7 @@ class BltViewSet(CustomGenericViewSet): macs = [] for i in blt_list: macs.append(i['mac']) - qs = self.queryset.filter().exclude(employee=None, code__in=macs) + qs = self.queryset.filter(code__in=macs).exclude(employee=None) ret['total'] = qs.count() ret['count_employee'] = qs.filter(employee__type='employee').count() ret['count_remployee'] = qs.filter(employee__type='remployee').count() @@ -86,12 +86,13 @@ class BltViewSet(CustomGenericViewSet): "online": "online" } _, res = xxClient.request(**xxapis['blt_list'], json=json) + count_people = 0 blt_list = res['recordList'] macs = [] for i in blt_list: macs.append(i['mac']) qs = self.queryset.filter(code__in=macs).exclude(employee=None) - qs_data = list(BltSerializer(instance=qs, many=True).data) + qs_data = BltSerializer(instance=qs, many=True).data qs_dict = {} for i in qs_data: qs_dict[i['code']] = i @@ -99,6 +100,11 @@ class BltViewSet(CustomGenericViewSet): i['my_info'] = {} if i['mac'] in qs_dict: i['my_info'] = qs_dict[i['mac']] + if area: + # 更新区域下的总人数 + count_people = qs.filter(obj_cate='people').count() + area.count_people = count_people + area.save() return Response(blt_list) @@ -123,7 +129,7 @@ class TDeviceViewSet(ListModelMixin, CustomGenericViewSet): for i in res['recordList']: macs.append(i['mac']) qs = self.queryset.filter(code__in=macs).exclude(employee=None) - qs_data = list(BltSerializer(instance=qs, many=True).data) + qs_data = BltSerializer(instance=qs, many=True).data qs_dict = {} for i in qs_data: qs_dict[i['code']] = i @@ -148,10 +154,12 @@ class TDeviceViewSet(ListModelMixin, CustomGenericViewSet): for i in res['pageData']: codes.append(i['channelCode']) tds_info = TDeviceSerializer(instance=TDevice.objects.filter(code__in=codes), many=True).data - for x in res['pageData']: - for y in tds_info: - if x['channelCode'] == y['code']: - x['my_info'] = y + tds_dict = {} + for i in tds_info: + tds_dict[i['code']] = i + for i in res['pageData']: + if i['channelCode'] in tds_dict: + i['my_info'] = tds_dict[i['channelCode']] return Response(res) @action(methods=['post'], detail=False, perms_map={'post': '*'}, @@ -163,6 +171,16 @@ class TDeviceViewSet(ListModelMixin, CustomGenericViewSet): 喇叭列表 """ _, res = spClient.request(**spapis['device_list'], params=request.data) + codes = [] + for i in res['rows']: + codes.append(i['sn']) + tds_info = TDeviceSerializer(instance=TDevice.objects.filter(code__in=codes), many=True).data + tds_dict = {} + for i in tds_info: + tds_dict[i['code']] = i + for i in res['rows']: + if i['sn'] in tds_dict: + i['my_info'] = tds_dict[i['sn']] return Response(res) @action(methods=['post'], detail=False, perms_map={'post': '*'}, @@ -175,6 +193,17 @@ class TDeviceViewSet(ListModelMixin, CustomGenericViewSet): """ request.data.update({'channelTypeList': ["7"]}) _, res = dhClient.request(**dhapis['channel_list'], json=request.data) + codes = [] + if res.get('pageData', None): + for i in res['pageData']: + codes.append(i['channelCode']) + tds_info = TDeviceSerializer(instance=TDevice.objects.filter(code__in=codes), many=True).data + tds_dict = {} + for i in tds_info: + tds_dict[i['code']] = i + for i in res['pageData']: + if i['channelCode'] in tds_dict: + i['my_info'] = tds_dict[i['channelCode']] return Response(res) @action(methods=['post'], detail=False, perms_map={'post': 'tdevice:label_location'}, diff --git a/requirements.txt b/requirements.txt index d78a6918..646194b3 100755 --- a/requirements.txt +++ b/requirements.txt @@ -24,3 +24,6 @@ aliyun-python-sdk-core==2.13.36 baidu-aip==4.16.6 chardet==5.0.0 requests==2.28.1 +grpcio==1.47.0 +grpcio-tools==1.47.0 +protobuf==3.20.1