增加area tdevice表
This commit is contained in:
parent
821d6cf2db
commit
0ab3ae31af
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
|
@ -0,0 +1,6 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class AemConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'apps.am'
|
|
@ -0,0 +1,64 @@
|
|||
# Generated by Django 3.2.12 on 2022-05-09 01: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 = [
|
||||
('system', '0004_auto_20220421_1511'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Access',
|
||||
fields=[
|
||||
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')),
|
||||
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||
('type', models.PositiveSmallIntegerField(choices=[(10, '准入'), (20, '禁入')], verbose_name='准入类型')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Area',
|
||||
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=20, verbose_name='名称')),
|
||||
('level', models.PositiveSmallIntegerField(verbose_name='区域等级')),
|
||||
('sort_str', models.CharField(default='1', max_length=12, verbose_name='排序字符')),
|
||||
('visitor_no', models.BooleanField(default=True, verbose_name='不准许访客')),
|
||||
('rparty_no', models.BooleanField(default=True, verbose_name='不准许相关方')),
|
||||
('third_info', models.JSONField(blank=True, default=dict, verbose_name='三方信息')),
|
||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='area_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||
('manager', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='区域负责人')),
|
||||
('posts_access', models.ManyToManyField(through='am.Access', to='system.Post')),
|
||||
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='area_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='access',
|
||||
name='area',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='am.area', verbose_name='关联区域'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='access',
|
||||
name='post',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.post', verbose_name='关联岗位'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,37 @@
|
|||
from django.db import models
|
||||
from apps.system.models import Post, User
|
||||
from apps.utils.models import BaseModel, CommonAModel
|
||||
# Create your models here.
|
||||
|
||||
|
||||
class Area(CommonAModel):
|
||||
"""
|
||||
地图区域
|
||||
"""
|
||||
name = models.CharField('名称', max_length=20)
|
||||
level = models.PositiveSmallIntegerField('区域等级')
|
||||
sort_str = models.CharField('排序字符', max_length=12, default='1')
|
||||
manager = models.ForeignKey(User, on_delete=models.CASCADE,
|
||||
verbose_name='区域负责人')
|
||||
visitor_no = models.BooleanField('不准许访客', default=True)
|
||||
rparty_no = models.BooleanField('不准许相关方', default=True)
|
||||
posts_access = models.ManyToManyField(Post, through='am.access')
|
||||
third_info = models.JSONField('三方信息', default=dict,
|
||||
null=False, blank=True)
|
||||
|
||||
|
||||
class Access(BaseModel):
|
||||
"""
|
||||
准入权限
|
||||
"""
|
||||
ACCESS_IN_YES = 10
|
||||
ACCESS_IN_NO = 20
|
||||
ACCESS_CHOICE = (
|
||||
(ACCESS_IN_YES, '准入'),
|
||||
(ACCESS_IN_NO, '禁入')
|
||||
)
|
||||
type = models.PositiveSmallIntegerField('准入类型', choices=ACCESS_CHOICE)
|
||||
area = models.ForeignKey(Area, verbose_name='关联区域',
|
||||
on_delete=models.CASCADE)
|
||||
post = models.ForeignKey(Post, verbose_name='关联岗位',
|
||||
on_delete=models.CASCADE)
|
|
@ -0,0 +1,8 @@
|
|||
from apps.am.models import Area
|
||||
from apps.utils.serializers import CustomModelSerializer
|
||||
|
||||
|
||||
class AreaSimpleSerializer(CustomModelSerializer):
|
||||
class Meta:
|
||||
model = Area
|
||||
fields = ['id', 'name', 'level']
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -0,0 +1,3 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
|
@ -97,7 +97,7 @@ class PTaskViewSet(CustomModelViewSet):
|
|||
interval, _ = IntervalSchedule.objects.get_or_create(
|
||||
**interval_, defaults=interval_)
|
||||
data['interval'] = interval.id
|
||||
except:
|
||||
except Exception:
|
||||
raise ParseError(**SCHEDULE_WRONG)
|
||||
if timetype == 'crontab' and crontab_:
|
||||
data['interval'] = None
|
||||
|
@ -106,7 +106,7 @@ class PTaskViewSet(CustomModelViewSet):
|
|||
crontab, _ = CrontabSchedule.objects.get_or_create(
|
||||
**crontab_, defaults=crontab_)
|
||||
data['crontab'] = crontab.id
|
||||
except:
|
||||
except Exception:
|
||||
raise ParseError(**SCHEDULE_WRONG)
|
||||
serializer = self.get_serializer(data=data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
@ -131,7 +131,7 @@ class PTaskViewSet(CustomModelViewSet):
|
|||
interval, _ = IntervalSchedule.objects.get_or_create(
|
||||
**interval_, defaults=interval_)
|
||||
data['interval'] = interval.id
|
||||
except:
|
||||
except Exception:
|
||||
raise ParseError(**SCHEDULE_WRONG)
|
||||
if timetype == 'crontab' and crontab_:
|
||||
data['interval'] = None
|
||||
|
@ -142,7 +142,7 @@ class PTaskViewSet(CustomModelViewSet):
|
|||
crontab, _ = CrontabSchedule.objects.get_or_create(
|
||||
**crontab_, defaults=crontab_)
|
||||
data['crontab'] = crontab.id
|
||||
except:
|
||||
except Exception:
|
||||
raise ParseError(**SCHEDULE_WRONG)
|
||||
instance = self.get_object()
|
||||
serializer = self.get_serializer(instance, data=data)
|
||||
|
@ -166,6 +166,7 @@ class PTaskResultViewSet(ListModelMixin, RetrieveModelMixin, CustomGenericViewSe
|
|||
queryset = TaskResult.objects.all()
|
||||
serializer_class = PTaskResultSerializer
|
||||
ordering = ['-date_created']
|
||||
lookup_field = 'task_id'
|
||||
|
||||
|
||||
class DictTypeViewSet(CustomModelViewSet):
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from apps.utils.xunxi import XxClient
|
||||
from apps.utils.dahua import DhClient
|
||||
|
||||
from apps.utils.speaker import SpClient
|
||||
dhClient = DhClient()
|
||||
xxClient = XxClient()
|
||||
spClient = SpClient()
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# Generated by Django 3.2.12 on 2022-05-09 01:05
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('am', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='TDevice',
|
||||
fields=[
|
||||
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')),
|
||||
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||
('type', models.PositiveSmallIntegerField(choices=[(10, '定位基站'), (20, '定位信标'), (30, '定位标签'), (40, 'aoa引擎'), (50, '音响'), (60, '视频通道'), (70, '闸机通道'), (80, '面板机')], verbose_name='设备类型')),
|
||||
('code', models.CharField(max_length=20, verbose_name='设备唯一标识')),
|
||||
('location', models.JSONField(blank=True, default=dict, verbose_name='位置信息')),
|
||||
('third_info', models.JSONField(blank=True, default=dict, verbose_name='三方信息')),
|
||||
('area', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='am.area', verbose_name='所在区')),
|
||||
('areas', models.ManyToManyField(related_name='tareas', to='am.Area', verbose_name='覆盖区')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
|
@ -1,3 +1,41 @@
|
|||
from django.db import models
|
||||
from apps.am.models import Area
|
||||
|
||||
from apps.utils.models import BaseModel
|
||||
|
||||
# Create your models here.
|
||||
|
||||
|
||||
class TDevice(BaseModel):
|
||||
"""
|
||||
三方设备补充信息
|
||||
"""
|
||||
DEVICE_BLG = 10
|
||||
DEVICE_IBEACON = 20
|
||||
DEVICE_BLT = 30
|
||||
DEVICE_AOA = 40
|
||||
DEVICE_SPEAKER = 50
|
||||
DEVICE_VCHANNEL = 60
|
||||
DEVICE_DCHANNEL = 70
|
||||
DEVICE_PANEL = 80
|
||||
|
||||
DEVICE_CHOICE = (
|
||||
(DEVICE_BLG, '定位基站'),
|
||||
(DEVICE_IBEACON, '定位信标'),
|
||||
(DEVICE_BLT, '定位标签'),
|
||||
(DEVICE_AOA, 'aoa引擎'),
|
||||
(DEVICE_SPEAKER, '音响'),
|
||||
(DEVICE_VCHANNEL, '视频通道'),
|
||||
(DEVICE_DCHANNEL, '闸机通道'),
|
||||
(DEVICE_PANEL, '面板机')
|
||||
)
|
||||
type = models.PositiveSmallIntegerField('设备类型', choices=DEVICE_CHOICE)
|
||||
code = models.CharField('设备唯一标识', max_length=20)
|
||||
location = models.JSONField('位置信息', default=dict,
|
||||
null=False, blank=True)
|
||||
area = models.ForeignKey(Area, on_delete=models.CASCADE,
|
||||
verbose_name='所在区', null=True, blank=True)
|
||||
areas = models.ManyToManyField(Area, verbose_name='覆盖区',
|
||||
related_name='tareas')
|
||||
third_info = models.JSONField('三方信息', default=dict,
|
||||
null=False, blank=True)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
from apps.am.models import Area
|
||||
|
||||
|
||||
class RequestCommonSerializer(serializers.Serializer):
|
||||
method_choice = (
|
||||
|
@ -13,3 +15,21 @@ class RequestCommonSerializer(serializers.Serializer):
|
|||
params = serializers.JSONField(label='请求参数', required=False, allow_null=True)
|
||||
json = serializers.JSONField(label='请求body(json格式)', required=False, allow_null=True)
|
||||
code = serializers.CharField(label='请求短标识', required=False, allow_null=True)
|
||||
|
||||
|
||||
class BindAreaSerializer(serializers.Serializer):
|
||||
codes = serializers.ListField(child=serializers.CharField(), label='标识列表')
|
||||
area = serializers.PrimaryKeyRelatedField(queryset=Area.objects.all(),
|
||||
label="区域ID")
|
||||
|
||||
|
||||
class LabelLocationSerializer(serializers.Serializer):
|
||||
code = serializers.CharField(label='设备唯一标识')
|
||||
location = serializers.JSONField(label='坐标信息')
|
||||
|
||||
|
||||
class BindAreasSerializer(serializers.Serializer):
|
||||
codes = serializers.ListField(child=serializers.CharField(), label='标识列表')
|
||||
areas = serializers.PrimaryKeyRelatedField(queryset=Area.objects.all(),
|
||||
label="区域ID列表",
|
||||
required=False, many=True)
|
||||
|
|
|
@ -88,5 +88,25 @@ dhapis = {
|
|||
|
||||
# 寻息API接口
|
||||
xxapis = {
|
||||
|
||||
"blg_list": {
|
||||
"url": "/api/devicesV3/blgs",
|
||||
"method": "post"
|
||||
},
|
||||
"ibeacon_list": {
|
||||
"url": "/api/devicesV3/ibeacons",
|
||||
"method": "post"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# 音响API接口
|
||||
spapis = {
|
||||
"user_login": {
|
||||
"url": "/api/users/login",
|
||||
"method": "post"
|
||||
},
|
||||
"device_list": {
|
||||
"url": "/api/devices",
|
||||
"method": "get"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from django.urls import path, include
|
||||
from rest_framework import routers
|
||||
from apps.third.views import DahuaTestView, DhCommonViewSet, XxCommonViewSet, XxTestView
|
||||
from apps.third.views import DahuaTestView, DhCommonViewSet, SpTestView, XxCommonViewSet, XxTestView
|
||||
from apps.third.views_d import VChannelViewSet
|
||||
|
||||
API_BASE_URL = 'api/third/'
|
||||
HTML_BASE_URL = 'third/'
|
||||
|
@ -8,9 +9,10 @@ HTML_BASE_URL = 'third/'
|
|||
router = routers.DefaultRouter()
|
||||
router.register('xunxi', XxCommonViewSet, basename='api_xunxi')
|
||||
router.register('dahua', DhCommonViewSet, basename='api_dahua')
|
||||
|
||||
router.register('vchannel', VChannelViewSet, basename='vchannel')
|
||||
urlpatterns = [
|
||||
path(API_BASE_URL, include(router.urls)),
|
||||
path(API_BASE_URL + 'dahua/test/', DahuaTestView.as_view()),
|
||||
path(API_BASE_URL + 'xunxi/test/', XxTestView.as_view()),
|
||||
path(API_BASE_URL + 'speaker/test/', SpTestView.as_view()),
|
||||
]
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
from rest_framework.exceptions import ParseError, APIException
|
||||
from apps.third.tapis import dhapis, xxapis
|
||||
from apps.third.tapis import dhapis, xxapis, spapis
|
||||
from apps.third.erros import TAPI_CODE_WRONG
|
||||
from apps.third.clients import dhClient
|
||||
from apps.third.clients import dhClient, spClient, xxClient
|
||||
from apps.utils.mixins import MyLoggingMixin
|
||||
from apps.third.clients import xxClient
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.permissions import IsAuthenticated, IsAdminUser
|
||||
|
@ -31,6 +30,22 @@ class DahuaTestView(MyLoggingMixin, APIView):
|
|||
return Response(res)
|
||||
|
||||
|
||||
class SpTestView(APIView):
|
||||
"""
|
||||
音响测试接口
|
||||
"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
"""
|
||||
音响测试接口
|
||||
|
||||
音响测试接口
|
||||
"""
|
||||
_, res = spClient.request(**spapis['device_list'])
|
||||
return Response(res)
|
||||
|
||||
|
||||
class XxTestView(APIView):
|
||||
"""
|
||||
寻息测试接口
|
||||
|
@ -58,11 +73,11 @@ class XxListener(stomp.ConnectionListener):
|
|||
print('received a message "%s"' % frame.body)
|
||||
|
||||
|
||||
if settings.XX_ENABLED:
|
||||
c = stomp.Connection([(settings.XX_MQ_HOST, settings.XX_MQ_PORT)])
|
||||
c.set_listener('', XxListener())
|
||||
c.connect(settings.XX_USERNAME, settings.XX_LICENCE)
|
||||
c.subscribe(settings.XX_QUEUE, id='')
|
||||
# if settings.XX_ENABLED:
|
||||
# c = stomp.Connection([(settings.XX_MQ_HOST, settings.XX_MQ_PORT)])
|
||||
# c.set_listener('', XxListener())
|
||||
# c.connect(settings.XX_USERNAME, settings.XX_LICENCE)
|
||||
# c.subscribe(settings.XX_QUEUE, id='')
|
||||
|
||||
|
||||
class XxCommonViewSet(CreateModelMixin, CustomGenericViewSet):
|
||||
|
@ -77,11 +92,11 @@ class XxCommonViewSet(CreateModelMixin, CustomGenericViewSet):
|
|||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.validated_data
|
||||
if vdata.get('code', ''):
|
||||
dhapi = dhapis.get(vdata['code'], None)
|
||||
if dhapi is None:
|
||||
xxapi = xxapis.get(vdata['code'], None)
|
||||
if xxapi is None:
|
||||
raise ParseError(**TAPI_CODE_WRONG)
|
||||
vdata['url'] = dhapi['url']
|
||||
vdata['method'] = dhapi['method']
|
||||
vdata['url'] = xxapi['url']
|
||||
vdata['method'] = xxapi['method']
|
||||
_, res = xxClient.request(
|
||||
url=vdata['url'],
|
||||
method=vdata.get('method', 'post'),
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
from apps.third.models import TDevice
|
||||
from apps.third.serializers import BindAreaSerializer, LabelLocationSerializer
|
||||
from apps.utils.viewsets import CustomGenericViewSet
|
||||
from rest_framework.mixins import ListModelMixin
|
||||
from apps.third.clients import xxClient, dhClient
|
||||
from apps.third.tapis import xxapis, dhapis
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.serializers import Serializer
|
||||
from rest_framework.decorators import action
|
||||
from apps.am.models import Area
|
||||
|
||||
# class BlgViewSet(ListModelMixin, CustomGenericViewSet):
|
||||
# """
|
||||
# 定位基站接口
|
||||
# """
|
||||
# perms_map = {'get': '*'} # 权限标识
|
||||
# serializer_class = Serializer
|
||||
|
||||
# def list(self, request, *args, **kwargs):
|
||||
# """
|
||||
# 定位基站列表
|
||||
|
||||
# 定位基站列表
|
||||
# """
|
||||
# data = request.data
|
||||
# _, res = xxClient.request(**xxapis['blg_list'], json=data)
|
||||
# return Response(res)
|
||||
|
||||
|
||||
# class IbeaconViewSet(CustomGenericViewSet):
|
||||
# """
|
||||
# 信标接口
|
||||
# """
|
||||
# perms_map = {'get': '*'} # 权限标识
|
||||
# serializer_class = Serializer
|
||||
|
||||
# def list(self, request, *args, **kwargs):
|
||||
# """
|
||||
# 信标列表
|
||||
|
||||
# 定位基站列表
|
||||
# """
|
||||
# data = request.data
|
||||
# _, res = xxClient.request(**xxapis['blg_list'], json=data)
|
||||
# return Response(res)
|
||||
|
||||
|
||||
class DChannelViewSet(CustomGenericViewSet):
|
||||
"""
|
||||
闸机接口
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class VChannelViewSet(CustomGenericViewSet):
|
||||
"""
|
||||
视频接口
|
||||
"""
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'},
|
||||
serializer_class=Serializer)
|
||||
def page(self, request):
|
||||
request.data.update({'channelTypeList': ["1"]})
|
||||
_, res = dhClient.request(**dhapis['channel_list'], json=request.data)
|
||||
return Response(res)
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post': 'dchannel:label_location'},
|
||||
serializer_class=LabelLocationSerializer)
|
||||
def label_location(self, request):
|
||||
"""
|
||||
标注坐标位置
|
||||
|
||||
标注坐标位置
|
||||
"""
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.vdata
|
||||
td = TDevice.objects.filter(code=vdata['code']).first()
|
||||
if td:
|
||||
td.location = vdata['location']
|
||||
td.update_by = request.user
|
||||
td.save()
|
||||
else:
|
||||
td = TDevice()
|
||||
td.type = TDevice.DEVICE_VCHANNEL
|
||||
td.code = vdata['code']
|
||||
td.location = vdata['location']
|
||||
td.create_by = request.user
|
||||
td.save()
|
||||
return Response()
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post': 'dchannel:bind_area'},
|
||||
serializer_class=BindAreaSerializer)
|
||||
def bind_area(self, request):
|
||||
"""
|
||||
绑定所在区域
|
||||
|
||||
绑定所在区域
|
||||
"""
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.vdata
|
||||
area = Area.objects.get(id=vdata['area'])
|
||||
for i in vdata['codes']:
|
||||
td = TDevice.objects.filter(code=i['code']).first()
|
||||
if td:
|
||||
td.area = area
|
||||
td.update_by = request.user
|
||||
td.save()
|
||||
else:
|
||||
td = TDevice()
|
||||
td.type = TDevice.DEVICE_VCHANNEL
|
||||
td.code = i['code']
|
||||
td.area = area
|
||||
td.create_by = request.user
|
||||
td.save()
|
||||
return Response()
|
|
@ -88,7 +88,7 @@ class DhClient:
|
|||
r = getattr(requests, method)('{}{}'.format(settings.DAHUA_BASE_URL, url),
|
||||
headers=self.headers, params=params, json=json,
|
||||
timeout=timeout, files=files, verify=False)
|
||||
except:
|
||||
except Exception:
|
||||
if raise_exception:
|
||||
raise APIException(**DH_REQUEST_ERROR)
|
||||
return 'error', DH_REQUEST_ERROR
|
||||
|
@ -112,6 +112,3 @@ class DhClient:
|
|||
if raise_exception:
|
||||
raise APIException(**DH_REQUEST_ERROR)
|
||||
return 'error', DH_REQUEST_ERROR
|
||||
|
||||
|
||||
dhClient = DhClient()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
XX_REQUEST_ERROR = {"code": "xx_request_error", "detail": "寻息接口访问异常"}
|
||||
DH_REQUEST_ERROR = {"code": "dh_request_error", "detail": "大华接口访问异常"}
|
||||
SP_REQUEST_ERROR = {"code": "sp_request_error", "detail": "音响接口访问异常"}
|
||||
SIGN_MAKE_FAIL = {"code": "sign_make_fail", "detail": "签名照生成失败,请重新上传"}
|
||||
PKS_ERROR = {"code": "pks_error", "detail": "未获取到主键列表"}
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
import time
|
||||
from threading import Thread
|
||||
|
||||
import requests
|
||||
# from django.conf import settings
|
||||
from server import settings
|
||||
from rest_framework.exceptions import APIException, ParseError
|
||||
|
||||
from apps.utils.errors import SP_REQUEST_ERROR
|
||||
from apps.utils.tools import print_roundtrip
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
|
||||
class SpClient:
|
||||
"""
|
||||
音响接口
|
||||
"""
|
||||
|
||||
def __init__(self, username=settings.SP_USERNAME,
|
||||
password=settings.SP_PASSWORD) -> None:
|
||||
if not settings.SP_ENABLED:
|
||||
return None
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.headers = {}
|
||||
self.isGetingToken = False
|
||||
self.isRuning = True
|
||||
self.t = None # 线程
|
||||
self.setup()
|
||||
|
||||
def _get_token_loop(self):
|
||||
while self.isRuning:
|
||||
params = {
|
||||
"user": {
|
||||
"email": self.username,
|
||||
"password": self.password
|
||||
}
|
||||
}
|
||||
r = requests.post(params=params,
|
||||
url=settings.SP_BASE_URL + '/api/users/login', verify=False)
|
||||
if r.status_code == 200:
|
||||
ret = r.json()
|
||||
self.headers['Authorization'] = 'bearer ' + ret['user']['token']
|
||||
time.sleep(3600)
|
||||
|
||||
def get_token(self):
|
||||
self.isGetingToken = True
|
||||
params = {
|
||||
'grant_type': 'client_credentials',
|
||||
'client_id': self.client_id,
|
||||
'client_secret': self.client_secret
|
||||
}
|
||||
r = requests.post(params=params, url=settings.SP_BASE_URL + '/evo-apigw/evo-oauth/oauth/token', verify=False)
|
||||
if r.status_code == 200:
|
||||
ret = r.json()
|
||||
print(ret)
|
||||
self.headers['Authorization'] = 'bearer ' + ret['user']['token']
|
||||
self.isGetingToken = False
|
||||
|
||||
def setup(self):
|
||||
t = Thread(target=self._get_token_loop, args=(), daemon=True)
|
||||
t.start()
|
||||
|
||||
def __del__(self):
|
||||
"""
|
||||
自定义销毁
|
||||
"""
|
||||
self.isRuning = False
|
||||
# self.t.join()
|
||||
|
||||
def request(self, url: str, method: str, params=dict(), json=dict(), timeout=10,
|
||||
file_path_rela=None, raise_exception=True):
|
||||
if self.isGetingToken:
|
||||
req_num = 0
|
||||
while True:
|
||||
time.sleep(0.5)
|
||||
if not self.isGetingToken:
|
||||
self.request(url, method, params, json, timeout, file_path_rela, raise_exception)
|
||||
req_num = req_num + 1
|
||||
if req_num > 4:
|
||||
break
|
||||
else:
|
||||
files = None
|
||||
if file_path_rela: # 相对路径
|
||||
files = {'file': open(settings.BASE_DIR + file_path_rela, 'rb')}
|
||||
try:
|
||||
if params:
|
||||
url = url.format(**params)
|
||||
r = getattr(requests, method)('{}{}'.format(settings.SP_BASE_URL, url),
|
||||
headers=self.headers, params=params, json=json,
|
||||
timeout=timeout, files=files, verify=False)
|
||||
except Exception:
|
||||
if raise_exception:
|
||||
raise APIException(**SP_REQUEST_ERROR)
|
||||
return 'error', SP_REQUEST_ERROR
|
||||
# if settings.DEBUG:
|
||||
# print_roundtrip(r)
|
||||
if r.status_code == 200:
|
||||
ret = r.json()
|
||||
if 'code' in ret and ret['code'] not in ['0', '100', '00000', '1000', 0, 100, 1000]:
|
||||
detail = '音响错误:{}'.format(str(ret['msg']))
|
||||
err_detail = dict(detail=detail, code='sp_'+str(ret['code']))
|
||||
if raise_exception:
|
||||
raise ParseError(**err_detail)
|
||||
return 'fail', dict(detail=detail, code='sp_'+str(ret['code']))
|
||||
return 'success', ret
|
||||
if raise_exception:
|
||||
raise APIException(**SP_REQUEST_ERROR)
|
||||
return 'error', SP_REQUEST_ERROR
|
|
@ -14,6 +14,7 @@ from apps.utils.mixins import CustomDestoryModelMixin, MyLoggingMixin
|
|||
from apps.utils.permission import ALL_PERMS, RbacPermission, get_user_perms_map
|
||||
from apps.utils.queryset import get_child_queryset2
|
||||
from apps.utils.serializers import PkSerializer
|
||||
from rest_framework.throttling import UserRateThrottle
|
||||
|
||||
|
||||
class CustomGenericViewSet(MyLoggingMixin, GenericViewSet):
|
||||
|
@ -21,6 +22,7 @@ class CustomGenericViewSet(MyLoggingMixin, GenericViewSet):
|
|||
增强的GenericViewSet
|
||||
"""
|
||||
perms_map = {} # 权限标识
|
||||
throttle_classes = [UserRateThrottle]
|
||||
logging_methods = ['POST', 'PUT', 'PATCH', 'DELETE']
|
||||
ordering_fields = '__all__'
|
||||
filter_fields = '__all__'
|
||||
|
|
|
@ -73,8 +73,8 @@ class XxClient:
|
|||
else:
|
||||
r = getattr(requests, method)('{}{}'.format(settings.XX_BASE_URL, url),
|
||||
params=params, json=json, timeout=timeout, verify=False)
|
||||
# if settings.DEBUG:
|
||||
# print_roundtrip(r)
|
||||
if settings.DEBUG:
|
||||
print_roundtrip(r)
|
||||
ret = r.json()
|
||||
if ret.get('errorCode') == '1060000':
|
||||
self.get_token() # 重新获取token
|
||||
|
|
|
@ -53,7 +53,8 @@ INSTALLED_APPS = [
|
|||
'apps.auth1',
|
||||
'apps.monitor',
|
||||
'apps.wf',
|
||||
'apps.hrm'
|
||||
'apps.hrm',
|
||||
'apps.am'
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -180,6 +181,10 @@ REST_FRAMEWORK = {
|
|||
# 'UNAUTHENTICATED_USER': None,
|
||||
# 'UNAUTHENTICATED_TOKEN': None,
|
||||
'EXCEPTION_HANDLER': 'apps.utils.exceptions.custom_exception_hander',
|
||||
'DEFAULT_THROTTLE_RATES': {
|
||||
'anon': '1/second',
|
||||
'user': '1/second'
|
||||
}
|
||||
}
|
||||
# simplejwt配置
|
||||
SIMPLE_JWT = {
|
||||
|
@ -327,6 +332,13 @@ XX_USERNAME = conf.XX_USERNAME
|
|||
XX_BUILDID = conf.XX_BUILDID
|
||||
XX_QUEUE = conf.XX_QUEUE
|
||||
|
||||
|
||||
# 喇叭配置
|
||||
SP_ENABLED = conf.SP_ENABLED
|
||||
SP_BASE_URL = conf.SP_BASE_URL
|
||||
SP_USERNAME = conf.SP_USERNAME
|
||||
SP_PASSWORD = conf.SP_PASSWORD
|
||||
|
||||
# 运维相关
|
||||
SD_PWD = conf.SD_PWD
|
||||
BACKUP_PATH = conf.BACKUP_PATH
|
||||
|
|
Loading…
Reference in New Issue