fix(enhance-v4): APK QR 버그 수정 + 웹메일 라우터 수정
This commit is contained in:
parent
1057915729
commit
f00388b066
@ -5457,7 +5457,8 @@ class AppVersion(Base):
|
|||||||
android_url = Column(String(1000), nullable=True)
|
android_url = Column(String(1000), nullable=True)
|
||||||
ios_url = Column(String(1000), nullable=True)
|
ios_url = Column(String(1000), nullable=True)
|
||||||
qr_image_path = Column(String(500), nullable=True)
|
qr_image_path = Column(String(500), nullable=True)
|
||||||
landing_token = Column(String(36), nullable=True, unique=True)
|
qr_data = Column(Text, nullable=True) # base64 PNG
|
||||||
|
landing_token = Column(String(64), nullable=True, unique=True)
|
||||||
download_count = Column(Integer, default=0)
|
download_count = Column(Integer, default=0)
|
||||||
is_latest = Column(Boolean, default=False)
|
is_latest = Column(Boolean, default=False)
|
||||||
release_notes = Column(Text, nullable=True)
|
release_notes = Column(Text, nullable=True)
|
||||||
|
|||||||
@ -97,9 +97,10 @@ async def upload_apk(
|
|||||||
file_path.write_bytes(file_bytes)
|
file_path.write_bytes(file_bytes)
|
||||||
|
|
||||||
# 기존 latest 해제
|
# 기존 latest 해제
|
||||||
|
from sqlalchemy import update as sa_update
|
||||||
await db.execute(
|
await db.execute(
|
||||||
__import__('sqlalchemy', fromlist=['update']).update(AppVersion)
|
sa_update(AppVersion)
|
||||||
.where(AppVersion.tenant_id == user.tenant_id, AppVersion.is_latest == True)
|
.where(AppVersion.is_latest == True)
|
||||||
.values(is_latest=False)
|
.values(is_latest=False)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -110,11 +111,10 @@ async def upload_apk(
|
|||||||
qr_b64 = base64.b64encode(qr_bytes).decode()
|
qr_b64 = base64.b64encode(qr_bytes).decode()
|
||||||
|
|
||||||
app_ver = AppVersion(
|
app_ver = AppVersion(
|
||||||
tenant_id=user.tenant_id,
|
|
||||||
version=version,
|
version=version,
|
||||||
platform="ANDROID",
|
platform="ANDROID",
|
||||||
file_path=str(file_path),
|
file_path=str(file_path),
|
||||||
file_size=len(file_bytes),
|
file_size_mb=round(len(file_bytes) / 1024 / 1024, 2),
|
||||||
android_url=f"{BASE_URL}/api/app/download?token={token}",
|
android_url=f"{BASE_URL}/api/app/download?token={token}",
|
||||||
ios_url=ios_url or None,
|
ios_url=ios_url or None,
|
||||||
landing_token=token,
|
landing_token=token,
|
||||||
@ -147,9 +147,10 @@ async def set_app_url(
|
|||||||
user: User = Depends(require_admin_role),
|
user: User = Depends(require_admin_role),
|
||||||
):
|
):
|
||||||
"""외부 URL(EAS 빌드 등)로 QR 코드 생성."""
|
"""외부 URL(EAS 빌드 등)로 QR 코드 생성."""
|
||||||
|
from sqlalchemy import update as sa_update
|
||||||
await db.execute(
|
await db.execute(
|
||||||
__import__('sqlalchemy', fromlist=['update']).update(AppVersion)
|
sa_update(AppVersion)
|
||||||
.where(AppVersion.tenant_id == user.tenant_id, AppVersion.is_latest == True)
|
.where(AppVersion.is_latest == True)
|
||||||
.values(is_latest=False)
|
.values(is_latest=False)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -158,7 +159,6 @@ async def set_app_url(
|
|||||||
qr_bytes = _generate_qr(landing_url)
|
qr_bytes = _generate_qr(landing_url)
|
||||||
|
|
||||||
app_ver = AppVersion(
|
app_ver = AppVersion(
|
||||||
tenant_id=user.tenant_id,
|
|
||||||
version=req.version,
|
version=req.version,
|
||||||
platform="BOTH" if req.ios_url else "ANDROID",
|
platform="BOTH" if req.ios_url else "ANDROID",
|
||||||
android_url=req.android_url,
|
android_url=req.android_url,
|
||||||
@ -190,10 +190,7 @@ async def get_latest(
|
|||||||
):
|
):
|
||||||
"""최신 버전 정보 조회."""
|
"""최신 버전 정보 조회."""
|
||||||
row = await db.execute(
|
row = await db.execute(
|
||||||
select(AppVersion).where(
|
select(AppVersion).where(AppVersion.is_latest == True)
|
||||||
AppVersion.tenant_id == user.tenant_id,
|
|
||||||
AppVersion.is_latest == True,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
ver = row.scalar_one_or_none()
|
ver = row.scalar_one_or_none()
|
||||||
if not ver:
|
if not ver:
|
||||||
@ -303,8 +300,7 @@ async def app_landing(
|
|||||||
version_id=ver.id,
|
version_id=ver.id,
|
||||||
platform="IOS" if is_ios else "ANDROID",
|
platform="IOS" if is_ios else "ANDROID",
|
||||||
user_agent=request.headers.get("User-Agent", "")[:200],
|
user_agent=request.headers.get("User-Agent", "")[:200],
|
||||||
ip_addr=request.client.host if request.client else "",
|
downloaded_at=datetime.utcnow(),
|
||||||
accessed_at=datetime.utcnow(),
|
|
||||||
)
|
)
|
||||||
db.add(log)
|
db.add(log)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
@ -343,8 +339,7 @@ async def list_versions(
|
|||||||
user: User = Depends(get_current_user),
|
user: User = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
rows = await db.execute(
|
rows = await db.execute(
|
||||||
select(AppVersion).where(AppVersion.tenant_id == user.tenant_id)
|
select(AppVersion).order_by(desc(AppVersion.created_at)).limit(20)
|
||||||
.order_by(desc(AppVersion.created_at)).limit(20)
|
|
||||||
)
|
)
|
||||||
versions = rows.scalars().all()
|
versions = rows.scalars().all()
|
||||||
return [
|
return [
|
||||||
@ -353,7 +348,7 @@ async def list_versions(
|
|||||||
"download_count": v.download_count, "is_latest": v.is_latest,
|
"download_count": v.download_count, "is_latest": v.is_latest,
|
||||||
"qr_url": f"{BASE_URL}/api/app/qr?token={v.landing_token}",
|
"qr_url": f"{BASE_URL}/api/app/qr?token={v.landing_token}",
|
||||||
"landing_url": f"{BASE_URL}/api/app/landing?token={v.landing_token}",
|
"landing_url": f"{BASE_URL}/api/app/landing?token={v.landing_token}",
|
||||||
"file_size_mb": round((v.file_size or 0) / 1024 / 1024, 1),
|
"file_size_mb": round((v.file_size_mb or 0), 1),
|
||||||
"release_notes": v.release_notes,
|
"release_notes": v.release_notes,
|
||||||
"created_at": v.created_at,
|
"created_at": v.created_at,
|
||||||
}
|
}
|
||||||
@ -368,7 +363,7 @@ async def delete_version(
|
|||||||
user: User = Depends(require_admin_role),
|
user: User = Depends(require_admin_role),
|
||||||
):
|
):
|
||||||
row = await db.execute(
|
row = await db.execute(
|
||||||
select(AppVersion).where(AppVersion.id == version_id, AppVersion.tenant_id == user.tenant_id)
|
select(AppVersion).where(AppVersion.id == version_id)
|
||||||
)
|
)
|
||||||
ver = row.scalar_one_or_none()
|
ver = row.scalar_one_or_none()
|
||||||
if not ver:
|
if not ver:
|
||||||
@ -388,7 +383,7 @@ async def app_stats(
|
|||||||
user: User = Depends(get_current_user),
|
user: User = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
total = (await db.execute(
|
total = (await db.execute(
|
||||||
select(func.sum(AppVersion.download_count)).where(AppVersion.tenant_id == user.tenant_id)
|
select(func.sum(AppVersion.download_count))
|
||||||
)).scalar() or 0
|
)).scalar() or 0
|
||||||
android = (await db.execute(
|
android = (await db.execute(
|
||||||
select(func.count(AppDownloadLog.id)).where(AppDownloadLog.platform == "ANDROID")
|
select(func.count(AppDownloadLog.id)).where(AppDownloadLog.platform == "ANDROID")
|
||||||
|
|||||||
@ -42,7 +42,7 @@ class NotifyRuleCreate(BaseModel):
|
|||||||
name: str = Field(..., max_length=200)
|
name: str = Field(..., max_length=200)
|
||||||
trigger_type: str = Field(..., description="SR_CREATED|SR_UPDATED|INCIDENT|DRIFT|KPI_BREACH|CUSTOM")
|
trigger_type: str = Field(..., description="SR_CREATED|SR_UPDATED|INCIDENT|DRIFT|KPI_BREACH|CUSTOM")
|
||||||
conditions: dict = Field(default_factory=dict)
|
conditions: dict = Field(default_factory=dict)
|
||||||
channels: List[str] = Field(default_factory=list, description=["messenger","email","slack","kakao"])
|
channels: List[str] = Field(default_factory=list, description="messenger|email|slack|kakao")
|
||||||
priority_filter: str = Field("ALL", description="HIGH|MEDIUM|ALL")
|
priority_filter: str = Field("ALL", description="HIGH|MEDIUM|ALL")
|
||||||
silence_hours: Optional[List[int]] = Field(None, description="무음 시간 목록 [22,23,0,1,...,7]")
|
silence_hours: Optional[List[int]] = Field(None, description="무음 시간 목록 [22,23,0,1,...,7]")
|
||||||
digest_mode: bool = Field(False, description="묶음 발송 모드")
|
digest_mode: bool = Field(False, description="묶음 발송 모드")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user