304 lines
16 KiB
Python
304 lines
16 KiB
Python
from rest_framework.views import APIView
|
||
from apps.lyTiktokUnion.models import DYSystemAccount
|
||
from utils.jsonResponse import SuccessResponse,ErrorResponse,DetailResponse
|
||
from utils.common import get_parameter_dic,formatdatetime
|
||
from django.db.models import Q,F,Sum,Count
|
||
from django.db import transaction
|
||
from rest_framework import serializers
|
||
from rest_framework_simplejwt.authentication import JWTAuthentication
|
||
from utils.serializers import CustomModelSerializer
|
||
from utils.viewset import CustomModelViewSet
|
||
from rest_framework.permissions import IsAuthenticated
|
||
from utils.pagination import CustomPagination
|
||
from utils.douyin.douyin_utils import douyin
|
||
from utils.douyin.douyinUnion_utils import douyinUnion
|
||
from config import DOUYIN_OPENAPI_CLIENT_KEY,DOUYIN_OPENAPI_CLIENT_SECRET,DOMAIN_HOST
|
||
from apps.lyTiktokUnion.tools.douyin import newdoudian_dklive_yz,newdoudian_dkfx_gj,newdoudian_tz_yz
|
||
from django.http import HttpResponse
|
||
import datetime
|
||
import time
|
||
import json
|
||
import django_filters
|
||
import logging
|
||
logger = logging.getLogger(__name__)
|
||
|
||
class DYSystemAccountFilterset(django_filters.rest_framework.FilterSet):
|
||
#开始时间
|
||
beginAt = django_filters.DateTimeFilter(field_name='update_datetime', lookup_expr='gte') # 指定过滤的字段
|
||
#结束时间
|
||
endAt = django_filters.DateTimeFilter(field_name='update_datetime', lookup_expr='lte')
|
||
# 模糊搜索
|
||
nickname = django_filters.CharFilter(field_name='nickname', lookup_expr='icontains') # icontains表示该字段模糊搜索
|
||
status = django_filters.CharFilter(field_name='status')
|
||
|
||
class Meta:
|
||
model = DYSystemAccount
|
||
fields = ['beginAt', 'endAt','nickname','status']
|
||
|
||
|
||
class DYSystemAccountSerializer(CustomModelSerializer):
|
||
token_status = serializers.SerializerMethodField()
|
||
|
||
def get_token_status(self,obj):
|
||
status = {
|
||
"access_token":False,
|
||
"refresh_token":False
|
||
}
|
||
now = datetime.datetime.now()
|
||
if obj.access_token_expire >= now:
|
||
status['access_token'] = True
|
||
if obj.refresh_token_expire >=now:
|
||
status['refresh_token'] = True
|
||
return status
|
||
|
||
class Meta:
|
||
model = DYSystemAccount
|
||
read_only_fields = ["id"]
|
||
fields = '__all__'
|
||
|
||
# 刷新抖店的认证,保持access_token为有效状态
|
||
def keepDouDianTokenOnline():
|
||
queryset = DYSystemAccount.objects.filter(is_delete=False)
|
||
for m in queryset:
|
||
if m.identity == 1:
|
||
dk_accesstoken_ttl = newdoudian_dkfx_gj.get_cache_access_token_ttl()
|
||
dk_refreshtoken_ttl = newdoudian_dkfx_gj.get_cache_refresh_access_token_ttl()
|
||
if (dk_accesstoken_ttl < 0 or dk_accesstoken_ttl < 2*60*60) and dk_refreshtoken_ttl > 0:
|
||
logger.info("开始刷新抖客token...")
|
||
refresh_bool = newdoudian_dkfx_gj.refresh_token()
|
||
if refresh_bool:
|
||
nowtimestap = int(time.time())
|
||
access_token_expire_in = int(newdoudian_dkfx_gj.get_cache_access_token_ttl())
|
||
refresh_access_expire_in = int(newdoudian_dkfx_gj.get_cache_refresh_access_token_ttl())
|
||
new_access_token = newdoudian_dkfx_gj.get_access_token()
|
||
new_refresh_token = newdoudian_dkfx_gj.get_cache_refresh_token()
|
||
access_token_expire = datetime.datetime.fromtimestamp(nowtimestap + access_token_expire_in)
|
||
refresh_token_expire = datetime.datetime.fromtimestamp(nowtimestap + refresh_access_expire_in)
|
||
m.access_token = new_access_token
|
||
m.refresh_token = new_refresh_token
|
||
m.access_token_expire = access_token_expire
|
||
m.refresh_token_expire = refresh_token_expire
|
||
m.save()
|
||
logger.info("刷新抖客token成功")
|
||
else:
|
||
logger.error("刷新抖客token失败")
|
||
if m.identity == 2:
|
||
tz_accesstoken_ttl = newdoudian_tz_yz.get_cache_access_token_ttl()
|
||
tz_refreshtoken_ttl = newdoudian_tz_yz.get_cache_refresh_access_token_ttl()
|
||
if (tz_accesstoken_ttl < 0 or tz_accesstoken_ttl < 2*60*60) and tz_refreshtoken_ttl > 0:
|
||
logger.info("开始刷新团长token...")
|
||
refresh_bool = newdoudian_tz_yz.refresh_token()
|
||
if refresh_bool:
|
||
nowtimestap = int(time.time())
|
||
access_token_expire_in = int(newdoudian_tz_yz.get_cache_access_token_ttl())
|
||
refresh_access_expire_in = int(newdoudian_tz_yz.get_cache_refresh_access_token_ttl())
|
||
new_access_token = newdoudian_tz_yz.get_access_token()
|
||
new_refresh_token = newdoudian_tz_yz.get_cache_refresh_token()
|
||
access_token_expire = datetime.datetime.fromtimestamp(nowtimestap + access_token_expire_in)
|
||
refresh_token_expire = datetime.datetime.fromtimestamp(nowtimestap + refresh_access_expire_in)
|
||
m.access_token = new_access_token
|
||
m.refresh_token = new_refresh_token
|
||
m.access_token_expire = access_token_expire
|
||
m.refresh_token_expire = refresh_token_expire
|
||
m.save()
|
||
logger.info("刷新团长token成功")
|
||
else:
|
||
logger.error("刷新团长token失败")
|
||
|
||
class DYSystemAccountViewSet(CustomModelViewSet):
|
||
queryset = DYSystemAccount.objects.filter(is_delete=False).order_by("create_datetime")
|
||
serializer_class = DYSystemAccountSerializer
|
||
filterset_class = DYSystemAccountFilterset
|
||
search_fields = ("nickname",)
|
||
|
||
#重写delete方法,并改为逻辑删除
|
||
def destroy(self, request, *args, **kwargs):
|
||
instance = self.get_object_list()
|
||
for i in range(len(instance)):
|
||
instance[i].is_delete = True
|
||
model = self.get_serializer().Meta.model
|
||
model.objects.bulk_update(instance,fields=['is_delete'])
|
||
return SuccessResponse(data=[], msg="删除成功")
|
||
|
||
# 工具型应用 抖客/达人 拼链接 方式 应用授权,抖客再浏览器登录自己的抖客账号,登录后访问此授权链接点击授权,会重定向授权code到 此 应用的【使用地址】(包括state)
|
||
# 拼接后的地址如: https://buyin.jinritemai.com/dashboard/institution/through-power?app_id=7252637730696414757&state=state
|
||
def createCodeBuyin(self,request):
|
||
id = get_parameter_dic(request).get("id",None)
|
||
if not id:#新增授权
|
||
url = newdoudian_dkfx_gj.build_auth_url(type=3)
|
||
else:#重新授权
|
||
url = newdoudian_dkfx_gj.build_auth_url(type=3,state=id)
|
||
return SuccessResponse(data=url)
|
||
|
||
def getCodeBuyinUserinfo(self,request):
|
||
#先触发刷新token
|
||
keepDouDianTokenOnline()
|
||
datas = []
|
||
data = {
|
||
'app_key':newdoudian_dkfx_gj.getCurrentAppKey(),
|
||
'buyin_id': "",
|
||
'name':"",
|
||
'status':"过期",
|
||
'identity':'抖客',
|
||
'expiretime':""
|
||
}
|
||
instance = DYSystemAccount.objects.filter(identity=1,is_delete=False).first()
|
||
if instance:
|
||
buyin_id = instance.buyin_id
|
||
data['buyin_id'] = buyin_id
|
||
data['name'] = instance.nickname
|
||
if newdoudian_dkfx_gj.get_cache_access_token_ttl():
|
||
data['status'] = "正常"
|
||
data['expiretime'] = round((newdoudian_dkfx_gj.get_cache_access_token_ttl())/3600,1)
|
||
else:
|
||
data['name'] = "请使用抖客授权"
|
||
datas.append(data)
|
||
|
||
data2 = {
|
||
'app_key':newdoudian_tz_yz.getCurrentAppKey(),
|
||
'buyin_id':"",
|
||
'name':"",
|
||
'status':"过期",
|
||
'identity':'团长',
|
||
'expiretime':""
|
||
}
|
||
|
||
instance2 = DYSystemAccount.objects.filter(identity=2, is_delete=False).first()
|
||
if instance2:
|
||
buyin_id = instance2.buyin_id
|
||
data2['buyin_id'] = buyin_id
|
||
data2['name'] = instance2.nickname
|
||
if newdoudian_tz_yz.get_cache_access_token_ttl():
|
||
data2['status'] = "正常"
|
||
data2['expiretime'] = round((newdoudian_tz_yz.get_cache_access_token_ttl()) / 3600, 1)
|
||
else:
|
||
data2['name'] = "请使用团长授权"
|
||
datas.append(data2)
|
||
return SuccessResponse(data=datas)
|
||
|
||
# 生成抖音授权码链接
|
||
def createCode(self,request):
|
||
id = get_parameter_dic(request).get("id",None)
|
||
newdouyin = douyin(client_key=DOUYIN_OPENAPI_CLIENT_KEY,client_secret=DOUYIN_OPENAPI_CLIENT_SECRET)
|
||
scope = "user_info,data.external.user,alliance.colonel.service,alliance.kol.buyin_id,alliance.product.skus,alliance.kol.store_manage,alliance.kol.reputation,alliance.kol.orders,alliance.kol.materials,alliance.kol.reputation,alliance.picksource.convert,alliance.kol.live_status"
|
||
redirect_uri = DOMAIN_HOST+"/api/system/douyincodeCallback/"
|
||
if not id:#新增授权
|
||
url = newdouyin.create_code(scope=scope,redirect_uri=redirect_uri)
|
||
else:#重新授权
|
||
url = newdouyin.create_code(scope=scope,redirect_uri=redirect_uri,state=id)
|
||
return SuccessResponse(data=url)
|
||
|
||
# 刷新抖音授权码链接
|
||
def refreshAccessToken(self,request):
|
||
id = get_parameter_dic(request)['id']
|
||
queryset = self.filter_queryset(self.get_queryset())
|
||
instance = queryset.filter(id=id,is_delete=False).first()
|
||
if not instance:
|
||
return ErrorResponse(msg="id error")
|
||
now = datetime.datetime.now()
|
||
refresh_datetime = datetime.timedelta(days=3)#提前三天刷新refresh_token
|
||
if instance.refresh_token_expire < now:
|
||
return ErrorResponse(msg="refresh_token已过期,请重新授权")
|
||
newdouyin = douyin(client_key=DOUYIN_OPENAPI_CLIENT_KEY,client_secret=DOUYIN_OPENAPI_CLIENT_SECRET)
|
||
#先检查是否要刷新refresh_token
|
||
if instance.refresh_token_expire <= (now + refresh_datetime):
|
||
refresh_res = newdouyin.refresh_refresh_token(instance.refresh_token)
|
||
if refresh_res:
|
||
if "error_code" in refresh_res["data"] and refresh_res["data"]["error_code"] == 0:
|
||
refresh_res = refresh_res['data']
|
||
refresh_token = refresh_res.get("refresh_token")
|
||
refresh_expires_in = refresh_res.get("refresh_expires_in")
|
||
refresh_token_expire = now + datetime.timedelta(seconds=int(refresh_expires_in))
|
||
instance.refresh_token_expire = refresh_token_expire
|
||
instance.refresh_token = refresh_token
|
||
instance.save()
|
||
#开始刷新access_token
|
||
res = newdouyin.refresh_access_token(instance.refresh_token)
|
||
if not res:
|
||
return ErrorResponse(msg="刷新token错误")
|
||
if "error_code" in res["data"] and not res["data"]["error_code"] == 0:
|
||
return ErrorResponse(msg="获取刷新access_token失败,错误码:%s,描述:%s"%(res["data"]["error_code"],res["data"]["description"]))
|
||
res = res['data']
|
||
instance.access_token = res.get("access_token")
|
||
expires_in = res.get("expires_in")
|
||
access_token_expire = now + datetime.timedelta(seconds=int(expires_in))
|
||
instance.access_token_expire = access_token_expire
|
||
instance.save()
|
||
return SuccessResponse(msg="刷新成功")
|
||
|
||
|
||
#抖音后台达人账号code授权回调
|
||
class DouyinSytemDarenCodeCallbackView(APIView):
|
||
'''
|
||
抖音后台达人账号code授权回调
|
||
get:
|
||
抖音后台达人账号code授权回调
|
||
'''
|
||
authentication_classes = []
|
||
permission_classes = []
|
||
|
||
def get(self, request):
|
||
newdouyin = douyin(client_key=DOUYIN_OPENAPI_CLIENT_KEY,client_secret=DOUYIN_OPENAPI_CLIENT_SECRET)
|
||
data = get_parameter_dic(request)
|
||
code,state = newdouyin.callback_code(data)
|
||
if not all([code,state]):
|
||
return HttpResponse("非法请求")
|
||
logger.info("获取code回调信息code=%s|state=%s"%(code,state))
|
||
if state == "state":#新增
|
||
now = datetime.datetime.now()
|
||
res = newdouyin.get_access_token(code=code)
|
||
if not res:
|
||
return HttpResponse("获取access_token失败")
|
||
if "error_code" in res["data"] and not res["data"]["error_code"] == 0:
|
||
return HttpResponse("获取access_token失败,错误码:%s,描述:%s"%(res["data"]["error_code"],res["data"]["description"]))
|
||
logger.info("新增系统抖客/达人授权信息,获取token信息:%s"%(res))
|
||
res = res['data']
|
||
access_token = res.get("access_token")
|
||
refresh_token = res.get("refresh_token")
|
||
refresh_expires_in = res.get("refresh_expires_in")
|
||
expires_in = res.get("expires_in")
|
||
access_token_expire = now + datetime.timedelta(seconds=int(expires_in))
|
||
refresh_token_expire = now + datetime.timedelta(seconds=int(refresh_expires_in))
|
||
open_id = res.get("open_id")
|
||
# newdouyinunion = douyinUnion(client_key=DOUYIN_OPENAPI_CLIENT_KEY,client_secret=DOUYIN_OPENAPI_CLIENT_SECRET)
|
||
# buyin_id_res = newdouyinunion.get_buyin_id(access_token=access_token,open_id=open_id)
|
||
# if not buyin_id_res:
|
||
# return HttpResponse("获取百应ID失败")
|
||
# logger.info("新增系统抖客/达人授权信息,获取百应ID信息:%s"%(buyin_id_res))
|
||
# buyin_id = buyin_id_res.get("buyin_id",None)
|
||
userinfo = newdouyin.get_userinfo(access_token=access_token,open_id=open_id)
|
||
if not userinfo:
|
||
return HttpResponse("获取userinfo失败")
|
||
logger.info("新增系统抖客/达人授权信息,获取用户基本信息%s"%(userinfo))
|
||
if "error_code" in userinfo["data"] and not userinfo["data"]["error_code"] == 0:
|
||
return HttpResponse("获取userinfo失败,错误码:%s,描述:%s"%(userinfo["data"]["error_code"],userinfo["data"]["description"]))
|
||
userinfo = userinfo['data']
|
||
avatar = userinfo.get("avatar")
|
||
nickname = userinfo.get("nickname")
|
||
DYSystemAccount.objects.create(refresh_token=refresh_token,access_token=access_token,open_id=open_id,avatar=avatar,nickname=nickname,access_token_expire=access_token_expire,refresh_token_expire=refresh_token_expire)
|
||
return HttpResponse("获取授权成功!!!")
|
||
#重新授权
|
||
instance = DYSystemAccount.objects.filter(id=state,is_delete=False).first()
|
||
if not instance:
|
||
return HttpResponse("非法请求2")
|
||
now = datetime.datetime.now()
|
||
res = newdouyin.get_access_token(code=code)
|
||
if not res:
|
||
return HttpResponse("获取access_token失败")
|
||
if "error_code" in res["data"] and not res["data"]["error_code"] == 0:
|
||
return HttpResponse("获取access_token失败,错误码:%s,描述:%s"%(res["data"]["error_code"],res["data"]["description"]))
|
||
res = res['data']
|
||
access_token = res.get("access_token")
|
||
refresh_token = res.get("refresh_token")
|
||
refresh_expires_in = res.get("refresh_expires_in")
|
||
expires_in = res.get("expires_in")
|
||
access_token_expire = now + datetime.timedelta(seconds=int(expires_in))
|
||
refresh_token_expire = now + datetime.timedelta(seconds=int(refresh_expires_in))
|
||
instance.access_token = access_token
|
||
instance.refresh_token = refresh_token
|
||
instance.access_token_expire = access_token_expire
|
||
instance.refresh_token_expire = refresh_token_expire
|
||
instance.save()
|
||
return HttpResponse("获取授权成功!!!")
|
||
|