chore: initial baseline with P0-safety .gitignore
This commit is contained in:
@@ -0,0 +1,439 @@
|
||||
# =============================================================================
|
||||
# 企微IT智能服务台 — 待办事项 API
|
||||
# =============================================================================
|
||||
# 说明:提供待办事项的 CRUD 接口
|
||||
# 接口列表:
|
||||
# GET /api/todo-items — 获取当前坐席待办列表
|
||||
# GET /api/todo-items/{id} — 获取待办详情
|
||||
# PUT /api/todo-items/{id}/status — 更新待办状态
|
||||
# Mock: 预置示例待办数据,不连接真实外部系统
|
||||
# =============================================================================
|
||||
|
||||
from datetime import datetime
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.utils.response import success_response, AppException
|
||||
|
||||
# 创建路由器
|
||||
router = APIRouter(prefix="/todo-items", tags=["待办事项"])
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# 请求/响应 Schema
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
class TodoStatusUpdateRequest(BaseModel):
|
||||
"""更新待办状态请求 Schema。"""
|
||||
status: str = Field(..., description="新状态: pending/processing/resolved")
|
||||
|
||||
|
||||
class TodoItemResponse(BaseModel):
|
||||
"""待办事项响应 Schema。"""
|
||||
id: str
|
||||
type: str
|
||||
title: str
|
||||
priority: str
|
||||
description: dict
|
||||
status: str
|
||||
assigned_agent_id: Optional[str] = None
|
||||
corp_id: str = ""
|
||||
created_at: str
|
||||
updated_at: str
|
||||
|
||||
|
||||
class TodoItemListResponse(BaseModel):
|
||||
"""待办事项列表响应 Schema。"""
|
||||
items: List[TodoItemResponse]
|
||||
total: int
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Mock 数据 — 预置示例待办(共 20 条,覆盖全部类型 × 状态)
|
||||
# --------------------------------------------------------------------------
|
||||
MOCK_TODO_ITEMS: List[dict] = [
|
||||
# ========== 工单(ticket)==========
|
||||
# 待处理
|
||||
{
|
||||
"id": "todo-001",
|
||||
"type": "ticket",
|
||||
"title": "VPN连接失败 — 财务部张伟",
|
||||
"priority": "urgent",
|
||||
"description": {
|
||||
"employee_name": "张伟",
|
||||
"department": "财务部",
|
||||
"error": "VPN Error 691",
|
||||
"steps": ["检查账号状态", "重置密码", "检查VPN配置"],
|
||||
},
|
||||
"status": "pending",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-05T09:15:00Z",
|
||||
"updated_at": "2026-06-05T09:15:00Z",
|
||||
},
|
||||
{
|
||||
"id": "todo-007",
|
||||
"type": "ticket",
|
||||
"title": "OA系统登录异常 — 人事部刘芳",
|
||||
"priority": "urgent",
|
||||
"description": {
|
||||
"employee_name": "刘芳",
|
||||
"department": "人事部",
|
||||
"error": "页面白屏,控制台报500错误",
|
||||
"affected_count": 15,
|
||||
},
|
||||
"status": "pending",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-05T11:30:00Z",
|
||||
"updated_at": "2026-06-05T11:30:00Z",
|
||||
},
|
||||
{
|
||||
"id": "todo-009",
|
||||
"type": "ticket",
|
||||
"title": "WiFi 无法连接 — 研发部开放区",
|
||||
"priority": "urgent",
|
||||
"description": {
|
||||
"employee_name": "陈明",
|
||||
"department": "研发部",
|
||||
"error": "获取IP失败,提示无法连接到此网络",
|
||||
"location": "3楼开放区",
|
||||
},
|
||||
"status": "pending",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-06T08:00:00Z",
|
||||
"updated_at": "2026-06-06T08:00:00Z",
|
||||
},
|
||||
{
|
||||
"id": "todo-017",
|
||||
"type": "ticket",
|
||||
"title": "鼠标失灵 — 行政部周婷",
|
||||
"priority": "normal",
|
||||
"description": {
|
||||
"employee_name": "周婷",
|
||||
"department": "行政部",
|
||||
"error": "USB鼠标间歇性失灵,更换接口无效",
|
||||
"os": "Windows 11",
|
||||
},
|
||||
"status": "pending",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-06T09:00:00Z",
|
||||
"updated_at": "2026-06-06T09:00:00Z",
|
||||
},
|
||||
# 进行中
|
||||
{
|
||||
"id": "todo-004",
|
||||
"type": "ticket",
|
||||
"title": "邮箱容量告警 — 市场部王强",
|
||||
"priority": "high",
|
||||
"description": {
|
||||
"employee_name": "王强",
|
||||
"department": "市场部",
|
||||
"current_usage": "4.8GB / 5GB",
|
||||
"action": "协助清理或申请扩容",
|
||||
},
|
||||
"status": "processing",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-04T14:30:00Z",
|
||||
"updated_at": "2026-06-05T08:00:00Z",
|
||||
},
|
||||
{
|
||||
"id": "todo-010",
|
||||
"type": "ticket",
|
||||
"title": "ERP系统响应慢 — 全公司反馈",
|
||||
"priority": "high",
|
||||
"description": {
|
||||
"employee_name": "多个员工",
|
||||
"department": "全公司",
|
||||
"error": "ERP首页加载超过15秒",
|
||||
"affected_count": 50,
|
||||
},
|
||||
"status": "processing",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-05T10:00:00Z",
|
||||
"updated_at": "2026-06-05T15:00:00Z",
|
||||
},
|
||||
# 已完成
|
||||
{
|
||||
"id": "todo-011",
|
||||
"type": "ticket",
|
||||
"title": "打印机驱动安装 — 市场部赵敏",
|
||||
"priority": "normal",
|
||||
"description": {
|
||||
"employee_name": "赵敏",
|
||||
"department": "市场部",
|
||||
"device_model": "Canon LBP2900",
|
||||
"solution": "从官网下载驱动并安装,测试打印正常",
|
||||
},
|
||||
"status": "resolved",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-01T09:00:00Z",
|
||||
"updated_at": "2026-06-02T16:00:00Z",
|
||||
},
|
||||
|
||||
# ========== 审批(approval)==========
|
||||
# 待处理
|
||||
{
|
||||
"id": "todo-002",
|
||||
"type": "approval",
|
||||
"title": "软件安装审批 — 设计部PS申请",
|
||||
"priority": "high",
|
||||
"description": {
|
||||
"employee_name": "李娜",
|
||||
"department": "设计部",
|
||||
"software": "Adobe Photoshop 2026",
|
||||
"license_type": "企业许可",
|
||||
},
|
||||
"status": "pending",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-05T10:20:00Z",
|
||||
"updated_at": "2026-06-05T10:20:00Z",
|
||||
},
|
||||
{
|
||||
"id": "todo-005",
|
||||
"type": "approval",
|
||||
"title": "权限升级审批 — 研发部数据库访问",
|
||||
"priority": "high",
|
||||
"description": {
|
||||
"employee_name": "陈明",
|
||||
"department": "研发部",
|
||||
"target_system": "生产数据库",
|
||||
"access_level": "只读",
|
||||
"approver": "研发总监",
|
||||
},
|
||||
"status": "pending",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-05T08:45:00Z",
|
||||
"updated_at": "2026-06-05T08:45:00Z",
|
||||
},
|
||||
{
|
||||
"id": "todo-008",
|
||||
"type": "approval",
|
||||
"title": "新员工设备采购审批 — Q3批次",
|
||||
"priority": "normal",
|
||||
"description": {
|
||||
"batch": "Q3新员工",
|
||||
"count": 5,
|
||||
"items": ["笔记本x5", "显示器x5", "键鼠套装x5"],
|
||||
"budget": "65,000元",
|
||||
},
|
||||
"status": "pending",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-05T07:00:00Z",
|
||||
"updated_at": "2026-06-05T07:00:00Z",
|
||||
},
|
||||
{
|
||||
"id": "todo-018",
|
||||
"type": "approval",
|
||||
"title": "弹性福利审批 — 全体员工Q3",
|
||||
"priority": "normal",
|
||||
"description": {
|
||||
"applicant": "人事部",
|
||||
"type": "弹性福利",
|
||||
"budget_per_person": "3000元",
|
||||
"total_count": 120,
|
||||
},
|
||||
"status": "pending",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-06T07:00:00Z",
|
||||
"updated_at": "2026-06-06T07:00:00Z",
|
||||
},
|
||||
# 进行中
|
||||
{
|
||||
"id": "todo-012",
|
||||
"type": "approval",
|
||||
"title": "预算审批 — IT部Q3采购",
|
||||
"priority": "high",
|
||||
"description": {
|
||||
"department": "IT部",
|
||||
"amount": "280,000元",
|
||||
"items": ["服务器x2", "防火墙x2", "交换机x4"],
|
||||
"approver": "CFO",
|
||||
},
|
||||
"status": "processing",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-04T09:00:00Z",
|
||||
"updated_at": "2026-06-05T14:00:00Z",
|
||||
},
|
||||
# 已完成
|
||||
{
|
||||
"id": "todo-013",
|
||||
"type": "approval",
|
||||
"title": "会议室预订审批 — 销售部Q3客户拜访",
|
||||
"priority": "normal",
|
||||
"description": {
|
||||
"employee_name": "刘军",
|
||||
"department": "销售部",
|
||||
"room": "5楼大会议室",
|
||||
"time": "2026-06-10 14:00-17:00",
|
||||
"result": "已批准",
|
||||
},
|
||||
"status": "resolved",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-05-28T08:00:00Z",
|
||||
"updated_at": "2026-05-29T10:00:00Z",
|
||||
},
|
||||
|
||||
# ========== 设备(device)==========
|
||||
# 待处理
|
||||
{
|
||||
"id": "todo-003",
|
||||
"type": "device",
|
||||
"title": "工位打印机故障 — 3楼A区",
|
||||
"priority": "normal",
|
||||
"description": {
|
||||
"location": "3楼A区打印间",
|
||||
"device_model": "HP LaserJet Pro M404",
|
||||
"issue": "卡纸,无法打印",
|
||||
},
|
||||
"status": "pending",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-05T11:05:00Z",
|
||||
"updated_at": "2026-06-05T11:05:00Z",
|
||||
},
|
||||
{
|
||||
"id": "todo-014",
|
||||
"type": "device",
|
||||
"title": "核心交换机故障 — 机房",
|
||||
"priority": "urgent",
|
||||
"description": {
|
||||
"location": "机房A区",
|
||||
"device_model": "Cisco Catalyst 9300",
|
||||
"issue": "端口3-12全部down,影响2楼所有工位",
|
||||
"affected_count": 45,
|
||||
},
|
||||
"status": "pending",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-06T00:30:00Z",
|
||||
"updated_at": "2026-06-06T00:30:00Z",
|
||||
},
|
||||
# 进行中
|
||||
{
|
||||
"id": "todo-006",
|
||||
"type": "device",
|
||||
"title": "会议室投影仪维修 — 5楼大会议室",
|
||||
"priority": "normal",
|
||||
"description": {
|
||||
"location": "5楼大会议室",
|
||||
"device_model": "Epson EB-X51",
|
||||
"issue": "投影模糊,可能灯泡老化",
|
||||
},
|
||||
"status": "processing",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-03T16:00:00Z",
|
||||
"updated_at": "2026-06-04T10:00:00Z",
|
||||
},
|
||||
{
|
||||
"id": "todo-015",
|
||||
"type": "device",
|
||||
"title": "服务器硬盘更换 — 虚拟化集群",
|
||||
"priority": "high",
|
||||
"description": {
|
||||
"location": "机房B区",
|
||||
"device_model": "Dell R740",
|
||||
"issue": "硬盘预警,需更换并做好数据迁移",
|
||||
"affected_vms": 12,
|
||||
},
|
||||
"status": "processing",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-06-05T09:00:00Z",
|
||||
"updated_at": "2026-06-05T16:00:00Z",
|
||||
},
|
||||
# 已完成
|
||||
{
|
||||
"id": "todo-016",
|
||||
"type": "device",
|
||||
"title": "员工笔记本磁盘扩容 — 人事部吴婷",
|
||||
"priority": "normal",
|
||||
"description": {
|
||||
"employee_name": "吴婷",
|
||||
"department": "人事部",
|
||||
"device_model": "ThinkPad X1 Carbon",
|
||||
"solution": "更换1TB SSD,克隆系统,测试正常",
|
||||
},
|
||||
"status": "resolved",
|
||||
"assigned_agent_id": "agent-001",
|
||||
"corp_id": "ww1234567890",
|
||||
"created_at": "2026-05-20T13:00:00Z",
|
||||
"updated_at": "2026-05-22T17:00:00Z",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# API 接口
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
@router.get("")
|
||||
async def list_todo_items(
|
||||
status: Optional[str] = None,
|
||||
priority: Optional[str] = None,
|
||||
):
|
||||
"""获取当前坐席待办列表。
|
||||
|
||||
支持按状态和优先级过滤。
|
||||
"""
|
||||
items = MOCK_TODO_ITEMS
|
||||
|
||||
# 按状态过滤
|
||||
if status:
|
||||
items = [item for item in items if item["status"] == status]
|
||||
|
||||
# 按优先级过滤
|
||||
if priority:
|
||||
items = [item for item in items if item["priority"] == priority]
|
||||
|
||||
# 按优先级排序:urgent → high → normal
|
||||
priority_order = {"urgent": 0, "high": 1, "normal": 2}
|
||||
items = sorted(items, key=lambda x: priority_order.get(x["priority"], 3))
|
||||
|
||||
return success_response(data={
|
||||
"items": [TodoItemResponse(**item).model_dump() for item in items],
|
||||
"total": len(items),
|
||||
})
|
||||
|
||||
|
||||
@router.get("/{item_id}")
|
||||
async def get_todo_item(item_id: str):
|
||||
"""获取待办事项详情。"""
|
||||
for item in MOCK_TODO_ITEMS:
|
||||
if item["id"] == item_id:
|
||||
return success_response(data=TodoItemResponse(**item).model_dump())
|
||||
raise AppException(code=1003, message=f"待办事项 {item_id} 不存在")
|
||||
|
||||
|
||||
@router.put("/{item_id}/status")
|
||||
async def update_todo_item_status(item_id: str, request: TodoStatusUpdateRequest):
|
||||
"""更新待办事项状态。"""
|
||||
# 校验状态值
|
||||
valid_statuses = {"pending", "processing", "resolved"}
|
||||
if request.status not in valid_statuses:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"无效的状态值: {request.status},合法值为: {valid_statuses}",
|
||||
)
|
||||
|
||||
for item in MOCK_TODO_ITEMS:
|
||||
if item["id"] == item_id:
|
||||
item["status"] = request.status
|
||||
item["updated_at"] = datetime.now().isoformat()
|
||||
return success_response(data=TodoItemResponse(**item).model_dump())
|
||||
|
||||
raise AppException(code=1003, message=f"待办事项 {item_id} 不存在")
|
||||
Reference in New Issue
Block a user