first commit
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
|
||||
from app.core.crud import CRUDBase
|
||||
from app.schemas.weixin import (
|
||||
WeixinUserCreate,
|
||||
WeixinUserUpdate,
|
||||
)
|
||||
|
||||
from app.models.weixin import WeixinUser
|
||||
from app.schemas.weixin import WeixinUserBindInfo
|
||||
|
||||
from some_sdk.services.binder import feishu_client, xy_client
|
||||
from some_sdk.feishu_sdk.biz.doc import search_file_record
|
||||
from some_sdk.xingyun_sdk.apis.channel import list_channel_group, list_channel_group_user_list, set_online_staff
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
def split_generator(iterable, chunk_size=50):
|
||||
"""
|
||||
将可迭代对象拆分为多个子列表
|
||||
"""
|
||||
chunk = []
|
||||
for item in iterable:
|
||||
chunk.append(item)
|
||||
if len(chunk) == chunk_size:
|
||||
yield chunk
|
||||
chunk = []
|
||||
if chunk:
|
||||
yield chunk
|
||||
|
||||
class WeixinUserController(CRUDBase[WeixinUser, WeixinUserCreate, WeixinUserUpdate]):
|
||||
def __init__(self):
|
||||
super().__init__(model=WeixinUser)
|
||||
|
||||
async def update_from_group(self, internal_members: list[dict]):
|
||||
# 同步更新数据库
|
||||
member_dict = {}
|
||||
for member in internal_members:
|
||||
member = member.copy()
|
||||
userid = member.get('userid', None)
|
||||
member['alias'] = member.pop('name', None)
|
||||
member_dict[userid] = member
|
||||
|
||||
member_list = await self.model.filter(userid__in=member_dict.keys())
|
||||
|
||||
update_list = []
|
||||
update_fileds = ['alias', 'role', 'erp_id', 'erp_name']
|
||||
|
||||
history = {}
|
||||
for member in member_list:
|
||||
member_info = member_dict.pop(member.userid, history.get(member.userid, {}))
|
||||
if member.role in ['owner', 'admin', 'follower']:
|
||||
continue
|
||||
if not member_info: continue
|
||||
history[member.userid] = member_info
|
||||
|
||||
updated = {}
|
||||
for field in update_fileds:
|
||||
old_value = getattr(member, field)
|
||||
if field not in member_info:
|
||||
continue
|
||||
value = member_info.get(field)
|
||||
if old_value != value:
|
||||
setattr(member, field, value)
|
||||
updated[f'{field}:{str(old_value)}'] = value
|
||||
if updated:
|
||||
logger.info(f'用户 {member.userid} 更新关系为 {updated}')
|
||||
update_list.append(member)
|
||||
if update_list:
|
||||
await self.model.bulk_update(update_list, fields=update_fileds)
|
||||
|
||||
# 新增用户
|
||||
create_list = []
|
||||
for userid, member_info in member_dict.items():
|
||||
create_list.append(WeixinUser(
|
||||
**member_info,
|
||||
name=member_info.get('alias'),
|
||||
))
|
||||
if create_list:
|
||||
await self.model.bulk_create(create_list)
|
||||
|
||||
return {
|
||||
'update_count': len(update_list),
|
||||
'create_count': len(create_list),
|
||||
}
|
||||
|
||||
|
||||
async def bind_user(self, user_in: WeixinUserBindInfo):
|
||||
if not user_in.userid:
|
||||
raise ValueError("用户ID不能为空")
|
||||
if user_in.erp_id == 0:
|
||||
del user_in.erp_id
|
||||
|
||||
user = await self.model.filter(userid=user_in.userid).first()
|
||||
if not user:
|
||||
await self.create({**user_in.model_dump(exclude_unset=True), 'name': user_in.username})
|
||||
return {}
|
||||
await self.model.filter(userid=user_in.userid).update(**user_in.model_dump(exclude_unset=True))
|
||||
|
||||
async def set_user_online(self, class_type: str, date: datetime):
|
||||
daysTimestamp = lambda nowStamp, days: nowStamp + days * 24 * 60 * 60 * 1000
|
||||
formatDate = lambda ts: datetime.fromtimestamp(ts / 1000).strftime('%Y-%m-%d')
|
||||
|
||||
today = int(date.timestamp() * 1000)
|
||||
logger.info(f'设置 {formatDate(today)} 班次为 {class_type} 的员工为在线状态')
|
||||
yestoday = daysTimestamp(today, -1)
|
||||
tomorrow = daysTimestamp(today, 1)
|
||||
|
||||
# 查询日期为 yestoday 到 后天 之间的所有记录
|
||||
resp = search_file_record(
|
||||
feishu_client,
|
||||
app_token="V4qebMG2kamCWMslJmdcQMbtngW",
|
||||
table_id="tblKgjc3F2jZ2inC",
|
||||
filter={
|
||||
"conjunction": "and",
|
||||
"conditions": [{
|
||||
"field_name": "日期",
|
||||
"operator": "isGreater",
|
||||
"value": ["ExactDate", yestoday]
|
||||
},{
|
||||
"field_name": "日期",
|
||||
"operator": "isLess",
|
||||
"value": ["ExactDate", daysTimestamp(today, 2)]
|
||||
}]
|
||||
},
|
||||
)
|
||||
|
||||
set_result = {}
|
||||
current_class = (class_type, today)
|
||||
next_class = ('早班', tomorrow) if class_type == '晚班' else ('晚班', today)
|
||||
|
||||
current_class_mapping = {}
|
||||
next_class_mapping = {}
|
||||
async for data in resp:
|
||||
user = data.get('data', {})
|
||||
user_online = ((user.get('班次') or '')[:2], user.get('日期', ''))
|
||||
# logger.info(f'用户{user.get("接量成员", "")} 在线时间为{user_online} 当前班次为{current_class} 下一班次为{next_class}')
|
||||
class_group = user.get('组别', '')
|
||||
class_mapping = None
|
||||
# 当前班次
|
||||
if user_online == current_class:
|
||||
class_mapping = current_class_mapping
|
||||
set_result[class_group] = {"接量成员": user.get('接量成员', '')}
|
||||
# 下一班次
|
||||
elif user_online == next_class:
|
||||
class_mapping = next_class_mapping
|
||||
if class_mapping is None:
|
||||
continue
|
||||
|
||||
if user.get('id', ''):
|
||||
class_mapping.setdefault(class_group, [])
|
||||
class_mapping[class_group].append(user.get('id', ''))
|
||||
|
||||
assert current_class_mapping, f"根据日期{current_class[1]} {formatDate(current_class[1])}没有找到班次为{class_type}的员工"
|
||||
logger.info(f'根据日期{current_class[1]} {formatDate(current_class[1])} 找到班次为{class_type}的员工: {current_class_mapping} {set_result}')
|
||||
if next_class_mapping:
|
||||
logger.info(f'根据日期{next_class[1]} {formatDate(next_class[1])} 找到班次为{next_class[0]}的员工: {next_class_mapping}')
|
||||
|
||||
group_list = list_channel_group(xy_client)
|
||||
async for group in group_list:
|
||||
title = group.get("title", "")
|
||||
if title not in current_class_mapping:
|
||||
continue
|
||||
|
||||
set_result[title] = set_result.get(title) or {}
|
||||
try:
|
||||
user_list = list_channel_group_user_list(xy_client, groupId=group.get("id", ""))
|
||||
|
||||
huomaList = []
|
||||
async for user in user_list:
|
||||
huomaList.append(user.get('id'))
|
||||
|
||||
if not huomaList:
|
||||
logger.error(f'组 {title} {group.get("id", "")} 中没有员工')
|
||||
continue
|
||||
|
||||
is_faild, is_success = [], []
|
||||
# 按照50个一组设置在线状态
|
||||
for i in range(0, len(huomaList), 50):
|
||||
result = await set_online_staff(xy_client, allDayUserIds=','.join(current_class_mapping[title]), huomaList=huomaList[i:i+50])
|
||||
|
||||
is_faild += list(filter(lambda x: x.get('errorMsg', ''), result.get('data', [])))
|
||||
is_success += list(filter(lambda x: x.get('success', True), result.get('data', [])))
|
||||
|
||||
is_faild = set(is_faild)
|
||||
if is_faild: logger.error(f'设置失败的员工: {is_faild}')
|
||||
else: logger.info(f'全部员工设置成功')
|
||||
|
||||
set_result[title] = {
|
||||
'success': len(is_success),
|
||||
'fail': len(is_faild),
|
||||
**set_result[title]
|
||||
}
|
||||
except Exception as e:
|
||||
logger.exception(f'设置群 {group.get("id", "")} 中员工 {huomaList} 为在线状态失败: {e}')
|
||||
|
||||
return set_result, next_class_mapping
|
||||
|
||||
weixin_user_controller = WeixinUserController()
|
||||
Reference in New Issue
Block a user