fix(时长): 所有时长计算排除非工作日 + 修复两处时区多算8小时
- get_wip_tasks/get_people_workload/get_people_history/product active_duration_hours/analytics 均改用 working_duration_hours - 修复 get_wip_tasks 与 active_duration_hours 的 naive 时间误标北京时间 bug(DB实存UTC,原多算8小时) - 每处读取 holidays 表排除配置的放假日期
This commit is contained in:
@ -209,7 +209,12 @@ async def get_dashboard_stats(
|
||||
async def get_wip_tasks(db: AsyncSession, limit: int = 20) -> list[WipTask]:
|
||||
from app.models.task import Task, TASK_STATUS_PENDING, TASK_STATUS_WIP
|
||||
from app.models.product import Product
|
||||
from app.core.time_utils import get_beijing_time, BEIJING_TZ
|
||||
from app.models.holiday import Holiday
|
||||
from app.core.time_utils import get_beijing_time, to_beijing, working_duration_hours
|
||||
|
||||
# 读取节假日(排除非工作日)
|
||||
hres = await db.execute(select(Holiday.day))
|
||||
holidays = {r[0] for r in hres}
|
||||
|
||||
stmt = (
|
||||
select(Task, Product.serial_number, Product.external_serial, Product.material_name, Product.spec_model)
|
||||
@ -231,12 +236,9 @@ async def get_wip_tasks(db: AsyncSession, limit: int = 20) -> list[WipTask]:
|
||||
for task, product_sn, ext_sn, mat_name, spec in rows:
|
||||
start = task.received_at or task.created_at
|
||||
if start:
|
||||
if start.tzinfo is None:
|
||||
start = start.replace(tzinfo=BEIJING_TZ)
|
||||
else:
|
||||
start = start.astimezone(BEIJING_TZ)
|
||||
hours = round((now - start).total_seconds() / 3600, 1)
|
||||
recv_str = start.strftime("%m-%d %H:%M")
|
||||
start_bj = to_beijing(start) # 🚀 naive 按 UTC 转北京时间(修复多算8小时)
|
||||
hours = working_duration_hours(start_bj, now, holidays)
|
||||
recv_str = start_bj.strftime("%m-%d %H:%M")
|
||||
else:
|
||||
hours = 0
|
||||
recv_str = ""
|
||||
@ -683,7 +685,12 @@ async def get_people_workload(db: AsyncSession) -> list[PersonWorkload]:
|
||||
"""上帝视角 — 按负责人聚合当前在制品设备(WIP/PENDING 任务,product 去重,含滞留时长)。"""
|
||||
from app.models.task import Task, TASK_STATUS_PENDING, TASK_STATUS_WIP
|
||||
from app.models.product import Product
|
||||
from app.core.time_utils import get_beijing_time, BEIJING_TZ
|
||||
from app.models.holiday import Holiday
|
||||
from app.core.time_utils import get_beijing_time, to_beijing, working_duration_hours
|
||||
|
||||
# 读取节假日(排除非工作日)
|
||||
hres = await db.execute(select(Holiday.day))
|
||||
holidays = {r[0] for r in hres}
|
||||
|
||||
stmt = (
|
||||
select(
|
||||
@ -749,7 +756,7 @@ async def get_people_workload(db: AsyncSession) -> list[PersonWorkload]:
|
||||
devices: list[PersonDevice] = []
|
||||
for product_id, e in prods.items():
|
||||
dt = e["earliest_dt"]
|
||||
hours = round((now - dt).total_seconds() / 3600, 1) if dt else 0.0
|
||||
hours = working_duration_hours(dt, now, holidays) if dt else 0.0
|
||||
received_str = dt.strftime("%m-%d %H:%M") if dt else None
|
||||
devices.append(PersonDevice(
|
||||
product_id=product_id,
|
||||
@ -787,11 +794,16 @@ async def get_people_history(
|
||||
"""上帝视角 — 人员效能与工时台账(平铺 Task 明细,含 WIP/PENDING/COMPLETED)。"""
|
||||
from app.models.task import Task, TASK_STATUS_WIP, TASK_STATUS_PENDING, TASK_STATUS_COMPLETED
|
||||
from app.models.product import Product
|
||||
from app.core.time_utils import get_beijing_time, BEIJING_TZ
|
||||
from app.core.time_utils import get_beijing_time, BEIJING_TZ, to_beijing, working_duration_hours
|
||||
from app.models.holiday import Holiday
|
||||
from sqlalchemy import func
|
||||
|
||||
now = get_beijing_time()
|
||||
|
||||
# 读取节假日(排除非工作日)
|
||||
hres = await db.execute(select(Holiday.day))
|
||||
holidays = {r[0] for r in hres}
|
||||
|
||||
# ── 关联 TaskRecord:最新有效备注 + 记录总数 ──
|
||||
from app.models.task import TaskRecord
|
||||
from sqlalchemy import and_, or_
|
||||
@ -915,7 +927,7 @@ async def get_people_history(
|
||||
else:
|
||||
end_dt = now
|
||||
completed_str = None
|
||||
hours = round((end_dt - received_dt).total_seconds() / 3600, 1) if received_dt else 0.0
|
||||
hours = working_duration_hours(received_dt, end_dt, holidays) if received_dt else 0.0
|
||||
records.append(PersonHistoryRecord(
|
||||
task_id=str(row[0]),
|
||||
task_name=row[1] or "",
|
||||
|
||||
Reference in New Issue
Block a user