feat: 双Token认证(Access 2h/Refresh 7d) + 通知系统(转交/驳回自动推送)
This commit is contained in:
@ -7,6 +7,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from app.models.task import Task, TaskRecord, TASK_STATUS_PENDING, TASK_STATUS_WIP, TASK_STATUS_COMPLETED, TASK_STATUS_REJECTED, TASK_STATUS_CANCELED, TASK_STATUS_ARCHIVED
|
||||
from app.models.notification import Notification, NOTIFY_TRANSFER, NOTIFY_REJECT
|
||||
from app.core.time_utils import get_beijing_time
|
||||
from app.models.product import Product
|
||||
from app.models.task_log import TaskLog
|
||||
@ -288,6 +289,12 @@ async def end_task(
|
||||
"""
|
||||
task = await _get_task_or_404(db, task_id)
|
||||
|
||||
# 校验:仅 SPAWN 协助分支可以结束,主分支(TRANSFER/RECOVERY)不能通过此接口终止
|
||||
if not task.parent_task_id:
|
||||
raise HTTPException(status_code=409, detail="根任务无法结束,请使用完工转交")
|
||||
if task.task_type != "SPAWN":
|
||||
raise HTTPException(status_code=409, detail="仅协助分支可以结束,主分支请使用完工转交")
|
||||
|
||||
# 校验:必须等待所有协助分支完成
|
||||
await _check_children_done(db, task_id)
|
||||
|
||||
@ -562,7 +569,7 @@ async def reject_task(
|
||||
task_name=task.task_name,
|
||||
assignee_id=rework_assignee_id,
|
||||
status=TASK_STATUS_PENDING,
|
||||
task_type="TRANSFER",
|
||||
task_type=task.task_type, # 🚀 继承被驳回任务的基因:主线→主线,协助→协助
|
||||
notify_parent_on_complete=task.notify_parent_on_complete,
|
||||
is_rework=True,
|
||||
)
|
||||
@ -576,6 +583,24 @@ async def reject_task(
|
||||
remark=f"返工任务(驳回自「{task.task_name}」,原因: {request.reason}),分配给 {rework_assignee_id}",
|
||||
)
|
||||
|
||||
# 🔔 通知:品质驳回
|
||||
product_sn = ""
|
||||
try:
|
||||
product_result = await db.execute(select(Product).where(Product.id == task.product_id))
|
||||
p = product_result.scalar_one_or_none()
|
||||
if p:
|
||||
product_sn = p.serial_number or ""
|
||||
except Exception:
|
||||
pass
|
||||
if rework_assignee_id:
|
||||
db.add(Notification(
|
||||
user_id=rework_assignee_id,
|
||||
title="🔴 品质驳回提醒",
|
||||
content=f"产品 [{product_sn}] 的「{task.task_name}」被驳回,原因: {request.reason}",
|
||||
type=NOTIFY_REJECT,
|
||||
task_id=rework_task.id,
|
||||
))
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(task)
|
||||
|
||||
@ -697,6 +722,21 @@ async def transfer_task(
|
||||
operator_id=operator_id,
|
||||
remark=request.note or f"由任务「{task.task_name}」裂变转交创建,分配给 {nt.assignee_id}",
|
||||
)
|
||||
# 🔔 通知:新任务派发
|
||||
if nt.assignee_id:
|
||||
product_sn = ""
|
||||
try:
|
||||
if product:
|
||||
product_sn = product.serial_number or ""
|
||||
except Exception:
|
||||
pass
|
||||
db.add(Notification(
|
||||
user_id=nt.assignee_id,
|
||||
title=f"🟢 新任务派发",
|
||||
content=f"产品 [{product_sn}] 的「{nt.task_name}」任务已分配给你",
|
||||
type=NOTIFY_TRANSFER,
|
||||
task_id=nt.id,
|
||||
))
|
||||
|
||||
# --- 更新 Product 的 current_location_id ---
|
||||
product_result = await db.execute(
|
||||
|
||||
Reference in New Issue
Block a user