|
|
|
import json
|
|
|
|
import requests
|
|
|
|
from urllib.parse import urljoin
|
|
|
|
from django.db.models import Q
|
|
|
|
from django_filters.rest_framework import DjangoFilterBackend
|
|
|
|
from django_redis import get_redis_connection
|
|
|
|
from rest_framework import filters
|
|
|
|
from rest_framework import viewsets
|
|
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
|
|
from dspt_api.models import EcChannel, EcEnv, EcApi, EcApiParams, EcCinemaIds, EcRequestLog, EcApiGroup
|
|
|
|
from dspt_api.serializers import EcChannelSerializer, EcEnvSerializer, EcApiSerializer, EcApiParamsSerializer, \
|
|
|
|
EcCinemaIdsSerializer, EcRequestLogSerializer, EcApiGroupSerializer
|
|
|
|
from django.http.response import JsonResponse
|
|
|
|
from dspt_api.util.sign import Sign
|
|
|
|
|
|
|
|
|
|
|
|
# Create your views here.
|
|
|
|
class EcChannelViewSet(viewsets.ModelViewSet):
|
|
|
|
queryset = EcChannel.objects.all()
|
|
|
|
serializer_class = EcChannelSerializer
|
|
|
|
|
|
|
|
|
|
|
|
class EcEnvViewSet(viewsets.ModelViewSet):
|
|
|
|
queryset = EcEnv.objects.all()
|
|
|
|
serializer_class = EcEnvSerializer
|
|
|
|
|
|
|
|
|
|
|
|
class EcApiViewSet(viewsets.ModelViewSet):
|
|
|
|
queryset = EcApi.objects.all()
|
|
|
|
serializer_class = EcApiSerializer
|
|
|
|
filter_backends = (DjangoFilterBackend,)
|
|
|
|
# http://172.16.1.114:8000/ec/get_api?type=nonmember
|
|
|
|
filterset_fields = ('type',)
|
|
|
|
|
|
|
|
|
|
|
|
class EcApiParamsViewSet(viewsets.ModelViewSet):
|
|
|
|
queryset = EcApiParams.objects.all()
|
|
|
|
serializer_class = EcApiParamsSerializer
|
|
|
|
filter_backends = (DjangoFilterBackend,)
|
|
|
|
# http://172.16.1.114:8000/ec/get_api_params?api_id=1
|
|
|
|
filterset_fields = ('api_id',)
|
|
|
|
|
|
|
|
|
|
|
|
class EcCinemaIdsViewSet(viewsets.ModelViewSet):
|
|
|
|
queryset = EcCinemaIds.objects.all()
|
|
|
|
serializer_class = EcCinemaIdsSerializer
|
|
|
|
|
|
|
|
|
|
|
|
class EcRequestLogViewSet(viewsets.ModelViewSet):
|
|
|
|
queryset = EcRequestLog.objects.all()
|
|
|
|
serializer_class = EcRequestLogSerializer
|
|
|
|
|
|
|
|
|
|
|
|
class EcApiGroupViewSet(viewsets.ModelViewSet):
|
|
|
|
queryset = EcApiGroup.objects.all()
|
|
|
|
serializer_class = EcApiGroupSerializer
|
|
|
|
filter_backends = (DjangoFilterBackend,)
|
|
|
|
# http://172.16.1.114:8000/ec/get_api_group?type=nonmember
|
|
|
|
filterset_fields = ('type',)
|
|
|
|
|
|
|
|
|
|
|
|
# 内部方法,用于生成requests请求对象
|
|
|
|
def handle_request(_request):
|
|
|
|
"""
|
|
|
|
POST请求参数
|
|
|
|
env dspt或zyds
|
|
|
|
member_type member或nonmember
|
|
|
|
api api地址
|
|
|
|
params 请求参数
|
|
|
|
"""
|
|
|
|
req = json.loads(_request.body)
|
|
|
|
env = req.get('env')
|
|
|
|
member_type = req.get('member_type')
|
|
|
|
api = req.get('api')
|
|
|
|
params = json.loads(req.get('params'))
|
|
|
|
base_url = EcEnv.objects.filter(Q(code=env) & Q(type=member_type)).values('host').first()['host']
|
|
|
|
pid = params.get('pid')
|
|
|
|
key = EcChannel.objects.filter(Q(pid=pid) & Q(env=env)).values('channel_key').first()['channel_key']
|
|
|
|
sign = Sign(key)
|
|
|
|
req_params = sign.add_sig(params)
|
|
|
|
req_obj = prepare_request(base_url, api, req_params)
|
|
|
|
return req_obj
|
|
|
|
|
|
|
|
|
|
|
|
# 内部方法,用于拼接请求
|
|
|
|
def prepare_request(_url, _api, _params):
|
|
|
|
req = requests.PreparedRequest()
|
|
|
|
req.prepare_method('GET')
|
|
|
|
req.prepare_url(url=urljoin(_url, _api), params=_params)
|
|
|
|
req.prepare_headers({'host': _url[7:]})
|
|
|
|
return req
|
|
|
|
|
|
|
|
|
|
|
|
@csrf_exempt
|
|
|
|
def get_api_params_by_api_type(request):
|
|
|
|
"""
|
|
|
|
对比接口用于获取指定类型的接口参数
|
|
|
|
http://172.16.1.168:8000/ec/get_params_by_type?type=nonmember
|
|
|
|
"""
|
|
|
|
# 通过Api model获取会员或非会员的api id
|
|
|
|
_type = request.GET.get('type')
|
|
|
|
api_list = EcApi.objects.filter(type=_type).values('id')
|
|
|
|
api_id = [api['id'] for api in api_list]
|
|
|
|
# 通过 api id 查询对应api的参数
|
|
|
|
api_params = EcApiParams.objects.filter(api_id__in=api_id)
|
|
|
|
params_data = EcApiParamsSerializer(api_params, many=True).data
|
|
|
|
# 组织数据结构,根据api id分组
|
|
|
|
api_params_dict = {}
|
|
|
|
for params in params_data:
|
|
|
|
if params['api_id'] in api_params_dict.keys():
|
|
|
|
api_params_dict[params['api_id']].append(params)
|
|
|
|
else:
|
|
|
|
api_params_dict[params['api_id']] = [params]
|
|
|
|
return JsonResponse(api_params_dict, json_dumps_params={'ensure_ascii': False})
|
|
|
|
|
|
|
|
|
|
|
|
# 外部接口, 用于实时生成url并返回前端
|
|
|
|
@csrf_exempt
|
|
|
|
def general_api_url(request):
|
|
|
|
"""
|
|
|
|
此接口为POST接口
|
|
|
|
request 包含
|
|
|
|
env dspt或zyds
|
|
|
|
member_type member或nonmember
|
|
|
|
api api地址
|
|
|
|
params 请求参数
|
|
|
|
"""
|
|
|
|
req_obj = handle_request(request)
|
|
|
|
return JsonResponse({'url': req_obj.url})
|
|
|
|
|
|
|
|
|
|
|
|
# 对外接口,用于收集用户提交内容后发送请求
|
|
|
|
@csrf_exempt
|
|
|
|
def send_request(request):
|
|
|
|
"""
|
|
|
|
request 包含
|
|
|
|
1. 请求链接 request_url
|
|
|
|
2. 返回数据 response_data
|
|
|
|
3. 接口 api
|
|
|
|
4. 环境 env
|
|
|
|
"""
|
|
|
|
# 初始化redis
|
|
|
|
redis_conn = get_redis_connection()
|
|
|
|
user_ip = request.META.get('REMOTE_ADDR')
|
|
|
|
api = request.get('api')
|
|
|
|
redis_key_api = f'dspt_api_{user_ip}_{api}'
|
|
|
|
redis_key_user_data = f'dspt_api_{user_ip}_{api}_data'
|
|
|
|
# 发送请求
|
|
|
|
req = handle_request(request)
|
|
|
|
response = requests.Session().send(req)
|
|
|
|
# 记录Redis
|
|
|
|
if redis_conn.exists(redis_key_api):
|
|
|
|
redis_conn.delete(redis_key_api)
|
|
|
|
else:
|
|
|
|
data = {
|
|
|
|
'request_url': request.get('request_url'),
|
|
|
|
'response_data': response.json()
|
|
|
|
}
|
|
|
|
redis_conn.set(redis_key_api, json.dumps(data), 10 * 60 * 60)
|
|
|
|
redis_conn.delete(redis_key_user_data)
|
|
|
|
# 插入数据
|
|
|
|
db_data = {
|
|
|
|
'ip': user_ip,
|
|
|
|
'env': request.get('env'),
|
|
|
|
'request': request.get('request_url'),
|
|
|
|
'response': response.json()
|
|
|
|
}
|
|
|
|
EcRequestLog.objects.create(db_data)
|
|
|
|
return response.json()
|
|
|
|
|
|
|
|
|
|
|
|
# 对外接口,用于收集用户选择的数据,例如场次,卖品等,以便后续接口直接调用
|
|
|
|
@csrf_exempt
|
|
|
|
def user_select_data(request):
|
|
|
|
# 初始化redis
|
|
|
|
redis_conn = get_redis_connection()
|
|
|
|
user_ip = request.META.get('REMOTE_ADDR')
|
|
|
|
api = request.get('api')
|
|
|
|
redis_key_user_data = f'dspt_api_{user_ip}_{api}_data'
|
|
|
|
# 记录用户选择
|
|
|
|
data = {
|
|
|
|
'user_data': request.get('user_data')
|
|
|
|
}
|
|
|
|
if redis_conn.exists(redis_key_user_data):
|
|
|
|
redis_conn.delete(redis_key_user_data)
|
|
|
|
result = redis_conn.set(redis_key_user_data, json.dumps(data), 10 * 60 * 60)
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
# 对外接口,用于给前端提供上次请求的数据,如果没有则返回数据库中的默认值
|
|
|
|
# 若果有些字段是依赖于其他接口返回值生成的则单独处理此接口, 单独处理逻辑在util目录下
|
|
|
|
@csrf_exempt
|
|
|
|
def get_last_request_data(request):
|
|
|
|
redis_conn = get_redis_connection()
|
|
|
|
user_ip = request.META.get('REMOTE_ADDR')
|
|
|
|
api = request.get('api')
|
|
|
|
|
|
|
|
match api:
|
|
|
|
case '':
|
|
|
|
pass
|
|
|
|
case _:
|
|
|
|
pass
|