Files
Neo-ZQYY/apps/backend/app/routers/xcx_tasks.py
Neo 6f8f12314f feat: 累积功能变更 — 聊天集成、租户管理、小程序更新、ETL 增强、迁移脚本
包含多个会话的累积代码变更:
- backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔
- admin-web: ETL 状态页、任务管理、调度配置、登录优化
- miniprogram: 看板页面、聊天集成、UI 组件、导航更新
- etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强
- tenant-admin: 项目初始化
- db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8)
- packages/shared: 枚举和工具函数更新
- tools: 数据库工具、报表生成、健康检查
- docs: PRD/架构/部署/合约文档更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 00:03:48 +08:00

116 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
小程序任务路由 —— 任务列表、任务详情、置顶、放弃、取消放弃。
端点清单:
- GET /api/xcx/tasks — 获取任务列表 + 绩效概览TASK-1
- GET /api/xcx/tasks/by-member/{member_id} — 按会员查询最高优先级 active 任务详情
- GET /api/xcx/tasks/{task_id} — 获取任务详情完整版TASK-2
- POST /api/xcx/tasks/{id}/pin — 置顶任务
- POST /api/xcx/tasks/{id}/unpin — 取消置顶
- POST /api/xcx/tasks/{id}/abandon — 放弃任务
- POST /api/xcx/tasks/{id}/restore — 恢复任务
所有端点均需 JWTapproved 状态)。
"""
from __future__ import annotations
from fastapi import APIRouter, Depends, Query
from app.auth.dependencies import CurrentUser
from app.middleware.permission import require_approved, require_permission
from app.schemas.xcx_tasks import (
AbandonRequest,
TaskDetailResponse,
TaskListResponse,
)
from app.services import task_manager
from app.trace.decorators import trace_service
router = APIRouter(prefix="/api/xcx/tasks", tags=["小程序任务"])
@router.get("", response_model=TaskListResponse)
@trace_service("获取任务列表", "Get task list")
async def get_tasks(
status: str = Query("pending", pattern="^(pending|completed|abandoned)$"),
page: int = Query(1, ge=1),
page_size: int = Query(20, ge=1, le=200),
# CHANGE 2026-03-27 | 权限改造 W4统一权限保护
user: CurrentUser = Depends(require_permission("view_tasks")),
):
"""获取任务列表 + 绩效概览。"""
return await task_manager.get_task_list_v2(
user.user_id, user.site_id, status, page, page_size
)
@router.get("/by-member/{member_id}", response_model=TaskDetailResponse)
@trace_service("按会员查询任务详情", "Get task detail by member")
async def get_task_by_member(
member_id: int,
user: CurrentUser = Depends(require_permission("view_tasks")),
):
"""按 member_id 查询当前助教的最高优先级 active 任务详情。"""
return await task_manager.get_task_by_member(
member_id, user.user_id, user.site_id
)
@router.get("/{task_id}", response_model=TaskDetailResponse)
@trace_service("获取任务详情", "Get task detail")
async def get_task_detail(
task_id: int,
user: CurrentUser = Depends(require_permission("view_tasks")),
):
"""获取任务详情完整版。"""
return await task_manager.get_task_detail(
task_id, user.user_id, user.site_id
)
@router.post("/{task_id}/pin")
@trace_service("置顶任务", "Pin task")
async def pin_task(
task_id: int,
user: CurrentUser = Depends(require_permission("view_tasks")),
):
"""置顶任务。"""
result = await task_manager.pin_task(task_id, user.user_id, user.site_id)
return {"is_pinned": result["is_pinned"]}
@router.post("/{task_id}/unpin")
@trace_service("取消置顶", "Unpin task")
async def unpin_task(
task_id: int,
user: CurrentUser = Depends(require_permission("view_tasks")),
):
"""取消置顶。"""
result = await task_manager.unpin_task(task_id, user.user_id, user.site_id)
return {"is_pinned": result["is_pinned"]}
@router.post("/{task_id}/abandon")
@trace_service("放弃任务", "Abandon task")
async def abandon_task(
task_id: int,
body: AbandonRequest,
user: CurrentUser = Depends(require_permission("view_tasks")),
):
"""放弃任务(需填写原因)。"""
return await task_manager.abandon_task(
task_id, user.user_id, user.site_id, body.reason
)
@router.post("/{task_id}/restore")
@trace_service("恢复任务", "Restore task")
async def restore_task(
task_id: int,
user: CurrentUser = Depends(require_permission("view_tasks")),
):
"""取消放弃,恢复为活跃状态。"""
return await task_manager.cancel_abandon(task_id, user.user_id, user.site_id)