You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
8.3 KiB
197 lines
8.3 KiB
import uuid
|
|
from fastapi import APIRouter, Depends, HTTPException, Request
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from database import get_db
|
|
from models import Task
|
|
from schemas import TaskCreate, TaskUpdate, TaskOut
|
|
from modules.org.router import _get_subordinate_ids
|
|
|
|
router = APIRouter(prefix="/api/tasks", tags=["tasks"])
|
|
|
|
|
|
@router.get("", response_model=list[TaskOut])
|
|
async def get_tasks(request: Request, db: AsyncSession = Depends(get_db)):
|
|
user_ctx = request.state.user
|
|
cur_id = uuid.UUID(user_ctx["id"])
|
|
|
|
if user_ctx["data_scope"] == "all":
|
|
result = await db.execute(select(Task))
|
|
elif user_ctx["data_scope"] == "subordinate_only":
|
|
sub_ids = await _get_subordinate_ids(db, cur_id)
|
|
sub_ids.add(cur_id)
|
|
result = await db.execute(
|
|
select(Task).where(
|
|
(Task.assignee_id.in_(sub_ids)) | (Task.assigner_id.in_(sub_ids))
|
|
)
|
|
)
|
|
else:
|
|
result = await db.execute(
|
|
select(Task).where(
|
|
(Task.assignee_id == cur_id) | (Task.assigner_id == cur_id)
|
|
)
|
|
)
|
|
|
|
tasks = result.scalars().all()
|
|
return [TaskOut(
|
|
id=t.id, title=t.title, content=t.content,
|
|
assigner_id=t.assigner_id, assignee_id=t.assignee_id,
|
|
status=t.status, priority=t.priority, deadline=t.deadline,
|
|
created_at=t.created_at, updated_at=t.updated_at,
|
|
) for t in tasks]
|
|
|
|
|
|
@router.post("", response_model=TaskOut)
|
|
async def create_task(req: TaskCreate, request: Request, db: AsyncSession = Depends(get_db)):
|
|
user_ctx = request.state.user
|
|
task = Task(
|
|
title=req.title, content=req.content,
|
|
assigner_id=uuid.UUID(user_ctx["id"]),
|
|
assignee_id=req.assignee_id,
|
|
priority=req.priority, deadline=req.deadline,
|
|
)
|
|
db.add(task)
|
|
await db.flush()
|
|
|
|
if req.push_to_wecom:
|
|
try:
|
|
import httpx
|
|
from config import settings
|
|
if settings.WECOM_CORP_ID and settings.WECOM_APP_SECRET:
|
|
async with httpx.AsyncClient() as client:
|
|
token_resp = await client.get(
|
|
"https://qyapi.weixin.qq.com/cgi-bin/gettoken",
|
|
params={"corpid": settings.WECOM_CORP_ID, "corpsecret": settings.WECOM_APP_SECRET},
|
|
)
|
|
token_data = token_resp.json()
|
|
access_token = token_data.get("access_token")
|
|
if access_token:
|
|
assignee_result = await db.execute(select(User).where(User.id == req.assignee_id))
|
|
assignee = assignee_result.scalar_one_or_none()
|
|
touser = assignee.wecom_user_id if assignee and assignee.wecom_user_id else req.assignee_id
|
|
msg_resp = await client.post(
|
|
f"https://qyapi.weixin.qq.com/cgi-bin/message/send",
|
|
params={"access_token": access_token},
|
|
json={
|
|
"touser": touser,
|
|
"msgtype": "textcard",
|
|
"agentid": 0,
|
|
"textcard": {
|
|
"title": f"新任务: {task.title}",
|
|
"description": f"任务内容: {task.content}\n优先级: {req.priority}\n截止: {str(req.deadline or '不限')}",
|
|
"url": "",
|
|
},
|
|
},
|
|
)
|
|
resp_data = msg_resp.json()
|
|
if resp_data.get("errcode") == 0:
|
|
task.wecom_message_id = resp_data.get("msgid", f"msg_{uuid.uuid4().hex[:12]}")
|
|
except Exception:
|
|
task.wecom_message_id = f"msg_{uuid.uuid4().hex[:12]}"
|
|
|
|
return TaskOut(
|
|
id=task.id, title=task.title, content=task.content,
|
|
assigner_id=task.assigner_id, assignee_id=task.assignee_id,
|
|
status=task.status, priority=task.priority, deadline=task.deadline,
|
|
created_at=task.created_at, updated_at=task.updated_at,
|
|
)
|
|
|
|
|
|
@router.delete("/{task_id}")
|
|
async def delete_task(task_id: uuid.UUID, request: Request, db: AsyncSession = Depends(get_db)):
|
|
result = await db.execute(select(Task).where(Task.id == task_id))
|
|
task = result.scalar_one_or_none()
|
|
if not task:
|
|
raise HTTPException(404, "任务不存在")
|
|
await db.delete(task)
|
|
await db.commit()
|
|
return {"code": 200, "message": "任务已删除"}
|
|
|
|
|
|
@router.get("/{task_id}", response_model=TaskOut)
|
|
async def get_task(task_id: uuid.UUID, request: Request, db: AsyncSession = Depends(get_db)):
|
|
result = await db.execute(select(Task).where(Task.id == task_id))
|
|
task = result.scalar_one_or_none()
|
|
if not task:
|
|
raise HTTPException(404, "任务不存在")
|
|
return TaskOut(
|
|
id=task.id, title=task.title, content=task.content,
|
|
assigner_id=task.assigner_id, assignee_id=task.assignee_id,
|
|
status=task.status, priority=task.priority, deadline=task.deadline,
|
|
created_at=task.created_at, updated_at=task.updated_at,
|
|
)
|
|
|
|
|
|
@router.put("/{task_id}", response_model=TaskOut)
|
|
async def update_task(task_id: uuid.UUID, req: TaskUpdate, request: Request, db: AsyncSession = Depends(get_db)):
|
|
result = await db.execute(select(Task).where(Task.id == task_id))
|
|
task = result.scalar_one_or_none()
|
|
if not task:
|
|
raise HTTPException(404, "任务不存在")
|
|
|
|
if req.title is not None:
|
|
task.title = req.title
|
|
if req.content is not None:
|
|
task.content = req.content
|
|
if req.status is not None:
|
|
task.status = req.status
|
|
if req.priority is not None:
|
|
task.priority = req.priority
|
|
if req.deadline is not None:
|
|
task.deadline = req.deadline
|
|
|
|
return TaskOut(
|
|
id=task.id, title=task.title, content=task.content,
|
|
assigner_id=task.assigner_id, assignee_id=task.assignee_id,
|
|
status=task.status, priority=task.priority, deadline=task.deadline,
|
|
created_at=task.created_at, updated_at=task.updated_at,
|
|
)
|
|
|
|
|
|
@router.post("/{task_id}/push")
|
|
async def push_task_to_wecom(task_id: uuid.UUID, request: Request, db: AsyncSession = Depends(get_db)):
|
|
result = await db.execute(select(Task).where(Task.id == task_id))
|
|
task = result.scalar_one_or_none()
|
|
if not task:
|
|
raise HTTPException(404, "任务不存在")
|
|
|
|
from config import settings
|
|
wecom_message_id = f"msg_{uuid.uuid4().hex[:12]}"
|
|
|
|
if settings.WECOM_CORP_ID and settings.WECOM_APP_SECRET:
|
|
try:
|
|
import httpx
|
|
async with httpx.AsyncClient() as client:
|
|
token_resp = await client.get(
|
|
"https://qyapi.weixin.qq.com/cgi-bin/gettoken",
|
|
params={"corpid": settings.WECOM_CORP_ID, "corpsecret": settings.WECOM_APP_SECRET},
|
|
)
|
|
token_data = token_resp.json()
|
|
access_token = token_data.get("access_token")
|
|
if access_token:
|
|
assignee_result = await db.execute(select(User).where(User.id == task.assignee_id))
|
|
assignee = assignee_result.scalar_one_or_none()
|
|
touser = assignee.wecom_user_id if assignee and assignee.wecom_user_id else str(task.assignee_id)
|
|
msg_resp = await client.post(
|
|
f"https://qyapi.weixin.qq.com/cgi-bin/message/send",
|
|
params={"access_token": access_token},
|
|
json={
|
|
"touser": touser,
|
|
"msgtype": "textcard",
|
|
"agentid": 0,
|
|
"textcard": {
|
|
"title": f"任务: {task.title}",
|
|
"description": f"状态: {task.status}\n内容: {task.content}\n截止: {str(task.deadline or '不限')}",
|
|
"url": "",
|
|
},
|
|
},
|
|
)
|
|
resp_data = msg_resp.json()
|
|
if resp_data.get("errcode") == 0:
|
|
wecom_message_id = resp_data.get("msgid", wecom_message_id)
|
|
except Exception:
|
|
pass
|
|
|
|
task.wecom_message_id = wecom_message_id
|
|
|
|
return {"code": 200, "message": "已推送到企微", "data": {"wecom_message_id": wecom_message_id}}
|