chore: initial baseline with P0-safety .gitignore

This commit is contained in:
Simon
2026-06-14 16:49:18 +08:00
commit 63262292d7
510 changed files with 146008 additions and 0 deletions
+439
View File
@@ -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} 不存在")