Files
dataelement--bisheng/src/backend/bisheng/api/v1/mark_task.py
T
2026-07-13 13:36:36 +08:00

261 lines
9.1 KiB
Python

from collections import deque
from typing import Optional
from fastapi import APIRouter, Depends, Request
from loguru import logger
from bisheng.api.v1.schema.mark_schema import MarkData, MarkTaskCreate
from bisheng.api.v1.schemas import resp_200, resp_500
from bisheng.common.dependencies.user_deps import UserPayload
from bisheng.database.models.mark_app_user import MarkAppUser, MarkAppUserDao
from bisheng.database.models.mark_record import MarkRecord, MarkRecordDao
from bisheng.database.models.mark_task import MarkTask, MarkTaskDao, MarkTaskRead, MarkTaskStatus
from bisheng.database.models.message import ChatMessageDao
from bisheng.database.models.session import MessageSessionDao
from bisheng.database.models.user_group import UserGroupDao
from bisheng.user.domain.models.user import UserDao
from bisheng.utils.linked_list import DoubleLinkList
router = APIRouter(prefix='/mark', tags=['Mark'])
@router.get('/list')
def list(request: Request,
status: Optional[int] = None,
page_size: int = 10,
page_num: int = 1,
login_user: UserPayload = Depends(UserPayload.get_login_user)):
"""
Nonadmin Can only see their own marked and unlabeled
"""
groups = UserGroupDao.get_user_admin_group(login_user.user_id)
if login_user.is_admin():
task_list, count = MarkTaskDao.get_task_list(page_size=page_size, page_num=page_num, status=status,
create_id=None, user_id=None)
else:
task_list, count = MarkTaskDao.get_task_list(page_size=page_size, page_num=page_num, status=status,
create_id=login_user.user_id if groups else None,
user_id=login_user.user_id)
result_list = []
for task in task_list:
record = MarkRecordDao.get_count(task.id)
process_list = []
user_count = {}
for c in task.process_users.split(","):
user = UserDao.get_user(int(c))
process_count = "{}:{}".format(user.user_name, 0)
user_count[int(c)] = process_count
for c in record:
process_count = "{}:{}".format(c.create_user, c.user_count)
user_count[c.create_id] = process_count
for c in user_count:
process_list.append(user_count[c])
result_list.append(MarkTaskRead(**task.model_dump(), mark_process=process_list))
result = {"list": result_list, "total": count}
return resp_200(data=result)
@router.get('/get_status')
async def get_status(task_id: int, chat_id: str,
login_user: UserPayload = Depends(UserPayload.get_login_user)):
record = MarkRecordDao.get_record(task_id, chat_id)
if not record:
return resp_200(data={"status": ""})
if login_user.user_id == record.create_id:
is_self = True
else:
is_self = False
result = {"status": record.status, "is_self": is_self}
return resp_200(result)
@router.post('/create_task')
async def create(task_create: MarkTaskCreate, login_user: UserPayload = Depends(UserPayload.get_login_user)):
"""
Apps and users are in a many-to-many relationship, relying on one director record
"""
task = MarkTask(create_id=login_user.user_id,
create_user=login_user.user_name,
app_id=",".join(task_create.app_list),
process_users=",".join(task_create.user_list)
)
MarkTaskDao.create_task(task)
user_app = [MarkAppUser(task_id=task.id, create_id=login_user.user_id, app_id=app, user_id=user) for app in
task_create.app_list for user in task_create.user_list]
MarkAppUserDao.create_task(user_app)
return resp_200(data="ok")
@router.get('/get_user')
async def get_user(task_id: int):
"""
Query under this app All Users
"""
# accordingtype Query different sessions
task = MarkTaskDao.get_task_byid(task_id)
user_list = []
for u in task.process_users.split(","):
user = UserDao.get_user(int(u))
user_list.append(user)
return resp_200(data=user_list)
@router.post('/mark')
async def mark(data: MarkData,
login_user: UserPayload = Depends(UserPayload.get_login_user)):
"""
Flag task as current user and cannot be overwritten by others
flow_type flow assistant
"""
# record = MarkRecordDao.get_record(data.task_id,data.session_id)
# if record:
# return resp_500(data="Already flagged")
session_info = MessageSessionDao.get_one(data.session_id)
if session_info:
data.flow_type = session_info.flow_type
db_r = MarkRecordDao.get_record(data.task_id, data.session_id)
if db_r:
if data.status == MarkTaskStatus.DEFAULT.value:
MarkRecordDao.del_task_chat(task_id=db_r.task_id, session_id=db_r.session_id)
return resp_200(data="ok")
db_r.status = data.status
MarkRecordDao.update_record(db_r)
else:
# Not marked No data recorded
if data.status == MarkTaskStatus.DEFAULT.value:
return resp_200(data="ok")
record_info = MarkRecord(create_user=login_user.user_name, create_id=login_user.user_id,
session_id=data.session_id, task_id=data.task_id, status=data.status,
flow_type=data.flow_type)
# Create an article User callout record
MarkRecordDao.create_record(record_info)
task = MarkTaskDao.get_task_byid(task_id=data.task_id)
msg_list = ChatMessageDao.get_msg_by_flows(task.app_id.split(","))
# m_list = [msg.chat_id for msg in msg_list]
m_list = msg_list
r_list = MarkRecordDao.get_list_by_taskid(data.task_id)
app_record = [r.session_id for r in r_list]
m_list = [s.strip() for s in m_list if s.strip()]
app_record = [s.strip() for s in app_record if s.strip()]
m_list.sort()
app_record.sort()
logger.info("m_list={} app_record={}", m_list, app_record)
if m_list == app_record:
MarkTaskDao.update_task(data.task_id, MarkTaskStatus.DONE.value)
else:
MarkTaskDao.update_task(data.task_id, MarkTaskStatus.ING.value)
return resp_200(data="ok")
@router.get('/get_record')
async def get_record(chat_id: str, task_id: int):
record = MarkRecordDao.get_record(task_id, chat_id)
return resp_200(data=record)
@router.get("/next")
async def pre_or_next(chat_id: str, action: str, task_id: int,
login_user: UserPayload = Depends(UserPayload.get_login_user)):
"""
prev or next
"""
if action not in ["prev", "next"]:
return resp_500(data="actionParameter salah")
result = {"task_id": task_id}
if action == "prev":
record = MarkRecordDao.get_prev_task(login_user.user_id, task_id)
top_queue = deque()
bottom_queue = deque()
if record:
queue = top_queue
for r in record:
if r.session_id == chat_id:
queue = bottom_queue
continue
queue.append(r)
logger.info("top_queue={} bottom_queue={}", top_queue, bottom_queue)
if len(top_queue) == 0 and len(bottom_queue) == 0:
return resp_200()
record = bottom_queue.popleft() if len(bottom_queue) else top_queue.popleft()
chat = MessageSessionDao.get_one(record.session_id)
result["chat_id"] = chat.chat_id
result["flow_type"] = chat.flow_type
result["flow_id"] = chat.flow_id
return resp_200(data=result)
else:
task = MarkTaskDao.get_task_byid(task_id)
record = MarkRecordDao.get_list_by_taskid(task_id)
chat_list = [r.session_id for r in record]
msg = MessageSessionDao.filter_session(flow_ids=task.app_id.split(","), exclude_chats=chat_list)
linked = DoubleLinkList()
k_list = {}
for m in msg:
k_list[m.chat_id] = m
linked.append(m.chat_id)
cur = linked.find(chat_id)
if not k_list:
return resp_200()
logger.info("k_list={} cur={}", k_list, cur)
if cur:
if cur.next is None:
if linked.length() == 1 and linked.head().data == chat_id:
return resp_200()
cur = k_list[linked.head().data]
else:
cur = k_list[cur.next.data]
result["chat_id"] = cur.chat_id
result["flow_id"] = cur.flow_id
result['flow_type'] = cur.flow_type
return resp_200(data=result)
else:
cur = k_list[linked.head().data]
result['flow_type'] = cur.flow_type
result["chat_id"] = cur.chat_id
result["flow_id"] = cur.flow_id
return resp_200(data=result)
return resp_200()
@router.delete('/del')
def del_task(request: Request, task_id: int, login_user: UserPayload = Depends(UserPayload.get_login_user)):
"""
Nonadmin Can only see their own marked and unlabeled
"""
MarkTaskDao.delete_task(task_id)
MarkRecordDao.del_record(task_id)
return resp_200(data="ok")