fix(操作统计): 返回全部人员而非仅有操作的人

- get_user_operations 先取全部 IRIS 人员清单,再合并各自操作次数
- 无操作的显示 0,避免只看得到当前有操作记录的人(如只看自己)
This commit is contained in:
2026-08-28 13:22:56 +08:00
parent 9471c1b7c5
commit 41c19242cf

View File

@ -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