102 lines
3.2 KiB
Python
102 lines
3.2 KiB
Python
"""OA 任务创建后服务号通知(commit 后异步)。"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
import threading
|
|
from datetime import datetime
|
|
from typing import Iterable, List
|
|
|
|
from app.core.database import SessionLocal
|
|
from app.models.models import OaInstance, OaTask, SysUser
|
|
from app.services.wechat_mp_message import send_oa_approval_notify, send_oa_cc_notify
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def build_oa_detail_pagepath(*, instance_id: str, task_id: str, mode: str) -> str:
|
|
# 无前导 /
|
|
return (
|
|
f"pages/oa/webview/index?instanceId={instance_id}"
|
|
f"&taskId={task_id}&mode={mode}"
|
|
)
|
|
|
|
|
|
def _send_one(db, task: OaTask) -> None:
|
|
uid = (task.assignee_user_id or "").strip()
|
|
if not uid:
|
|
return
|
|
user = db.query(SysUser).filter(SysUser.id == uid, SysUser.del_flag == 0).first()
|
|
mp = (getattr(user, "wx_mp_openid", None) or "").strip() if user else ""
|
|
if not mp:
|
|
logger.info("oa wx notify skip: no mp_openid user=%s task=%s", uid, task.id)
|
|
return
|
|
inst = (
|
|
db.query(OaInstance)
|
|
.filter(OaInstance.id == task.instance_id, OaInstance.del_flag == 0)
|
|
.first()
|
|
)
|
|
title = (inst.title if inst else "") or (task.node_name or "审批")
|
|
applicant = ""
|
|
if inst and inst.initiator_user_id:
|
|
ini = db.query(SysUser).filter(SysUser.id == inst.initiator_user_id).first()
|
|
applicant = (ini.nick_name if ini else "") or ""
|
|
time_text = datetime.now().strftime("%Y-%m-%d %H:%M")
|
|
node_name = task.node_name or ""
|
|
if task.task_type == "approval" and (task.status or "") == "pending":
|
|
pagepath = build_oa_detail_pagepath(
|
|
instance_id=task.instance_id, task_id=task.id, mode="approve"
|
|
)
|
|
send_oa_approval_notify(
|
|
mp_openid=mp,
|
|
pagepath=pagepath,
|
|
title=title,
|
|
applicant=applicant,
|
|
node_name=node_name,
|
|
time_text=time_text,
|
|
)
|
|
elif task.task_type == "cc":
|
|
pagepath = build_oa_detail_pagepath(
|
|
instance_id=task.instance_id, task_id=task.id, mode="view"
|
|
)
|
|
send_oa_cc_notify(
|
|
mp_openid=mp,
|
|
pagepath=pagepath,
|
|
title=title,
|
|
applicant=applicant,
|
|
node_name=node_name,
|
|
time_text=time_text,
|
|
)
|
|
|
|
|
|
def notify_oa_tasks_sync(task_ids: Iterable[str]) -> None:
|
|
ids = [str(x).strip() for x in task_ids if str(x).strip()]
|
|
if not ids:
|
|
return
|
|
db = None
|
|
try:
|
|
db = SessionLocal()
|
|
tasks = (
|
|
db.query(OaTask)
|
|
.filter(OaTask.id.in_(ids), OaTask.del_flag == 0)
|
|
.all()
|
|
)
|
|
for t in tasks:
|
|
try:
|
|
_send_one(db, t)
|
|
except Exception:
|
|
logger.exception("oa wx notify failed task=%s", t.id)
|
|
except Exception:
|
|
logger.exception("oa wx notify batch failed ids=%s", ids)
|
|
finally:
|
|
if db is not None:
|
|
db.close()
|
|
|
|
|
|
def schedule_oa_task_notifies(task_ids: List[str]) -> None:
|
|
ids = [str(x).strip() for x in (task_ids or []) if str(x).strip()]
|
|
if not ids:
|
|
return
|
|
threading.Thread(
|
|
target=notify_oa_tasks_sync, args=(ids,), daemon=True, name="oa-wx-notify"
|
|
).start()
|