260725_1
This commit is contained in:
@@ -86,6 +86,63 @@ async def get_latest_section_options(
|
||||
return options if isinstance(options, dict) else None
|
||||
|
||||
|
||||
async def list_recent_company_projects(
|
||||
connection: aiomysql.Connection, company_id: int, exclude_project_id: UUID
|
||||
) -> list[dict[str, Any]]:
|
||||
"""같은 회사의 최근 프로젝트 5개(최근 갱신순, 현재·삭제 프로젝트 제외).
|
||||
|
||||
설계값 보유 여부와 무관하게 보여준다 — 선택 시 설계값 조회에서 없으면 안내한다.
|
||||
"""
|
||||
async with connection.cursor(aiomysql.DictCursor) as cursor:
|
||||
await cursor.execute(
|
||||
"""
|
||||
SELECT p.id AS project_id, p.name AS name
|
||||
FROM projects p
|
||||
WHERE p.company_id = %s
|
||||
AND p.id <> %s
|
||||
AND p.deleted_at IS NULL
|
||||
ORDER BY p.updated_at DESC
|
||||
LIMIT 5
|
||||
""",
|
||||
(company_id, str(exclude_project_id)),
|
||||
)
|
||||
rows = await cursor.fetchall()
|
||||
return [{"project_id": row["project_id"], "name": row["name"]} for row in rows]
|
||||
|
||||
|
||||
async def get_project_standard_cross_section(
|
||||
connection: aiomysql.Connection, company_id: int, project_id: UUID
|
||||
) -> dict[str, Any] | None:
|
||||
"""회사 스코프로 특정 프로젝트의 표준횡단 설정값을 반환한다(타 회사 접근 차단).
|
||||
|
||||
company_id 조건으로 남의 회사 프로젝트 값은 조회되지 않는다(권한 강제).
|
||||
"""
|
||||
async with connection.cursor() as cursor:
|
||||
await cursor.execute(
|
||||
"""
|
||||
SELECT l.data
|
||||
FROM longitudinal_sections l
|
||||
JOIN projects p ON p.id = l.project_id
|
||||
WHERE l.project_id = %s
|
||||
AND p.company_id = %s
|
||||
AND p.deleted_at IS NULL
|
||||
AND JSON_EXTRACT(l.data, '$.options.standard_cross_section') IS NOT NULL
|
||||
ORDER BY l.id DESC
|
||||
LIMIT 1
|
||||
""",
|
||||
(str(project_id), company_id),
|
||||
)
|
||||
row = await cursor.fetchone()
|
||||
if not row or not row[0]:
|
||||
return None
|
||||
data = row[0]
|
||||
if isinstance(data, str):
|
||||
data = json.loads(data)
|
||||
options = data.get("options") if isinstance(data, dict) else None
|
||||
standard = options.get("standard_cross_section") if isinstance(options, dict) else None
|
||||
return standard if isinstance(standard, dict) else None
|
||||
|
||||
|
||||
async def get_latest_grade_options(
|
||||
connection: aiomysql.Connection, project_id: UUID
|
||||
) -> dict[str, Any] | None:
|
||||
@@ -274,11 +331,14 @@ async def update_cross_section_design(
|
||||
route_id: int,
|
||||
chainage_m: float,
|
||||
design: dict[str, Any],
|
||||
project_id: UUID | None = None,
|
||||
) -> bool:
|
||||
"""측점 하나의 data.design(잠정 설계 지정·단면적)을 병합 저장한다.
|
||||
|
||||
기존 data 요약을 보존하고 design 키만 갱신한다. 대상 측점을 chainage 근사로
|
||||
찾으며(부동소수 오차 허용), 갱신 여부를 반환한다.
|
||||
구조물(비정규) 측점은 B05 확정이 파일만 쓰고 DB 행을 만들지 않으므로, 행이 없고
|
||||
project_id가 오면 새 행을 삽입한다(upsert — 구조물 측점 설계 저장 보장).
|
||||
"""
|
||||
async with connection.cursor() as cursor:
|
||||
await cursor.execute(
|
||||
@@ -292,7 +352,21 @@ async def update_cross_section_design(
|
||||
)
|
||||
row = await cursor.fetchone()
|
||||
if not row:
|
||||
return False
|
||||
if project_id is None:
|
||||
return False
|
||||
await cursor.execute(
|
||||
"""
|
||||
INSERT INTO cross_sections (project_id, route_id, chainage_m, data, status)
|
||||
VALUES (%s, %s, %s, %s, 'DRAFT')
|
||||
""",
|
||||
(
|
||||
str(project_id),
|
||||
route_id,
|
||||
chainage_m,
|
||||
json.dumps({"design": design}, ensure_ascii=False),
|
||||
),
|
||||
)
|
||||
return True
|
||||
data = row[1]
|
||||
if isinstance(data, str):
|
||||
data = json.loads(data)
|
||||
|
||||
Reference in New Issue
Block a user