移动端认证,短信发送等
This commit is contained in:
parent
dae9b5cfcc
commit
28f2daca2b
|
@ -1,3 +1,5 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
from apps.utils.models import BaseModel
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
|
@ -4,3 +4,12 @@ from rest_framework import serializers
|
||||||
class LoginSerializer(serializers.Serializer):
|
class LoginSerializer(serializers.Serializer):
|
||||||
username = serializers.CharField(label="用户名")
|
username = serializers.CharField(label="用户名")
|
||||||
password = serializers.CharField(label="密码")
|
password = serializers.CharField(label="密码")
|
||||||
|
|
||||||
|
|
||||||
|
class SendCodeSerializer(serializers.Serializer):
|
||||||
|
phone = serializers.CharField(label="手机号")
|
||||||
|
|
||||||
|
|
||||||
|
class CodeLoginSerializer(serializers.Serializer):
|
||||||
|
phone = serializers.CharField(label="手机号")
|
||||||
|
code = serializers.CharField(label="验证码")
|
||||||
|
|
|
@ -3,7 +3,7 @@ from django.urls import path
|
||||||
from rest_framework_simplejwt.views import (TokenObtainPairView,
|
from rest_framework_simplejwt.views import (TokenObtainPairView,
|
||||||
TokenRefreshView)
|
TokenRefreshView)
|
||||||
|
|
||||||
from apps.auth1.views import LoginView, LogoutView, TokenBlackView
|
from apps.auth1.views import CodeLogin, GetTokenFromCache, LoginView, LogoutView, SendCode, TokenBlackView, WxLogin, WxmpLogin
|
||||||
|
|
||||||
API_BASE_URL = 'api/auth/'
|
API_BASE_URL = 'api/auth/'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
@ -11,5 +11,10 @@ urlpatterns = [
|
||||||
path(API_BASE_URL + 'token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
path(API_BASE_URL + 'token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||||
path(API_BASE_URL + 'token/black/', TokenBlackView.as_view(), name='token_black'),
|
path(API_BASE_URL + 'token/black/', TokenBlackView.as_view(), name='token_black'),
|
||||||
path(API_BASE_URL + 'login/', LoginView.as_view(), name='session_login'),
|
path(API_BASE_URL + 'login/', LoginView.as_view(), name='session_login'),
|
||||||
|
path(API_BASE_URL + 'login_wxmp/', WxmpLogin.as_view(), name='login_wxmp'),
|
||||||
|
path(API_BASE_URL + 'login_wx/', WxLogin.as_view(), name='login_wx'),
|
||||||
|
path(API_BASE_URL + 'login_sms_code/', CodeLogin.as_view(), name='login_sms_code'),
|
||||||
|
path(API_BASE_URL + 'sms_code/', SendCode.as_view(), name='sms_code_send'),
|
||||||
|
path(API_BASE_URL + 'code_cache_token/', GetTokenFromCache.as_view(), name='code_cache_token'),
|
||||||
path(API_BASE_URL + 'logout/', LogoutView.as_view(), name='session_logout'),
|
path(API_BASE_URL + 'logout/', LogoutView.as_view(), name='session_logout'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,15 +8,30 @@ from rest_framework.generics import CreateAPIView
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from apps.auth1.errors import USERNAME_OR_PASSWORD_WRONG
|
from apps.auth1.errors import USERNAME_OR_PASSWORD_WRONG
|
||||||
from rest_framework.exceptions import ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
from django.conf import settings
|
||||||
|
from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
|
from django.core.cache import cache
|
||||||
|
from apps.utils.sms import send_sms
|
||||||
|
from apps.utils.tools import rannum
|
||||||
|
|
||||||
|
|
||||||
|
from apps.auth1.serializers import LoginSerializer, SendCodeSerializer
|
||||||
from apps.auth1.serializers import LoginSerializer
|
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
|
def get_tokens_for_user(user: User):
|
||||||
|
refresh = RefreshToken.for_user(user)
|
||||||
|
return {
|
||||||
|
'refresh': str(refresh),
|
||||||
|
'access': str(refresh.access_token),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TokenBlackView(APIView):
|
class TokenBlackView(APIView):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
@ -66,3 +81,109 @@ class LogoutView(APIView):
|
||||||
"""
|
"""
|
||||||
logout(request)
|
logout(request)
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
|
class WxmpLogin(CreateAPIView):
|
||||||
|
"""微信小程序自动登录
|
||||||
|
|
||||||
|
微信小程序自动登录
|
||||||
|
"""
|
||||||
|
authentication_classes = []
|
||||||
|
permission_classes = []
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
code = request.data['code']
|
||||||
|
info = requests.get('https://api.weixin.qq.com/sns/jscode2session?appid='+settings.WXMP_APPID+'&secret='+settings.WXMP_APPSECRET+'&js_code=' +
|
||||||
|
code+'&grant_type=authorization_code').content.decode('utf-8')
|
||||||
|
info = json.loads(info)
|
||||||
|
openid = info['openid']
|
||||||
|
session_key = info['session_key']
|
||||||
|
try:
|
||||||
|
user = User.objects.get(wxmp_openid=openid, is_active=True)
|
||||||
|
ret = get_tokens_for_user(user)
|
||||||
|
ret['wxmp_session_key'] = session_key
|
||||||
|
ret['wxmp_openid'] = openid
|
||||||
|
cache.set(code, ret, 60*5)
|
||||||
|
return Response(ret)
|
||||||
|
except Exception:
|
||||||
|
return Response({'wxmp_openid': openid, 'wxmp_session_key': session_key}, status=400)
|
||||||
|
|
||||||
|
|
||||||
|
class WxLogin(CreateAPIView):
|
||||||
|
"""微信公众号授权登录
|
||||||
|
|
||||||
|
微信公众号授权登录
|
||||||
|
"""
|
||||||
|
authentication_classes = []
|
||||||
|
permission_classes = []
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
code = request.data['code']
|
||||||
|
info = requests.get('https://api.weixin.qq.com/sns/jscode2session?appid='+settings.WXMP_APPID+'&secret='+settings.WXMP_APPSECRET+'&js_code=' +
|
||||||
|
code+'&grant_type=authorization_code').content.decode('utf-8')
|
||||||
|
info = json.loads(info)
|
||||||
|
openid = info['openid']
|
||||||
|
session_key = info['session_key']
|
||||||
|
try:
|
||||||
|
user = User.objects.get(wx_openid=openid, is_active=True)
|
||||||
|
ret = get_tokens_for_user(user)
|
||||||
|
ret['wx_session_key'] = session_key
|
||||||
|
ret['wx_openid'] = openid
|
||||||
|
cache.set(code, ret, 60*5)
|
||||||
|
return Response(ret)
|
||||||
|
except Exception:
|
||||||
|
return Response({'wx_openid': openid, 'wx_session_key': session_key}, status=400)
|
||||||
|
|
||||||
|
|
||||||
|
class GetTokenFromCache(CreateAPIView):
|
||||||
|
"""以code获取token
|
||||||
|
|
||||||
|
以code获取token
|
||||||
|
"""
|
||||||
|
authentication_classes = []
|
||||||
|
permission_classes = []
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
code = request.data['code']
|
||||||
|
ret = cache.get(code, {})
|
||||||
|
return Response(ret)
|
||||||
|
|
||||||
|
|
||||||
|
class SendCode(CreateAPIView):
|
||||||
|
authentication_classes = []
|
||||||
|
permission_classes = []
|
||||||
|
serializer_class = SendCodeSerializer
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
"""短信验证码发送
|
||||||
|
|
||||||
|
短信验证码发送
|
||||||
|
"""
|
||||||
|
phone = request.data['phone']
|
||||||
|
code = rannum(4)
|
||||||
|
is_ok, _ = send_sms(phone, 505, {'code': code})
|
||||||
|
cache.set(phone, code, 60*5)
|
||||||
|
if is_ok:
|
||||||
|
return Response()
|
||||||
|
raise ParseError('短信发送失败,请确认手机号')
|
||||||
|
|
||||||
|
|
||||||
|
class CodeLogin(CreateAPIView):
|
||||||
|
"""手机验证码登录
|
||||||
|
|
||||||
|
手机验证码登录
|
||||||
|
"""
|
||||||
|
authentication_classes = []
|
||||||
|
permission_classes = []
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
phone = request.data['phone']
|
||||||
|
code = request.data['code']
|
||||||
|
code_exist = cache.get(phone, None)
|
||||||
|
if code_exist == code:
|
||||||
|
user = User.objects.filter(phone=phone).first()
|
||||||
|
if user:
|
||||||
|
ret = get_tokens_for_user(user)
|
||||||
|
return Response(ret)
|
||||||
|
raise ParseError('账户不存在或已禁用')
|
||||||
|
raise ParseError('验证码错误')
|
||||||
|
|
|
@ -90,8 +90,8 @@ def notify_event(event: Event):
|
||||||
event (Event): _description_
|
event (Event): _description_
|
||||||
"""
|
"""
|
||||||
# 生成通知文本
|
# 生成通知文本
|
||||||
voice_msg = ''
|
|
||||||
ep = event.employee
|
ep = event.employee
|
||||||
|
params = {'area': event.area.name, 'employee': '', 'event': ''}
|
||||||
if ep:
|
if ep:
|
||||||
ep_name = ep.name
|
ep_name = ep.name
|
||||||
ep_type = '员工'
|
ep_type = '员工'
|
||||||
|
@ -99,17 +99,17 @@ def notify_event(event: Event):
|
||||||
ep_type = '相关方人员'
|
ep_type = '相关方人员'
|
||||||
elif ep.type == 'visitor':
|
elif ep.type == 'visitor':
|
||||||
ep_type = '访客'
|
ep_type = '访客'
|
||||||
voice_msg = '位于{}的{}{},'.format(event.area.name, ep_type, ep_name)
|
params['employee'] = ep_type + ep_name
|
||||||
else:
|
else:
|
||||||
voice_msg = '位于{}的未知人员,'.format(event.area.name)
|
params['employee'] = '未知人员'
|
||||||
for i in event.cates.all():
|
for i in event.cates.all():
|
||||||
voice_msg = voice_msg + i.name + ','
|
params['event'] = params['event'] + i.name + ','
|
||||||
event.voice_msg = voice_msg + '请及时处理'
|
event.voice_msg = '位于{}的{},{}请及时处理'.format(params['area'], params['employee'], params['event'])
|
||||||
event.save()
|
event.save()
|
||||||
# 喇叭播放
|
# 喇叭播放
|
||||||
Thread(target=save_voice_and_speak, args=(event,), daemon=True).start()
|
Thread(target=save_voice_and_speak, args=(event,), daemon=True).start()
|
||||||
# 创建提醒
|
# 创建提醒
|
||||||
Thread(target=create_remind, args=(event,), daemon=True).start()
|
Thread(target=create_remind, args=(event, params), daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
def save_voice_and_speak(event: Event):
|
def save_voice_and_speak(event: Event):
|
||||||
|
@ -135,7 +135,7 @@ def save_voice_and_speak(event: Event):
|
||||||
spClient.speak(event.voice, sps, v_num)
|
spClient.speak(event.voice, sps, v_num)
|
||||||
|
|
||||||
|
|
||||||
def create_remind(event: Event):
|
def create_remind(event: Event, params: dict):
|
||||||
"""
|
"""
|
||||||
创建事件提醒并发送短信/微信
|
创建事件提醒并发送短信/微信
|
||||||
"""
|
"""
|
||||||
|
@ -203,10 +203,11 @@ def create_remind(event: Event):
|
||||||
})
|
})
|
||||||
# 开始发送通知
|
# 开始发送通知
|
||||||
for i in Remind.objects.filter(event=event):
|
for i in Remind.objects.filter(event=event):
|
||||||
if i.notify_setting.sms_enable:
|
if i.notify_setting.sms_enable and i.recipient.employee.phone:
|
||||||
if i.recipient.employee.phone: # 短信通知
|
# 发送短信通知
|
||||||
|
|
||||||
Thread(target=send_sms, args=(i.recipient.employee.phone,
|
Thread(target=send_sms, args=(i.recipient.employee.phone,
|
||||||
'1001', {'code': '5678'}), daemon=True).start()
|
'1003', params), daemon=True).start()
|
||||||
if i.notify_setting.wechat_enable:
|
if i.notify_setting.wechat_enable:
|
||||||
pass
|
pass
|
||||||
event.is_pushed = True
|
event.is_pushed = True
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Generated by Django 3.2.12 on 2022-07-24 05:05
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('system', '0003_alter_user_phone'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='wx_headimg',
|
||||||
|
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='微信头像'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='wx_nickname',
|
||||||
|
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='微信昵称'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='wx_openid',
|
||||||
|
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='微信公众号OpenId'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='wxmp_openid',
|
||||||
|
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='微信小程序OpenId'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -134,6 +134,12 @@ class User(AbstractUser, CommonBModel):
|
||||||
depts = models.ManyToManyField(Dept, through='system.userpost')
|
depts = models.ManyToManyField(Dept, through='system.userpost')
|
||||||
roles = models.ManyToManyField(Role, verbose_name='关联角色')
|
roles = models.ManyToManyField(Role, verbose_name='关联角色')
|
||||||
|
|
||||||
|
# 关联账号
|
||||||
|
wx_openid = models.CharField('微信公众号OpenId', max_length=100, null=True, blank=True)
|
||||||
|
wx_nickname = models.CharField('微信昵称', max_length=100, null=True, blank=True)
|
||||||
|
wx_headimg = models.CharField('微信头像', max_length=100, null=True, blank=True)
|
||||||
|
wxmp_openid = models.CharField('微信小程序OpenId', max_length=100, null=True, blank=True)
|
||||||
|
|
||||||
objects = SoftDeletableUserManager()
|
objects = SoftDeletableUserManager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -462,10 +462,53 @@ class UserViewSet(CustomModelViewSet):
|
||||||
'perms': perms,
|
'perms': perms,
|
||||||
'belong_dept_name': user.belong_dept.name if user.belong_dept else '',
|
'belong_dept_name': user.belong_dept.name if user.belong_dept else '',
|
||||||
'post_name': user.post.name if user.post else '',
|
'post_name': user.post.name if user.post else '',
|
||||||
'is_superuser': user.is_superuser
|
'is_superuser': user.is_superuser,
|
||||||
|
'wxmp_openid': user.wxmp_openid,
|
||||||
|
'wx_openid': user.wx_openid
|
||||||
}
|
}
|
||||||
return Response(data)
|
return Response(data)
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
|
||||||
|
def bind_wxmp(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
绑定微信小程序
|
||||||
|
|
||||||
|
绑定微信小程序
|
||||||
|
"""
|
||||||
|
openid = request.data['openid']
|
||||||
|
user = request.user
|
||||||
|
if user.wxmp_openid != openid:
|
||||||
|
User.objects.filter(wxmp_openid=openid).update(wxmp_openid=None)
|
||||||
|
user.wxmp_openid = openid
|
||||||
|
user.save()
|
||||||
|
return Response({'wxmp_openid': openid})
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
|
||||||
|
def unbind_wxmp(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
解绑微信小程序
|
||||||
|
|
||||||
|
解绑微信小程序
|
||||||
|
"""
|
||||||
|
user = request.user
|
||||||
|
user.wxmp_openid = None
|
||||||
|
user.save()
|
||||||
|
return Response()
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
|
||||||
|
def bind_wx(self, request, pk=None):
|
||||||
|
"""绑定微信公众号
|
||||||
|
|
||||||
|
绑定微信公众号, 用于发送通知
|
||||||
|
"""
|
||||||
|
openid = request.data['openid']
|
||||||
|
user = request.user
|
||||||
|
if user.wx_openid != openid:
|
||||||
|
User.objects.filter(wx_openid=openid).update(wx_openid=None)
|
||||||
|
user.wx_openid = openid
|
||||||
|
user.save()
|
||||||
|
return Response({'wx_openid': openid})
|
||||||
|
|
||||||
|
|
||||||
class FileViewSet(CustomCreateModelMixin, RetrieveModelMixin, ListModelMixin, CustomGenericViewSet):
|
class FileViewSet(CustomCreateModelMixin, RetrieveModelMixin, ListModelMixin, CustomGenericViewSet):
|
||||||
"""文件上传
|
"""文件上传
|
||||||
|
|
|
@ -26,7 +26,7 @@ def send_sms(phone: str, template_code: str, template_param: dict):
|
||||||
# 手机号码
|
# 手机号码
|
||||||
request.add_query_param('PhoneNumbers', phone)
|
request.add_query_param('PhoneNumbers', phone)
|
||||||
# 签名名称
|
# 签名名称
|
||||||
request.add_query_param('SignName', "国家建材网")
|
request.add_query_param('SignName', "曲阳金隅EHS")
|
||||||
# 模板CODE
|
# 模板CODE
|
||||||
request.add_query_param('TemplateCode', template_code)
|
request.add_query_param('TemplateCode', template_code)
|
||||||
# 如果有模板参数 填写模板参数 如果无 无须填写
|
# 如果有模板参数 填写模板参数 如果无 无须填写
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from requests import request
|
||||||
from apps.hrm.models import Employee
|
from apps.hrm.models import Employee
|
||||||
from apps.utils.constants import EXCLUDE_FIELDS
|
from apps.utils.constants import EXCLUDE_FIELDS
|
||||||
from apps.utils.serializers import CustomModelSerializer
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
|
@ -80,7 +81,9 @@ class VpeopleSerializer(CustomModelSerializer):
|
||||||
|
|
||||||
class VisitorRegisterSerializer(serializers.Serializer):
|
class VisitorRegisterSerializer(serializers.Serializer):
|
||||||
name = serializers.CharField(label="姓名")
|
name = serializers.CharField(label="姓名")
|
||||||
username = serializers.CharField(label='用户名', min_length=6)
|
username = serializers.CharField(label="账户名", required=False)
|
||||||
|
wxmp_openid = serializers.CharField(label='微信小程序ID', required=False)
|
||||||
|
wx_openid = serializers.CharField(label='微信公众号ID', required=False)
|
||||||
|
|
||||||
|
|
||||||
class VisitDetailSerializer(CustomModelSerializer):
|
class VisitDetailSerializer(CustomModelSerializer):
|
||||||
|
|
|
@ -75,6 +75,7 @@ class VisitorViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Custo
|
||||||
serializer = self.get_serializer(data=request.data)
|
serializer = self.get_serializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
vdata = serializer.validated_data
|
vdata = serializer.validated_data
|
||||||
|
if vdata.get('username', None): # 如果是用户名注册
|
||||||
user = User.objects.get_queryset(all=True).filter(username=vdata['username']).first()
|
user = User.objects.get_queryset(all=True).filter(username=vdata['username']).first()
|
||||||
if user:
|
if user:
|
||||||
raise ParseError('账号已存在或禁用不可注册')
|
raise ParseError('账号已存在或禁用不可注册')
|
||||||
|
@ -85,6 +86,10 @@ class VisitorViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Custo
|
||||||
type='visitor',
|
type='visitor',
|
||||||
password=password)
|
password=password)
|
||||||
return Response({'user': user.id}, status=201)
|
return Response({'user': user.id}, status=201)
|
||||||
|
elif vdata.get('wxmp_openid', None): # 如果是微信小程序注册
|
||||||
|
pass
|
||||||
|
elif vdata.get('wx_openid', None): # 如果是微信公众号注册
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class VpeopleViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, CustomGenericViewSet):
|
class VpeopleViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, CustomGenericViewSet):
|
||||||
|
|
|
@ -3,18 +3,33 @@ from __future__ import absolute_import, unicode_literals
|
||||||
import importlib
|
import importlib
|
||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
|
from apps.system.models import User
|
||||||
|
from apps.utils.sms import send_sms
|
||||||
from apps.utils.task import CustomTask
|
from apps.utils.task 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
|
||||||
|
|
||||||
myLogger = logging.getLogger('log')
|
myLogger = logging.getLogger('log')
|
||||||
|
|
||||||
|
|
||||||
@shared_task(base=CustomTask)
|
@shared_task(base=CustomTask)
|
||||||
def send_ticket_notice(ticket_id):
|
def send_ticket_notice(ticket_id):
|
||||||
"""
|
"""
|
||||||
发送通知
|
发送通知
|
||||||
"""
|
"""
|
||||||
pass
|
ticket = Ticket.objects.filter(id=ticket_id).first()
|
||||||
|
params = {'workflow': ticket.workflow.name, 'state': ticket.state.name}
|
||||||
|
if ticket:
|
||||||
|
if ticket.participant_type == 1:
|
||||||
|
# 发送短信通知
|
||||||
|
pt = User.objects.filter(id=ticket.participant).first()
|
||||||
|
if pt and pt.phone:
|
||||||
|
send_sms(pt.phone, 1002, params)
|
||||||
|
elif ticket.participant_type == 2:
|
||||||
|
pts = User.objects.filter(id__in=ticket.participant).first()
|
||||||
|
for i in pts:
|
||||||
|
if i.phone:
|
||||||
|
send_sms(i.phone, 1002, params)
|
||||||
|
|
||||||
|
|
||||||
@shared_task(base=CustomTask)
|
@shared_task(base=CustomTask)
|
||||||
|
|
|
@ -394,3 +394,8 @@ BD_SP_SECRET = conf.BD_SP_SECRET
|
||||||
|
|
||||||
# 算法层
|
# 算法层
|
||||||
AI_IP = conf.AI_IP
|
AI_IP = conf.AI_IP
|
||||||
|
|
||||||
|
|
||||||
|
# 微信有关
|
||||||
|
WXMP_APPID = conf.WXMP_APPID
|
||||||
|
WXMP_APPSECRET = conf.WXMP_APPSECRET
|
||||||
|
|
Loading…
Reference in New Issue