From 41c19242cf642f7336167c43f6120a7b1c99d36f Mon Sep 17 00:00:00 2001 From: duxingchen Date: Fri, 28 Aug 2026 13:22:56 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=93=8D=E4=BD=9C=E7=BB=9F=E8=AE=A1):=20?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=85=A8=E9=83=A8=E4=BA=BA=E5=91=98=E8=80=8C?= =?UTF-8?q?=E9=9D=9E=E4=BB=85=E6=9C=89=E6=93=8D=E4=BD=9C=E7=9A=84=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - get_user_operations 先取全部 IRIS 人员清单,再合并各自操作次数 - 无操作的显示 0,避免只看得到当前有操作记录的人(如只看自己) --- backend/app/services/dashboard_service.py | 69 ++++++++++++++++------- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/backend/app/services/dashboard_service.py b/backend/app/services/dashboard_service.py index e8ac73e..62c57fa 100644 --- a/backend/app/services/dashboard_service.py +++ b/backend/app/services/dashboard_service.py @@ -483,7 +483,10 @@ async def get_user_operations( since: datetime | None = None, until: datetime | None = None, ) -> list[UserOperation]: - """上帝视角 — 统计每个人员的操作次数(按时段过滤 task_logs)。 + """上帝视角 — 统计**全部人员**的操作次数(按时段过滤 task_logs)。 + + 返回所有 IRIS 部门人员(该时段无操作的计 0),并追加有操作记录但不在 + 人员清单中的账号(如历史/已离职)。 操作口径: - 接收: action_type='receive' @@ -491,11 +494,13 @@ async def get_user_operations( - 上传备注: action_type='record'(工人手动追加的进度记录) """ from app.models.task_log import TaskLog + from app.core.mom_database import MomSessionLocal + from sqlalchemy import text + # ── 1. 统计 task_logs 操作次数(按 operator_id 聚合)── rcv = func.count().filter(TaskLog.action_type == "receive") cpl = func.count().filter(TaskLog.action_type == "complete") rcd = func.count().filter(TaskLog.action_type == "record") - total_expr = rcv + cpl + rcd stmt = ( select(TaskLog.operator_id, rcv.label("receive"), cpl.label("complete"), rcd.label("record")) @@ -504,7 +509,6 @@ async def get_user_operations( TaskLog.operator_id.isnot(None), ) .group_by(TaskLog.operator_id) - .order_by(total_expr.desc()) ) if since: stmt = stmt.where(TaskLog.created_at >= since) @@ -512,27 +516,54 @@ async def get_user_operations( stmt = stmt.where(TaskLog.created_at <= until) result = await db.execute(stmt) - rows = result.all() + op_map = {r[0]: (r[1] or 0, r[2] or 0, r[3] or 0) for r in result.all()} - ids = [r[0] for r in rows if r[0]] - name_map: dict[str, str] = {} - if ids: - from app.services.mom_cache import get_display_names - name_map = get_display_names(ids) + # ── 2. 获取全部 MOM 用户清单(IRIS 部门)── + users: list[dict] = [] + try: + dbm = MomSessionLocal() + try: + rows = dbm.execute(text(""" + SELECT username, SPLIT_PART(username, '/', 1) AS full_name + FROM sys_user WHERE department = 'IRIS' + """)).fetchall() + except Exception: + rows = dbm.execute(text(""" + SELECT username, SPLIT_PART(username, '/', 1) AS full_name + FROM sys_user + """)).fetchall() + finally: + dbm.close() + for row in rows: + short = row.username.split("/")[-1] if "/" in row.username else row.username + users.append({"username": short, "full_name": row.full_name or short}) + except Exception: + users = [] + # ── 3. 合并:所有人员 + 有操作但不在清单的账号 ── + merged: dict[str, dict] = {} + for u in users: + merged[u["username"]] = {"name": u["full_name"], "rcv": 0, "cpl": 0, "rcd": 0} + for uid, (r, c, rd) in op_map.items(): + if uid in merged: + merged[uid]["rcv"] = r + merged[uid]["cpl"] = c + merged[uid]["rcd"] = rd + else: + merged[uid] = {"name": uid, "rcv": r, "cpl": c, "rcd": rd} + + # ── 4. 组装 + 排序(总次数降序,无操作的排在最后)── items: list[UserOperation] = [] - for row in rows: - receive = row[1] or 0 - transfer = row[2] or 0 - record = row[3] or 0 + for uid, v in merged.items(): items.append(UserOperation( - user_id=row[0], - user_name=name_map.get(row[0], row[0]), - receive_count=receive, - transfer_count=transfer, - record_count=record, - total=receive + transfer + record, + user_id=uid, + user_name=v["name"], + receive_count=v["rcv"], + transfer_count=v["cpl"], + record_count=v["rcd"], + total=v["rcv"] + v["cpl"] + v["rcd"], )) + items.sort(key=lambda x: x.total, reverse=True) return items