# app/api/wechat.py from fastapi import APIRouter, Query, BackgroundTasks, Depends from tortoise.expressions import Q from app.controllers.weixin.utils import get_buyer_nick_from_group_name from app.controllers.weixin.group import weixin_group_chat_controller from app.controllers.weixin.customer import weixin_customer_controller from app.controllers.weixin.user import weixin_user_controller from app.controllers.action import action_controller from app.schemas.weixin import WeixinUserBindInfo, WeixinOrderBindInfo, TriggerWeixinGroupChat, WeixinOrderRemark, WeixinCustomerFilter, WeixinCustomerCreate from app.http_base import unified_resp from app.schemas.apis import Paginate from .base import get_weixin_user from .base import WeixinUserDep from app.models.msg import ActionType from datetime import datetime, timedelta from app.utils.event_task import event_manager, EventType from app.core.cache import cache_if # from app.schemas.crm import CrmBindInfoCreate, CrmBindInfoUpdate import logging logger = logging.getLogger(__name__) router = APIRouter(prefix="") # 废弃 @router.post("/list_user_join_group", summary="加载用户加入的群聊列表") @unified_resp async def list_user_join_group(customer: WeixinCustomerCreate, weixin_user: dict = Depends(get_weixin_user)): print(f'list_user_join_group, customer: {customer}') # user_join_group = await weixin_group_chat_controller.list_user_join_group(customer.xingyun_id) user_join_group = await weixin_customer_controller.get_user_detail(customer.weixin_id) return user_join_group @router.get("/list_customer", summary="加载客户列表") @unified_resp async def list_msg(paginate: Paginate = Depends(), order: str = "-id", customer_filter: WeixinCustomerFilter = Depends(), weixin_user: dict = Depends(get_weixin_user)): print('paginate', paginate.page, paginate.page_size) print('customer_filter', customer_filter) print('weixin_user', weixin_user.username, weixin_user.userid) q = Q() data = {} if customer_filter.order_id is not None: q &= Q(order_id=customer_filter.order_id) data['order_id'] = customer_filter.order_id if customer_filter.shop_name is not None: q &= Q(shop_name__contains=customer_filter.shop_name) data['shop_name'] = customer_filter.shop_name if customer_filter.union_id is not None: # 是或者的关系 weixin_id\xingyun_id\taobao_id\union_id q &= (Q(weixin_id=customer_filter.union_id) | Q(xingyun_id=customer_filter.union_id) | Q(taobao_id=customer_filter.union_id) | Q(union_id=customer_filter.union_id)) data['union_id'] = customer_filter.union_id if customer_filter.union_name is not None: # 是或者的关系 weixin_username\xingyun_name\taobao_name q &= (Q(weixin_name__contains=customer_filter.union_name) | Q(xingyun_name__contains=customer_filter.union_name) | Q(taobao_name__contains=customer_filter.union_name)) data['union_name'] = customer_filter.union_name if customer_filter.xingyun_tags is not None: q &= Q(xingyun_tags__contains={"tagName": customer_filter.xingyun_tags}) data['xingyun_tags'] = customer_filter.xingyun_tags if customer_filter.has_order is not None: q &= Q(order_id__isnull=not customer_filter.has_order) data['has_order'] = customer_filter.has_order # 打印查询条件明文 print('raw query', data) total, user_list = await weixin_customer_controller.list(paginate.page, paginate.page_size, order=[order], search=q) lists = [] for user in user_list: user_info = user.dump_dict() lists.append(user_info) user_info['user_join_group'] = await weixin_customer_controller.get_user_detail(user.weixin_id) return {"count": total, "lists": lists} # 群聊入口 @router.get("/get_user_info", summary="通过群ID获取到群信息以及同步数据到本地") @unified_resp async def get_external_group_chat_info(userid: str): weixin_user = await weixin_user_controller.model.filter(userid=userid).first() return weixin_user.to_dict() # 群聊入口 @router.get("/group/get_external_group_chat_info", summary="通过群ID获取到群信息以及同步数据到本地") @unified_resp async def get_external_group_chat_info(chat_id: str, background_tasks: BackgroundTasks): group_info = await weixin_group_chat_controller.get_external_group_chat_info(chat_id) if group_info['detect_update']: await event_manager.publish_async(EventType.GROUP_CHAT_UPDATED, group_info, background_tasks) return group_info @router.get("/group/get_order_relative_user_list_by_weixin_groupid", summary="通过群ID获取订单相关用户列表") @unified_resp async def get_order_relative_user_list_by_weixin_groupid(chat_id: str = Query(..., description="群ID"), background_tasks: BackgroundTasks = None): async with cache_if(f'order:chat:{chat_id}', ttl=60*3) as cache: if cache.hit: order_list = cache.value if order_list: order_list[0] = await weixin_group_chat_controller.get_user_detail_by_order(order_id=order_list[0]['ctid']) else: order_list = await _get_order_relative_user_list_by_weixin_groupid(chat_id, background_tasks) cache.set(order_list) return order_list async def _get_order_relative_user_list_by_weixin_groupid(chat_id: str = Query(..., description="群ID"), background_tasks: BackgroundTasks = None): group_info = await weixin_group_chat_controller.get_external_group_chat_info(chat_id) logger.info(f'group_info: {group_info}') if group_info['detect_update'] or True: await event_manager.publish_async(EventType.GROUP_CHAT_UPDATED, group_info, background_tasks) name = group_info.get('name') logger.debug(f'群聊名称: {name} chat_id: {chat_id}') user_order_list = [] external_member_list = group_info['external_member_list'] if external_member_list: userid_list = [member['userid'] for member in external_member_list if member.get('userid')] logger.debug(f'userid_list: {userid_list}') customer_list = await weixin_customer_controller.model.filter(weixin_id__in=userid_list, taobao_id__isnull=False).all() for customer in customer_list: buyer = customer.taobao_name or customer.taobao_id if not buyer: continue logger.debug(f'buyer: {buyer}') result, order_list = await weixin_group_chat_controller.get_order_relative_user_list_by_weixin_userid(customer.weixin_id) if not result: continue user_order_list = order_list break # return await weixin_group_chat_controller.get_order_relative_user_list_by_weixin_group_name(buyer_nick) # return await weixin_group_chat_controller.get_order_relative_user_list_by_weixin_group_buyer_id(buyer_id) if not user_order_list: logger.warning(f'群内成员没有订单,将根据群聊名称 {name} 来获取订单相关用户列表') assert name, "当前群聊未命名" buyer_nick = get_buyer_nick_from_group_name(name) logger.debug(f'name: {name}; buyer_nick: {buyer_nick}') assert buyer_nick, "当前群聊未命名" user_order_list = await weixin_group_chat_controller.get_order_relative_user_list_by_weixin_group_name(buyer_nick) if group_info['detect_update']: try: await action_controller.check_create_group_action_is_done(group_info, user_order_list[0]['shop_name'] if user_order_list else None) except Exception as e: logger.exception(f'检查创建群聊动作是否完成失败: {e}') return user_order_list # @router.get("/group/load_xingyun_group_info", summary="通过群ID获取订单相关用户列表") # @unified_resp # async def load_xingyun_group_info(): # return await weixin_group_chat_controller.load_xingyun_group_info() @router.get("/get_user_detail_by_order", summary="通过订单ID获取订单相关用户详情") @unified_resp async def get_user_detail_by_order(order_id: str): return await weixin_group_chat_controller.get_user_detail_by_order(order_id) @router.get("/get_erp_order_log", summary="通过订单ID获取订单日志") @unified_resp async def get_erp_order_log(order_id: str, login_user: WeixinUserDep): result = await weixin_group_chat_controller.get_erp_order_log(order_id) try: await action_controller.new_action(ActionType.VIEW_ERP_LOG, login_user, order_id=order_id) except Exception as e: logger.exception(e) logger.error(f'员工操作日志记录失败') return result # 通过私聊入口 @router.get("/get_order_relative_user_list_by_weixin_userid", summary="通过用户ID获取订单相关用户列表") @unified_resp async def get_order_relative_user_list_by_weixin_userid(userid: str, background_tasks: BackgroundTasks): result, order_list = await weixin_group_chat_controller.get_order_relative_user_list_by_weixin_userid(userid) if not result: await event_manager.publish_async(EventType.OPEN_PERSONAL_CHAT, {"userid": userid}, background_tasks) return order_list @router.post("/bind_order", summary="绑定订单") @unified_resp async def bind_order(bind_in: WeixinOrderBindInfo, background_tasks: BackgroundTasks, login_user: WeixinUserDep): bind_in.userid = bind_in.userid.strip() bind_in.order_id = bind_in.order_id.strip() logger.info(f'【绑定订单】userid: {bind_in.userid}; order_id: {bind_in.order_id}') old_info = await weixin_customer_controller.model.filter(weixin_id=bind_in.userid, order_id=bind_in.order_id).first() assert not old_info, "不用为客户绑定相同订单" result, orders = await weixin_customer_controller.bind_order(bind_in) try: await action_controller.new_action(ActionType.BIND_ORDER, login_user, **bind_in.model_dump(exclude_unset=True)) if orders and bind_in.remark: orders = [{ "title": order.get("title"), "ctid": order.get("ctid"), "trade_no": order.get("trade_no"), "remark": order.get("remark", ""), } for order in orders] need_monitor_order_list = await weixin_customer_controller.remark_order_by_order_id(remark=bind_in.remark, orders=orders) await action_controller.new_action(ActionType.WRITE_REMARK, login_user, order_id=bind_in.order_id, remark=bind_in.remark, orders=need_monitor_order_list, done=len(need_monitor_order_list) == 0) except Exception as e: logger.exception(e) logger.error(f'员工操作日志记录失败') # 用户触发绑定时,及时同步到星云有客中 await event_manager.publish_async(EventType.BIND_ORDER_FOR_USER, orders[0] if orders else {}, background_tasks) return result @router.post("/remark_order", summary="为订单添加额外备注") @unified_resp async def remark_order(remark_in: WeixinOrderRemark, login_user: WeixinUserDep): if not remark_in.remark: logger.warning(f'订单备注为空,将不执行任何操作') return False try: need_monitor_order_list = await weixin_customer_controller.remark_order_by_order_id(remark=remark_in.remark, order_id=remark_in.order_id) await action_controller.new_action(ActionType.WRITE_REMARK, login_user, order_id=remark_in.order_id, remark=remark_in.remark, orders=need_monitor_order_list, done=len(need_monitor_order_list) == 0) except Exception as e: logger.exception(e) logger.error(f'员工操作日志记录失败') return bool(need_monitor_order_list) @router.post("/bind_user", summary="用户绑定客户") @unified_resp async def bind_user(bind_info: WeixinUserBindInfo, login_user: WeixinUserDep): result = await weixin_customer_controller.bind_user(bind_info=bind_info) try: await action_controller.new_action(ActionType.BIND_USER, login_user, **bind_info.model_dump(exclude_unset=True)) except Exception as e: logger.exception(e) logger.error(f'员工操作日志记录失败') return result @router.post("/bind_inner_user", summary="用户绑定内部公司成员(erp和企微架构不同)") @unified_resp async def bind_inner_user(bind_info: WeixinUserBindInfo, login_user: WeixinUserDep): result = await weixin_user_controller.bind_user(bind_info) try: await action_controller.new_action(ActionType.BIND_USER, login_user, **bind_info.model_dump(exclude_unset=True)) except Exception as e: logger.exception(e) logger.error(f'员工操作日志记录失败') return result @router.get("/load_recent_user_from_xingyun", summary="加载最近N天的客户数据") @unified_resp async def load_user_from_xingyun(days_range: int = Query(3, description="加载最近N天的客户数据")): now_time = datetime.now() start_time = (now_time - timedelta(days=days_range)).replace(hour=0, minute=0, second=0, microsecond=0) end_time = now_time + timedelta(days=1) return await weixin_customer_controller.load_user_from_xingyun(add_time_start=start_time, add_time_end=end_time) @router.get("/load_all_user_from_xingyun", summary="加载所有客户数据") @unified_resp async def load_all_user_from_xingyun(background_tasks: BackgroundTasks): await event_manager.publish_async(EventType.SYNC_XINGYUN_CONTACT_INFO, {}, background_tasks) return True @router.post("/trigger_create_group_chat", summary="触发创建群聊") @unified_resp async def trigger_create_group_chat(group_chat: TriggerWeixinGroupChat, login_user: WeixinUserDep): try: await action_controller.new_action(ActionType.CREATE_GROUP, login_user, **group_chat.model_dump(exclude_unset=True)) if group_chat.order_id: username = login_user.english_name or login_user.nickname username = username.split('-印刷')[0] remark = f'企微联系{username}拉群' need_monitor_order_list = await weixin_customer_controller.remark_order_by_order_id(remark=remark, order_id=group_chat.order_id) await action_controller.new_action(ActionType.WRITE_REMARK, login_user, order_id=group_chat.order_id, remark=remark, orders=need_monitor_order_list, done=len(need_monitor_order_list) == 0) except Exception as e: logger.exception(e) logger.error(f'员工操作日志记录失败') return True