tlog 增加errors
This commit is contained in:
parent
28f2daca2b
commit
d8b2ac28a3
|
@ -1,5 +1,5 @@
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
from apps.utils.task import CustomTask
|
from apps.utils.tasks import CustomTask
|
||||||
from apps.am.models import Area
|
from apps.am.models import Area
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
|
|
@ -13,3 +13,7 @@ class SendCodeSerializer(serializers.Serializer):
|
||||||
class CodeLoginSerializer(serializers.Serializer):
|
class CodeLoginSerializer(serializers.Serializer):
|
||||||
phone = serializers.CharField(label="手机号")
|
phone = serializers.CharField(label="手机号")
|
||||||
code = serializers.CharField(label="验证码")
|
code = serializers.CharField(label="验证码")
|
||||||
|
|
||||||
|
|
||||||
|
class WxCodeSerializer(serializers.Serializer):
|
||||||
|
code = serializers.CharField(label="code")
|
|
@ -15,9 +15,11 @@ from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from apps.utils.sms import send_sms
|
from apps.utils.sms import send_sms
|
||||||
from apps.utils.tools import rannum
|
from apps.utils.tools import rannum
|
||||||
|
from apps.utils.wxmp import wxmpClient
|
||||||
|
from apps.utils.wx import wxClient
|
||||||
|
|
||||||
|
|
||||||
from apps.auth1.serializers import LoginSerializer, SendCodeSerializer
|
from apps.auth1.serializers import CodeLoginSerializer, LoginSerializer, SendCodeSerializer, WxCodeSerializer
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
||||||
|
|
||||||
|
@ -90,12 +92,11 @@ class WxmpLogin(CreateAPIView):
|
||||||
"""
|
"""
|
||||||
authentication_classes = []
|
authentication_classes = []
|
||||||
permission_classes = []
|
permission_classes = []
|
||||||
|
serializer_class = WxCodeSerializer
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
code = request.data['code']
|
code = request.data['code']
|
||||||
info = requests.get('https://api.weixin.qq.com/sns/jscode2session?appid='+settings.WXMP_APPID+'&secret='+settings.WXMP_APPSECRET+'&js_code=' +
|
info = wxmpClient.get_basic_info(code=code)
|
||||||
code+'&grant_type=authorization_code').content.decode('utf-8')
|
|
||||||
info = json.loads(info)
|
|
||||||
openid = info['openid']
|
openid = info['openid']
|
||||||
session_key = info['session_key']
|
session_key = info['session_key']
|
||||||
try:
|
try:
|
||||||
|
@ -116,23 +117,22 @@ class WxLogin(CreateAPIView):
|
||||||
"""
|
"""
|
||||||
authentication_classes = []
|
authentication_classes = []
|
||||||
permission_classes = []
|
permission_classes = []
|
||||||
|
serializer_class = WxCodeSerializer
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
code = request.data['code']
|
code = request.data['code']
|
||||||
info = requests.get('https://api.weixin.qq.com/sns/jscode2session?appid='+settings.WXMP_APPID+'&secret='+settings.WXMP_APPSECRET+'&js_code=' +
|
info = wxClient.get_basic_info(code=code)
|
||||||
code+'&grant_type=authorization_code').content.decode('utf-8')
|
|
||||||
info = json.loads(info)
|
|
||||||
openid = info['openid']
|
openid = info['openid']
|
||||||
session_key = info['session_key']
|
access = info['access_token']
|
||||||
try:
|
try:
|
||||||
user = User.objects.get(wx_openid=openid, is_active=True)
|
user = User.objects.get(wx_openid=openid, is_active=True)
|
||||||
ret = get_tokens_for_user(user)
|
ret = get_tokens_for_user(user)
|
||||||
ret['wx_session_key'] = session_key
|
ret['wx_token'] = access
|
||||||
ret['wx_openid'] = openid
|
ret['wx_openid'] = openid
|
||||||
cache.set(code, ret, 60*5)
|
cache.set(code, ret, 60*5)
|
||||||
return Response(ret)
|
return Response(ret)
|
||||||
except Exception:
|
except Exception:
|
||||||
return Response({'wx_openid': openid, 'wx_session_key': session_key}, status=400)
|
return Response({'wx_openid': openid, 'wx_token': access}, status=400)
|
||||||
|
|
||||||
|
|
||||||
class GetTokenFromCache(CreateAPIView):
|
class GetTokenFromCache(CreateAPIView):
|
||||||
|
@ -142,6 +142,7 @@ class GetTokenFromCache(CreateAPIView):
|
||||||
"""
|
"""
|
||||||
authentication_classes = []
|
authentication_classes = []
|
||||||
permission_classes = []
|
permission_classes = []
|
||||||
|
serializer_class = WxCodeSerializer
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
code = request.data['code']
|
code = request.data['code']
|
||||||
|
@ -175,6 +176,7 @@ class CodeLogin(CreateAPIView):
|
||||||
"""
|
"""
|
||||||
authentication_classes = []
|
authentication_classes = []
|
||||||
permission_classes = []
|
permission_classes = []
|
||||||
|
serializer_class = CodeLoginSerializer
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
phone = request.data['phone']
|
phone = request.data['phone']
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
|
||||||
|
class SendSmsSerializer(serializers.Serializer):
|
||||||
|
phone = serializers.CharField(label='手机号')
|
||||||
|
template_code = serializers.CharField(label='模板标识')
|
||||||
|
template_param = serializers.JSONField(label='模板参数')
|
||||||
|
|
||||||
|
|
||||||
|
class GenerateVoiceSerializer(serializers.Serializer):
|
||||||
|
msg = serializers.CharField(label='文本')
|
||||||
|
|
||||||
|
|
||||||
|
class TestTaskSerializer(serializers.Serializer):
|
||||||
|
args = serializers.ListField(child=serializers.CharField(), label='列表参数', required=False, allow_null=True)
|
||||||
|
kwargs = serializers.JSONField(label="字典参数", required=False, allow_null=True)
|
|
@ -1,7 +1,12 @@
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from apps.utils.tasks import CustomTask
|
||||||
from server.settings import DATABASES, BACKUP_PATH, SH_PATH, SD_PWD
|
from server.settings import DATABASES, BACKUP_PATH, SH_PATH, SD_PWD
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.cache import cache
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
|
@ -37,6 +42,7 @@ def reload_web_git():
|
||||||
if completed.returncode != 0:
|
if completed.returncode != 0:
|
||||||
return completed.stderr
|
return completed.stderr
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def reload_server_only():
|
def reload_server_only():
|
||||||
command = 'echo "{}" | sudo -S supervisorctl reload'.format(SD_PWD)
|
command = 'echo "{}" | sudo -S supervisorctl reload'.format(SD_PWD)
|
||||||
|
@ -49,3 +55,12 @@ def backup_media():
|
||||||
command = 'bash {}/backup_media.sh'.format(SH_PATH)
|
command = 'bash {}/backup_media.sh'.format(SH_PATH)
|
||||||
completed = subprocess.run(command, shell=True, capture_output=True, text=True)
|
completed = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||||
return completed
|
return completed
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task(base=CustomTask)
|
||||||
|
def get_wx_token():
|
||||||
|
r = requests.get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}'.format(
|
||||||
|
settings.WX_APPID, settings.WX_APPSECRET)).text
|
||||||
|
token = json.loads(r)['access_token']
|
||||||
|
cache.set('wx_token', token)
|
||||||
|
return token
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
from django.urls import path
|
from django.urls import path, include
|
||||||
from apps.develop.views import BackupDatabase, BackupMedia, ReloadClientGit, ReloadServerGit, ReloadServerOnly
|
from apps.develop.views import BackupDatabase, BackupMedia, ReloadClientGit, ReloadServerGit, ReloadServerOnly, TestViewSet
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
API_BASE_URL = 'api/develop/'
|
API_BASE_URL = 'api/develop/'
|
||||||
HTML_BASE_URL = 'develop/'
|
HTML_BASE_URL = 'develop/'
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register('test', TestViewSet, basename='api_test')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path(API_BASE_URL + 'reload_server_git/', ReloadServerGit.as_view()),
|
path(API_BASE_URL + 'reload_server_git/', ReloadServerGit.as_view()),
|
||||||
path(API_BASE_URL + 'reload_web_git/', ReloadClientGit.as_view()),
|
path(API_BASE_URL + 'reload_web_git/', ReloadClientGit.as_view()),
|
||||||
path(API_BASE_URL + 'reload_server_only/', ReloadServerOnly.as_view()),
|
path(API_BASE_URL + 'reload_server_only/', ReloadServerOnly.as_view()),
|
||||||
path(API_BASE_URL + 'backup_database/', BackupDatabase.as_view()),
|
path(API_BASE_URL + 'backup_database/', BackupDatabase.as_view()),
|
||||||
path(API_BASE_URL + 'backup_media/', BackupMedia.as_view())
|
path(API_BASE_URL + 'backup_media/', BackupMedia.as_view()),
|
||||||
|
path(API_BASE_URL, include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,8 +1,20 @@
|
||||||
|
import json
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.permissions import IsAdminUser
|
from rest_framework.permissions import IsAdminUser
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from apps.develop.tasks import backup_database, backup_media, reload_web_git, reload_server_git, reload_server_only
|
from rest_framework.serializers import Serializer
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from apps.develop.serializers import GenerateVoiceSerializer, SendSmsSerializer, TestTaskSerializer
|
||||||
|
from apps.develop.tasks import backup_database, backup_media, get_wx_token, reload_web_git, reload_server_git, reload_server_only
|
||||||
from rest_framework.exceptions import APIException, ParseError
|
from rest_framework.exceptions import APIException, ParseError
|
||||||
|
from apps.system.models import User
|
||||||
|
from apps.system.tasks import show
|
||||||
|
from apps.utils.sms import send_sms
|
||||||
|
from apps.utils.speech import generate_voice
|
||||||
|
from django.core.cache import cache
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from apps.utils.viewsets import CustomGenericViewSet
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,3 +103,74 @@ class BackupMedia(APIView):
|
||||||
return Response()
|
return Response()
|
||||||
else:
|
else:
|
||||||
raise APIException(completed.stdout)
|
raise APIException(completed.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
class TestViewSet(CustomGenericViewSet):
|
||||||
|
authentication_classes = ()
|
||||||
|
permission_classes = ()
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, serializer_class=SendSmsSerializer)
|
||||||
|
def send_sms(self, request, pk=None):
|
||||||
|
"""发送短信测试
|
||||||
|
|
||||||
|
发送短信测试
|
||||||
|
"""
|
||||||
|
serializer = SendSmsSerializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
vdata = serializer.validated_data
|
||||||
|
res = send_sms(**vdata)
|
||||||
|
return Response(res)
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, serializer_class=GenerateVoiceSerializer)
|
||||||
|
def generate_voice(self, request, pk=None):
|
||||||
|
"""文字转语音测试
|
||||||
|
|
||||||
|
文字转语音测试
|
||||||
|
"""
|
||||||
|
serializer = GenerateVoiceSerializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
vdata = serializer.validated_data
|
||||||
|
res = generate_voice(**vdata)
|
||||||
|
return Response(res)
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, serializer_class=TestTaskSerializer)
|
||||||
|
def task(self, request, pk=None):
|
||||||
|
"""任务派发测试
|
||||||
|
|
||||||
|
任务派发测试
|
||||||
|
"""
|
||||||
|
serializer = TestTaskSerializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
vdata = serializer.validated_data
|
||||||
|
ret = {}
|
||||||
|
task = show.delay(*vdata.get('args', []), **vdata.get('kwargs', {}))
|
||||||
|
ret['task_id'] = task.task_id
|
||||||
|
return Response(ret)
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, serializer_class=Serializer)
|
||||||
|
def send_wx_msg(self, request, pk=None):
|
||||||
|
"""微信模板消息发送测试
|
||||||
|
|
||||||
|
微信模板消息发送测试
|
||||||
|
"""
|
||||||
|
wx_token = cache.get('wx_token', None)
|
||||||
|
if not wx_token:
|
||||||
|
wx_token = get_wx_token()
|
||||||
|
data = {
|
||||||
|
"touser": 'ocAnm5vab6QGOnf2dqpuUZGJ0xyw',
|
||||||
|
"template_id": "wczl-hB_bs8CpxwO8_KZuogSTPFXqhBxf8C5HjKl2M4",
|
||||||
|
"url": "http://weixin.qq.com/download",
|
||||||
|
# "miniprogram":{
|
||||||
|
# "appid":"xiaochengxuappid12345",
|
||||||
|
# "pagepath":"index?foo=bar"
|
||||||
|
# },
|
||||||
|
"client_msg_id": "MSG_000001",
|
||||||
|
"data": {
|
||||||
|
"first": {
|
||||||
|
"value": "恭喜你购买成功!",
|
||||||
|
"color": "#173177"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requests.post(url='https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='+wx_token, json=data)
|
||||||
|
return Response({'wx_token': wx_token, 'wx_openid': 'ocAnm5vab6QGOnf2dqpuUZGJ0xyw'})
|
||||||
|
|
|
@ -49,4 +49,6 @@ def check_event_timeout():
|
||||||
cate = i.cates.all().order_by('priority', 'create_time').first()
|
cate = i.cates.all().order_by('priority', 'create_time').first()
|
||||||
if cate.hanle_minute > 0 and (timezone.now()-i.create_time).seconds > cate.hanle_minute * 60:
|
if cate.hanle_minute > 0 and (timezone.now()-i.create_time).seconds > cate.hanle_minute * 60:
|
||||||
i.is_timeout = True
|
i.is_timeout = True
|
||||||
i.save()
|
i.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Create your tasks here
|
# Create your tasks here
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
from apps.opm.models import Operation, Opl
|
from apps.opm.models import Operation, Opl
|
||||||
from apps.utils.task import CustomTask
|
from apps.utils.tasks import CustomTask
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
|
|
||||||
from apps.wf.models import State, Ticket
|
from apps.wf.models import State, Ticket
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
from apps.hrm.models import Certificate, Employee
|
from apps.hrm.models import Certificate, Employee
|
||||||
from apps.rpm.models import Rcertificate, Remployee, Rpj, Rpjcertificate, Rpjmember
|
from apps.rpm.models import Rcertificate, Remployee, Rpj, Rpjcertificate, Rpjmember
|
||||||
from apps.utils.task import CustomTask
|
from apps.utils.tasks import CustomTask
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Create your tasks here
|
# Create your tasks here
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
from random import random, randint
|
from random import random, randint
|
||||||
from apps.utils.task import CustomTask
|
from apps.utils.tasks import CustomTask
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
|
|
||||||
|
|
|
@ -476,11 +476,12 @@ class UserViewSet(CustomModelViewSet):
|
||||||
绑定微信小程序
|
绑定微信小程序
|
||||||
"""
|
"""
|
||||||
openid = request.data['openid']
|
openid = request.data['openid']
|
||||||
user = request.user
|
if openid:
|
||||||
if user.wxmp_openid != openid:
|
user = request.user
|
||||||
User.objects.filter(wxmp_openid=openid).update(wxmp_openid=None)
|
if user.wxmp_openid != openid:
|
||||||
user.wxmp_openid = openid
|
User.objects.filter(wxmp_openid=openid).update(wxmp_openid=None)
|
||||||
user.save()
|
user.wxmp_openid = openid
|
||||||
|
user.save()
|
||||||
return Response({'wxmp_openid': openid})
|
return Response({'wxmp_openid': openid})
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
|
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
|
||||||
|
@ -502,11 +503,12 @@ class UserViewSet(CustomModelViewSet):
|
||||||
绑定微信公众号, 用于发送通知
|
绑定微信公众号, 用于发送通知
|
||||||
"""
|
"""
|
||||||
openid = request.data['openid']
|
openid = request.data['openid']
|
||||||
user = request.user
|
if openid:
|
||||||
if user.wx_openid != openid:
|
user = request.user
|
||||||
User.objects.filter(wx_openid=openid).update(wx_openid=None)
|
if user.wx_openid != openid:
|
||||||
user.wx_openid = openid
|
User.objects.filter(wx_openid=openid).update(wx_openid=None)
|
||||||
user.save()
|
user.wx_openid = openid
|
||||||
|
user.save()
|
||||||
return Response({'wx_openid': openid})
|
return Response({'wx_openid': openid})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.12 on 2022-07-26 04:20
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('third', '0008_auto_20220713_1408'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='tlog',
|
||||||
|
name='errors',
|
||||||
|
field=models.TextField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -76,5 +76,6 @@ class Tlog(BaseModel):
|
||||||
response = models.JSONField(null=True, blank=True)
|
response = models.JSONField(null=True, blank=True)
|
||||||
method = models.CharField(max_length=10)
|
method = models.CharField(max_length=10)
|
||||||
url = models.TextField(null=True, blank=True)
|
url = models.TextField(null=True, blank=True)
|
||||||
|
errors = models.TextField(null=True, blank=True)
|
||||||
params = models.JSONField(null=True, blank=True)
|
params = models.JSONField(null=True, blank=True)
|
||||||
body = models.JSONField(null=True, blank=True)
|
body = models.JSONField(null=True, blank=True)
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
SIGN_MAKE_FAIL = {"code": "sign_make_fail", "detail": "签名照生成失败,请重新上传"}
|
SIGN_MAKE_FAIL = {"code": "sign_make_fail", "detail": "签名照生成失败,请重新上传"}
|
||||||
PKS_ERROR = {"code": "pks_error", "detail": "未获取到主键列表"}
|
PKS_ERROR = {"code": "pks_error", "detail": "未获取到主键列表"}
|
||||||
|
WX_REQUEST_ERROR = {"code": "wx_request_error", "detail": "微信接口访问异常"}
|
||||||
|
|
|
@ -39,18 +39,3 @@ class CustomModelSerializer(DynamicFieldsMixin, serializers.ModelSerializer):
|
||||||
if hasattr(instance, 'update_by'):
|
if hasattr(instance, 'update_by'):
|
||||||
validated_data['update_by'] = getattr(self.request, 'user', None)
|
validated_data['update_by'] = getattr(self.request, 'user', None)
|
||||||
return super().update(instance, validated_data)
|
return super().update(instance, validated_data)
|
||||||
|
|
||||||
|
|
||||||
class SendSmsSerializer(serializers.Serializer):
|
|
||||||
phone = serializers.CharField(label='手机号')
|
|
||||||
template_code = serializers.CharField(label='模板标识')
|
|
||||||
template_param = serializers.JSONField(label='模板参数')
|
|
||||||
|
|
||||||
|
|
||||||
class GenerateVoiceSerializer(serializers.Serializer):
|
|
||||||
msg = serializers.CharField(label='文本')
|
|
||||||
|
|
||||||
|
|
||||||
class TestTaskSerializer(serializers.Serializer):
|
|
||||||
args = serializers.ListField(child=serializers.CharField(), label='列表参数', required=False, allow_null=True)
|
|
||||||
kwargs = serializers.JSONField(label="字典参数", required=False, allow_null=True)
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# from __future__ import absolute_import, unicode_literals
|
||||||
from celery import Task
|
from celery import Task
|
||||||
import logging
|
import logging
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
from apps.utils.views import SignatureViewSet, TestViewSet
|
from apps.utils.views import SignatureViewSet
|
||||||
API_BASE_URL = 'api/utils/'
|
API_BASE_URL = 'api/utils/'
|
||||||
|
|
||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.register('signature', SignatureViewSet, basename='signature')
|
router.register('signature', SignatureViewSet, basename='signature')
|
||||||
router.register('test', TestViewSet, basename='util_test')
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path(API_BASE_URL, include(router.urls)),
|
path(API_BASE_URL, include(router.urls)),
|
||||||
|
|
|
@ -4,18 +4,19 @@ import cv2
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from apps.system.tasks import show
|
from apps.system.tasks import show
|
||||||
from apps.utils.errors import SIGN_MAKE_FAIL
|
from apps.utils.errors import SIGN_MAKE_FAIL
|
||||||
from apps.utils.sms import send_sms
|
|
||||||
from apps.utils.speech import generate_voice
|
|
||||||
from server.settings import BASE_DIR
|
from server.settings import BASE_DIR
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.exceptions import ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
from apps.utils.viewsets import CustomGenericViewSet
|
from apps.utils.viewsets import CustomGenericViewSet
|
||||||
from apps.utils.mixins import CustomCreateModelMixin
|
from apps.utils.mixins import CustomCreateModelMixin
|
||||||
from apps.utils.serializers import GenSignatureSerializer, GenerateVoiceSerializer, SendSmsSerializer, TestTaskSerializer
|
from apps.utils.serializers import GenSignatureSerializer
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.serializers import Serializer
|
from rest_framework.serializers import Serializer
|
||||||
|
from django.core.cache import cache
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
class SignatureViewSet(CustomCreateModelMixin, CustomGenericViewSet):
|
class SignatureViewSet(CustomCreateModelMixin, CustomGenericViewSet):
|
||||||
|
@ -54,47 +55,4 @@ class SignatureViewSet(CustomCreateModelMixin, CustomGenericViewSet):
|
||||||
cv2.imwrite(new_path, image)
|
cv2.imwrite(new_path, image)
|
||||||
return Response({'path': new_path.replace(BASE_DIR, '')})
|
return Response({'path': new_path.replace(BASE_DIR, '')})
|
||||||
except Exception:
|
except Exception:
|
||||||
raise ParseError(**SIGN_MAKE_FAIL)
|
raise ParseError(**SIGN_MAKE_FAIL)
|
||||||
|
|
||||||
|
|
||||||
class TestViewSet(CustomGenericViewSet):
|
|
||||||
authentication_classes = ()
|
|
||||||
permission_classes = ()
|
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, serializer_class=SendSmsSerializer)
|
|
||||||
def send_sms(self, request, pk=None):
|
|
||||||
"""发送短信测试
|
|
||||||
|
|
||||||
发送短信测试
|
|
||||||
"""
|
|
||||||
serializer = SendSmsSerializer(data=request.data)
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
vdata = serializer.validated_data
|
|
||||||
res = send_sms(**vdata)
|
|
||||||
return Response(res)
|
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, serializer_class=GenerateVoiceSerializer)
|
|
||||||
def generate_voice(self, request, pk=None):
|
|
||||||
"""文字转语音测试
|
|
||||||
|
|
||||||
文字转语音测试
|
|
||||||
"""
|
|
||||||
serializer = GenerateVoiceSerializer(data=request.data)
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
vdata = serializer.validated_data
|
|
||||||
res = generate_voice(**vdata)
|
|
||||||
return Response(res)
|
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, serializer_class=TestTaskSerializer)
|
|
||||||
def task(self, request, pk=None):
|
|
||||||
"""任务派发测试
|
|
||||||
|
|
||||||
任务派发测试
|
|
||||||
"""
|
|
||||||
serializer = TestTaskSerializer(data=request.data)
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
vdata = serializer.validated_data
|
|
||||||
ret = {}
|
|
||||||
task = show.delay(*vdata.get('args', []), **vdata.get('kwargs', {}))
|
|
||||||
ret['task_id'] = task.task_id
|
|
||||||
return Response(ret)
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
from threading import Thread
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from django.conf import settings
|
||||||
|
from rest_framework.exceptions import APIException, ParseError
|
||||||
|
import logging
|
||||||
|
from apps.third.models import Tlog
|
||||||
|
from apps.utils.errors import WX_REQUEST_ERROR
|
||||||
|
from apps.utils.tools import print_roundtrip
|
||||||
|
from django.utils.timezone import now
|
||||||
|
import traceback
|
||||||
|
requests.packages.urllib3.disable_warnings()
|
||||||
|
|
||||||
|
# 实例化myLogger
|
||||||
|
myLogger = logging.getLogger('log')
|
||||||
|
|
||||||
|
|
||||||
|
class WxClient:
|
||||||
|
"""
|
||||||
|
微信公众号相关
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, app_id=settings.WX_APPID,
|
||||||
|
app_secret=settings.WX_APPSECRET) -> None:
|
||||||
|
if settings.WX_ENABLED:
|
||||||
|
self.app_id = app_id
|
||||||
|
self.app_secret = app_secret
|
||||||
|
self.isRuning = True
|
||||||
|
self.token = None
|
||||||
|
self.t = None # 线程
|
||||||
|
self.log = {}
|
||||||
|
self.setup()
|
||||||
|
|
||||||
|
def _get_token_loop(self):
|
||||||
|
while self.isRuning:
|
||||||
|
parmas = {
|
||||||
|
'grant_type': 'client_credential',
|
||||||
|
'appid': self.app_id,
|
||||||
|
'secret': self.app_secret
|
||||||
|
}
|
||||||
|
_, ret = self.request(url='/cgi-bin/token', params=parmas, method='get')
|
||||||
|
self.token = ret['access_token']
|
||||||
|
time.sleep(3600)
|
||||||
|
|
||||||
|
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 not settings.WX_ENABLED:
|
||||||
|
raise ParseError('微信公众号未启用')
|
||||||
|
self.log = {"requested_at": now(), "id": uuid.uuid4(), "path": url, "method": method,
|
||||||
|
"params": params, "body": json, "target": "wx", "result": 10}
|
||||||
|
files = None
|
||||||
|
if file_path_rela: # 相对路径
|
||||||
|
files = {'file': open(settings.BASE_DIR + file_path_rela, 'rb')}
|
||||||
|
try:
|
||||||
|
if params:
|
||||||
|
url = url.format(**params)
|
||||||
|
self.log.update({"path": url})
|
||||||
|
r = getattr(requests, method)('{}{}'.format('https://api.weixin.qq.com', url),
|
||||||
|
params=params, json=json,
|
||||||
|
timeout=timeout, files=files, verify=False)
|
||||||
|
except Exception:
|
||||||
|
errors = traceback.format_exc()
|
||||||
|
myLogger.error(errors)
|
||||||
|
self.handle_log(result='error', errors=errors)
|
||||||
|
if raise_exception:
|
||||||
|
raise APIException(**WX_REQUEST_ERROR)
|
||||||
|
return 'error', WX_REQUEST_ERROR
|
||||||
|
# if settings.DEBUG:
|
||||||
|
# print_roundtrip(r)
|
||||||
|
if r.status_code == 200:
|
||||||
|
ret = r.json()
|
||||||
|
if 'errcode' in ret and ret['errcode'] not in [0, '0']:
|
||||||
|
detail = '微信错误:' + \
|
||||||
|
'{}|{}'.format(str(ret['errcode']), ret.get('errmsg', ''))
|
||||||
|
err_detail = dict(detail=detail, code='wx_'+str(ret['errcode']))
|
||||||
|
self.handle_log(result='fail', response=ret)
|
||||||
|
if raise_exception:
|
||||||
|
raise ParseError(**err_detail)
|
||||||
|
return 'fail', dict(detail=detail, code='wx_'+str(ret['errcode']))
|
||||||
|
# self.handle_log(result='success', response=ret) # 成功的日志就不记录了
|
||||||
|
return 'success', ret
|
||||||
|
|
||||||
|
self.handle_log(result='error', response=None)
|
||||||
|
if raise_exception:
|
||||||
|
raise APIException(**WX_REQUEST_ERROR)
|
||||||
|
return 'error', WX_REQUEST_ERROR
|
||||||
|
|
||||||
|
def _get_response_ms(self):
|
||||||
|
"""
|
||||||
|
Get the duration of the request response cycle is milliseconds.
|
||||||
|
In case of negative duration 0 is returned.
|
||||||
|
"""
|
||||||
|
response_timedelta = now() - self.log["requested_at"]
|
||||||
|
response_ms = int(response_timedelta.total_seconds() * 1000)
|
||||||
|
return max(response_ms, 0)
|
||||||
|
|
||||||
|
def handle_log(self, result, response=None, errors=None):
|
||||||
|
self.log.update({
|
||||||
|
"result": result,
|
||||||
|
"response": response,
|
||||||
|
"response_ms": self._get_response_ms(),
|
||||||
|
"errors": errors
|
||||||
|
})
|
||||||
|
Tlog(**self.log).save()
|
||||||
|
|
||||||
|
def get_basic_info(self, code):
|
||||||
|
params = {
|
||||||
|
'appid': self.app_id,
|
||||||
|
'secret': self.app_secret,
|
||||||
|
'code': code,
|
||||||
|
'grant_type': 'authorization_code'
|
||||||
|
}
|
||||||
|
_, res = self.request('/sns/oauth2/access_token', params=params, method='get')
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
wxClient = WxClient()
|
|
@ -0,0 +1,106 @@
|
||||||
|
from distutils import errors
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
from threading import Thread
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from django.conf import settings
|
||||||
|
from rest_framework.exceptions import APIException, ParseError
|
||||||
|
import logging
|
||||||
|
from apps.third.models import Tlog
|
||||||
|
from apps.utils.errors import WX_REQUEST_ERROR
|
||||||
|
from apps.utils.tools import print_roundtrip
|
||||||
|
from django.utils.timezone import now
|
||||||
|
import traceback
|
||||||
|
requests.packages.urllib3.disable_warnings()
|
||||||
|
|
||||||
|
# 实例化myLogger
|
||||||
|
myLogger = logging.getLogger('log')
|
||||||
|
|
||||||
|
|
||||||
|
class WxmpClient:
|
||||||
|
"""
|
||||||
|
微信小程序相关
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, app_id=settings.WXMP_APPID,
|
||||||
|
app_secret=settings.WXMP_APPSECRET) -> None:
|
||||||
|
if settings.WXMP_ENABLED:
|
||||||
|
self.app_id = app_id
|
||||||
|
self.app_secret = app_secret
|
||||||
|
self.log = {}
|
||||||
|
|
||||||
|
def request(self, url: str, method: str, params=dict(), json=dict(), timeout=10,
|
||||||
|
file_path_rela=None, raise_exception=True):
|
||||||
|
if not settings.WX_ENABLED:
|
||||||
|
raise ParseError('微信小程序未启用')
|
||||||
|
self.log = {"requested_at": now(), "id": uuid.uuid4(), "path": url, "method": method,
|
||||||
|
"params": params, "body": json, "target": "wx", "result": 10}
|
||||||
|
files = None
|
||||||
|
if file_path_rela: # 相对路径
|
||||||
|
files = {'file': open(settings.BASE_DIR + file_path_rela, 'rb')}
|
||||||
|
try:
|
||||||
|
if params:
|
||||||
|
url = url.format(**params)
|
||||||
|
self.log.update({"path": url})
|
||||||
|
r = getattr(requests, method)('{}{}'.format('https://api.weixin.qq.com', url),
|
||||||
|
params=params, json=json,
|
||||||
|
timeout=timeout, files=files, verify=False)
|
||||||
|
except Exception:
|
||||||
|
errors = traceback.format_exc()
|
||||||
|
myLogger.error(errors)
|
||||||
|
self.handle_log(result='error', errors=errors)
|
||||||
|
if raise_exception:
|
||||||
|
raise APIException(**WX_REQUEST_ERROR)
|
||||||
|
return 'error', WX_REQUEST_ERROR
|
||||||
|
# if settings.DEBUG:
|
||||||
|
# print_roundtrip(r)
|
||||||
|
if r.status_code == 200:
|
||||||
|
ret = r.json()
|
||||||
|
if 'errcode' in ret and ret['errcode'] not in [0, '0']:
|
||||||
|
detail = '微信错误:' + \
|
||||||
|
'{}|{}'.format(str(ret['errcode']), ret.get('errmsg', ''))
|
||||||
|
err_detail = dict(detail=detail, code='wx_'+str(ret['errcode']))
|
||||||
|
self.handle_log(result='fail', response=ret)
|
||||||
|
if raise_exception:
|
||||||
|
raise ParseError(**err_detail)
|
||||||
|
return 'fail', dict(detail=detail, code='wx_'+str(ret['errcode']))
|
||||||
|
# self.handle_log(result='success', response=ret) # 成功的日志就不记录了
|
||||||
|
return 'success', ret
|
||||||
|
|
||||||
|
self.handle_log(result='error', response=None)
|
||||||
|
if raise_exception:
|
||||||
|
raise APIException(**WX_REQUEST_ERROR)
|
||||||
|
return 'error', WX_REQUEST_ERROR
|
||||||
|
|
||||||
|
def _get_response_ms(self):
|
||||||
|
"""
|
||||||
|
Get the duration of the request response cycle is milliseconds.
|
||||||
|
In case of negative duration 0 is returned.
|
||||||
|
"""
|
||||||
|
response_timedelta = now() - self.log["requested_at"]
|
||||||
|
response_ms = int(response_timedelta.total_seconds() * 1000)
|
||||||
|
return max(response_ms, 0)
|
||||||
|
|
||||||
|
def handle_log(self, result, response=None, errors=None):
|
||||||
|
self.log.update({
|
||||||
|
"result": result,
|
||||||
|
"response": response,
|
||||||
|
"response_ms": self._get_response_ms(),
|
||||||
|
"errors": errors
|
||||||
|
})
|
||||||
|
Tlog(**self.log).save()
|
||||||
|
|
||||||
|
def get_basic_info(self, code):
|
||||||
|
params = {
|
||||||
|
'appid': self.app_id,
|
||||||
|
'secret': self.app_secret,
|
||||||
|
'js_code': code,
|
||||||
|
'grant_type': 'authorization_code'
|
||||||
|
}
|
||||||
|
_, res = self.request('/sns/jscode2session', params=params, method='get')
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
wxmpClient = WxmpClient()
|
|
@ -1,7 +1,7 @@
|
||||||
# Create your tasks here
|
# Create your tasks here
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
from apps.hrm.models import Employee
|
from apps.hrm.models import Employee
|
||||||
from apps.utils.task import CustomTask
|
from apps.utils.tasks import CustomTask
|
||||||
from apps.vm.models import Visit, Vpeople
|
from apps.vm.models import Visit, Vpeople
|
||||||
from apps.wf.models import Ticket
|
from apps.wf.models import Ticket
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
|
|
|
@ -5,7 +5,7 @@ import logging
|
||||||
import traceback
|
import traceback
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
from apps.utils.sms import send_sms
|
from apps.utils.sms import send_sms
|
||||||
from apps.utils.task import CustomTask
|
from apps.utils.tasks import CustomTask
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from apps.wf.models import State, Ticket, TicketFlow, Transition
|
from apps.wf.models import State, Ticket, TicketFlow, Transition
|
||||||
|
|
||||||
|
|
|
@ -397,5 +397,10 @@ AI_IP = conf.AI_IP
|
||||||
|
|
||||||
|
|
||||||
# 微信有关
|
# 微信有关
|
||||||
|
WXMP_ENABLED = conf.WXMP_ENABLED
|
||||||
WXMP_APPID = conf.WXMP_APPID
|
WXMP_APPID = conf.WXMP_APPID
|
||||||
WXMP_APPSECRET = conf.WXMP_APPSECRET
|
WXMP_APPSECRET = conf.WXMP_APPSECRET
|
||||||
|
|
||||||
|
WX_ENABLED = conf.WX_ENABLED
|
||||||
|
WX_APPID = conf.WX_APPID
|
||||||
|
WX_APPSECRET = conf.WX_APPSECRET
|
||||||
|
|
Loading…
Reference in New Issue