время изменения

This commit is contained in:
dv 2026-04-09 11:40:51 +03:00
parent 0d0cec1f9f
commit cabc7b865a
4 changed files with 23 additions and 2 deletions

View file

@ -3,7 +3,7 @@ import re
from typing import Annotated from typing import Annotated
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
from sqlalchemy import select, distinct from sqlalchemy import func, select, distinct
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
@ -91,7 +91,18 @@ async def list_objects(
query = query.where(Object.client == client) query = query.where(Object.client == client)
query = query.order_by(Object.city, Object.client, Object.name) query = query.order_by(Object.city, Object.client, Object.name)
result = await db.execute(query) result = await db.execute(query)
return result.scalars().all() objects = result.scalars().all()
if objects:
ids = [o.id for o in objects]
cnt_rows = await db.execute(
select(Device.object_id, func.count(Device.id).label("cnt"))
.where(Device.object_id.in_(ids))
.group_by(Device.object_id)
)
counts = dict(cnt_rows.all())
for obj in objects:
obj.device_count = counts.get(obj.id, 0)
return objects
@router.post("", response_model=ObjectRead, status_code=status.HTTP_201_CREATED) @router.post("", response_model=ObjectRead, status_code=status.HTTP_201_CREATED)

View file

@ -76,6 +76,7 @@ class ObjectRead(BaseModel):
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
tags: list[TagRead] = [] tags: list[TagRead] = []
device_count: int = 0
model_config = {"from_attributes": True} model_config = {"from_attributes": True}

View file

@ -13,6 +13,8 @@ export interface ObjectItem {
is_active: boolean is_active: boolean
tags: { id: number; name: string; color: string }[] tags: { id: number; name: string; color: string }[]
created_at: string created_at: string
updated_at: string
device_count: number
} }
export interface ObjectMeta { export interface ObjectMeta {

View file

@ -27,6 +27,7 @@ import {
Upload, Upload,
message, message,
} from 'antd' } from 'antd'
import dayjs from 'dayjs'
import { useMemo, useState } from 'react' import { useMemo, useState } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { import {
@ -212,6 +213,12 @@ export function ObjectsPage({ mode }: Props) {
<Tag key={t.id} color={t.color} style={{ margin: 0 }}>{t.name}</Tag> <Tag key={t.id} color={t.color} style={{ margin: 0 }}>{t.name}</Tag>
))} ))}
{!obj.is_active && <Tag color="default">Неактивен</Tag>} {!obj.is_active && <Tag color="default">Неактивен</Tag>}
<Typography.Text type="secondary" style={{ fontSize: 12, whiteSpace: 'nowrap' }}>
{obj.device_count} уст.
</Typography.Text>
<Typography.Text type="secondary" style={{ fontSize: 12, whiteSpace: 'nowrap' }}>
изм. {dayjs(obj.updated_at).format('DD.MM.YY HH:mm')}
</Typography.Text>
{mode === 'inventory' && ( {mode === 'inventory' && (
<Space size={4}> <Space size={4}>
<Button size="small" icon={<EditOutlined />} onClick={() => openEdit(obj)} /> <Button size="small" icon={<EditOutlined />} onClick={() => openEdit(obj)} />