yzk_wechat_event/apps/jqr/tasks.py

280 lines
12 KiB
Python
Raw Normal View History

2023-12-13 15:27:31 +08:00
from celery import shared_task
2023-12-15 17:42:32 +08:00
from datetime import datetime, date, timedelta
2023-12-13 17:25:23 +08:00
import logging
2023-12-15 17:42:32 +08:00
from django.db.models import Count, Sum, When, Case, Value
2023-12-14 18:43:01 +08:00
from apps.jqr.choices import JqrWechatbizuserinfoDeleteTypeChoices, JqrAddTypeChoices
2023-12-15 17:42:32 +08:00
from apps.qc.choices import QcWechatbizeventAddcontactIsDeleteChoices, QcQrcodesEditLogOperateTypeChoices, \
QcQrcodesEditLogTypeChoices
from apps.qc.models import QcWechatbizeventAddcontact, QcQrcodes, QcWechatbizuserinfo, QcQrcodesEditLog, QcCorpinfo
2023-12-14 18:43:01 +08:00
from apps.jqr.models import JqrExternalFollowUser, JqrExternalUser
2023-12-15 17:42:32 +08:00
from apps.qc.utils import generate_qrcode_by_qrcode
from apps.warning.models import QcWarningRule
2023-12-14 18:43:01 +08:00
from libs.wechat import WechatWorkerUtil
2023-12-13 17:25:23 +08:00
logger = logging.getLogger('apps')
2023-12-13 15:27:31 +08:00
2023-12-14 18:43:01 +08:00
@shared_task(name='save_add_contact', queue='contact')
def save_add_contact(data, corpinfo, *args, **kwargs):
state = data.get('state')
2023-12-15 17:42:32 +08:00
userid = data.get('userid')
2023-12-15 09:30:38 +08:00
if state and state.startswith('mg') and '_' in state:
2023-12-14 18:43:01 +08:00
[_, _, qrcodeid] = state.split('_')
data['qrcodeid'] = qrcodeid
2023-12-15 17:42:32 +08:00
# TODO 异步执行
check_qrcode(qrcodeid, userid, corpinfo)
2023-12-14 18:43:01 +08:00
externaluserid = data.get('externaluserid')
corpid = data.get('corpid')
QcWechatbizeventAddcontact.objects.update_or_create(
userid=userid,
externaluserid=externaluserid,
corpid=corpid,
defaults={
**data,
'isdelete': QcWechatbizeventAddcontactIsDeleteChoices.NOT_DELETE,
2023-12-15 09:32:22 +08:00
'deletetime': None,
'ctime': datetime.now(),
2023-12-14 18:43:01 +08:00
}
)
edit_add_contact.delay(data, corpinfo, *args, **kwargs)
@shared_task(name='edit_add_contact', queue='contact')
def edit_add_contact(data, corpinfo, *args, **kwargs):
# 更新 关系表
externaluserid = data.get('externaluserid')
corpid = corpinfo.get('corpid')
appsecret = corpinfo.get('appsecret')
wechat_worker = WechatWorkerUtil(corpid, appsecret)
cursor = ''
while cursor is not None:
success, data = wechat_worker.get_external_contact(externaluserid, cursor=cursor)
if not success:
logger.error(f'获取外部联系人信息失败,{data}')
return
(external_contact, follow_user, cursor) = data
JqrExternalUser.objects.update_or_create(
corpid=corpid,
external_userid=externaluserid,
defaults={
**external_contact,
'addtype': JqrAddTypeChoices.EVENT_CALLBACK,
'deletetype': None,
'dtime': None
}
)
for follow_info in follow_user:
userid = follow_info.get('userid')
follow_info['tags'] = [tag.get('tag_id') for tag in follow_info.get('tags', [])]
JqrExternalFollowUser.objects.update_or_create(
userid=userid,
corpid=corpid,
external_userid=externaluserid,
defaults={
**follow_info,
'addtype': JqrAddTypeChoices.EVENT_CALLBACK,
'deletetype': None,
'dtime': None
}
)
@shared_task(name='delete_add_contact', queue='contact')
def delete_add_contact(data, corpinfo, *args, **kwargs):
userid = data.get('userid')
externaluserid = data.get('externaluserid')
corpid = data.get('corpid')
agentid = data.get('agentid')
# 更新add_contact 表删除字段
QcWechatbizeventAddcontact.objects.filter(userid=userid, externaluserid=externaluserid, corpid=corpid,
agentid=agentid).update(
isdelete=QcWechatbizeventAddcontactIsDeleteChoices.DELETED,
deletetime=datetime.now()
)
JqrExternalFollowUser.objects.filter(userid=userid, external_userid=externaluserid, corpid=corpid).update(
deletetype=JqrWechatbizuserinfoDeleteTypeChoices.EVENT_CALLBACK,
dtime=datetime.now()
)
2023-12-15 17:42:32 +08:00
@shared_task(name='check_qrcode', queue='qrcode')
def check_qrcode(qrcodeid, userid, corpinfo):
qrcode = QcQrcodes.objects.get(id=qrcodeid)
users = qrcode.userids
corpid = qrcode.corpid
userinfo = QcWechatbizuserinfo.objects.get(corpid=corpid, userid=userid)
today = date.today()
# 账号当前活码的接粉情况
count_info = QcWechatbizeventAddcontact.objects.filter(corpid=corpinfo.get('corpid'), userid=userid).values(
'corpid',
'userid').aggregate(
total_count=Count('*'),
today_count=Sum(
Case(
When(ctime__date=today, then=Value(1)),
default=Value(0),
)
),
qrcode_count=Sum(
Case(
When(qrcodeid=qrcodeid, then=Value(1)),
default=Value(0),
)
),
qrcode_today_count=Sum(
Case(
When(qrcodeid=qrcodeid, ctime__date=today, then=Value(1)),
default=Value(0),
)
)
)
# 该账号总共加了多少人
total_count = count_info.get('total_count', 0)
# 该账号今天加了多少人
today_count = count_info.get('today_count', 0)
# 该账号当前活码加了多少人
qrcode_count = count_info.get('qrcode_count')
# 该账号今天当前活码加了多少人
qrcode_today_count = count_info.get('qrcode_today_count')
# 该用户所有活码每日新增好友上限
limitaddusercount = userinfo.limitaddusercount
# 该用户总加粉总上限
totallimitaddusercount = userinfo.totallimitaddusercount
# 该用户当前活码上限
user_qrcode_limitcount = None
for user in users:
if user.get('userid') == userid:
user_qrcode_limitcount = user.get('limitcount')
break
user_count = len(users)
offline_user_count = len(
[user for user in users if user.get('isonline') == QcQrcodesEditLogOperateTypeChoices.OFFLINE])
# 该账号是否需要下线
need_offline = False
# 该账号今天当前活码加的人数 大于 该用户当前活码上限
if user_qrcode_limitcount is not None and qrcode_today_count > user_qrcode_limitcount > 0:
need_offline = True
if total_count is not None and total_count > totallimitaddusercount > 0:
need_offline = True
if today_count is not None and today_count > limitaddusercount > 0:
need_offline = True
if need_offline:
if user_count - offline_user_count > 1:
for user in users:
if user.get('userid') == userid:
user['isonline'] = QcQrcodesEditLogOperateTypeChoices.OFFLINE
user['endtime'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
qrcode.save()
# 重新生成活码, 请求企微api更新活码
generate_qrcode_by_qrcode(qrcode, corpinfo, is_update=True)
# 生成活码修改记录
QcQrcodesEditLog.objects.create(
userid=userid,
uid=qrcode.uid,
corpid=qrcode.corpid,
agentid=qrcode.agentid,
qrcodeid=qrcode.pk,
detail={
'totallimit': totallimitaddusercount,
'daliylimit': limitaddusercount,
'qrcodelimit': user_qrcode_limitcount,
'addcount': total_count,
'qrcodeaddcount': qrcode_count,
'qrcode_today_count': qrcode_today_count,
},
type=QcQrcodesEditLogTypeChoices.AUTO,
operatetype=QcQrcodesEditLogOperateTypeChoices.OFFLINE,
)
# 接粉号报警检测任务
@shared_task(name='check_follow_user', queue='check_follow_user')
def check_follow_user():
batch_size = 1000
warning_rules = QcWarningRule.objects.filter(is_on=True, is_delete=False)
count = warning_rules.count()
for i in range(0, count, batch_size):
for warning_rule in warning_rules[i:i + batch_size]:
users = warning_rule.userids
users = [{"alias": "饿了么小霸王155", "corpid": "ww4450b72962300373", "userid": "mg12976",
"username": "[155]5G-8-1-汪琦"},
{"alias": "饿了么小霸王157", "corpid": "ww4450b72962300373", "userid": "mg04598",
"username": "[157]5G-3-2-汪潇"}]
if users and len(users) > 0:
corpid = users[0]["corpid"]
userid_map = {user.get('userid'): user for user in users}
warning_interval = warning_rule.warning_interval
now = datetime.now()
warning_interval_ago = now - timedelta(minutes=warning_interval)
user_count_info = QcWechatbizeventAddcontact.objects.filter(corpid=corpid,
userid__in=list(userid_map.keys())).values(
'corpid',
'userid').annotate(
warning_interval_count=Sum(
Case(
When(ctime__gte=warning_interval_ago, then=Value(1)),
default=Value(0),
)
),
).values('userid', 'warning_interval_count')
for user_count in user_count_info:
if user_count.get('warning_interval_count') < 1:
user = userid_map.get(user_count.get('userid'))
text = f"账号 {user.get('userid')} {user.get('username')} {user.get('alias')}{warning_interval}分钟内没进粉"
log_info = {
'corpid': corpid,
'userid': user_count.get('userid'),
}
print(warning_rule.warning_setting)
# 活码上线
@shared_task(name='online_qrcode', queue='qrcode')
def online_qrcode():
batch_size = 1000
qrcodes = QcQrcodes.objects.all()
for i in range(0, qrcodes.count(), batch_size):
for qrcode in qrcodes[i:i + batch_size]:
users = qrcode.userids
need_generate_code = False
# 获取下线的用户
userids = []
for user in users:
if user.get('isonline') == QcQrcodesEditLogOperateTypeChoices.OFFLINE:
userids.append(user.get('userid'))
need_generate_code = True
user['isonline'] = QcQrcodesEditLogOperateTypeChoices.ONLINE
user['endtime'] = None
# 上线时间
user['starttime'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
if need_generate_code:
qrcode.save()
corp = QcCorpinfo.objects.get(corpid=qrcode.corpid, agentid=qrcode.agentid)
# 重新生成活码, 请求企微api更新活码
generate_qrcode_by_qrcode(qrcode, corp, is_update=True)
# 生成活码修改记录
for userid in userids:
QcQrcodesEditLog.objects.create(
userid=userid,
uid=qrcode.uid,
corpid=qrcode.corpid,
agentid=qrcode.agentid,
qrcodeid=qrcode.pk,
detail={
'totallimit': 0,
'daliylimit': 0,
'qrcodelimit': 0,
'addcount': 0,
'qrcodeaddcount': 0,
'qrcode_today_count': 0,
},
type=QcQrcodesEditLogTypeChoices.AUTO,
operatetype=QcQrcodesEditLogOperateTypeChoices.ONLINE,
)