32a95d09f0
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 1m49s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 2m10s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Successful in 2m40s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 2m48s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 1m17s
CI/CD Pipeline / Validate - Code Quality (push) Successful in 5m1s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 5m10s
CI/CD Pipeline / Unit Tests (push) Failing after 5m58s
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Integration Tests (push) Successful in 2m33s
CI/CD Pipeline / Build Staging API Image (push) Successful in 17m18s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (push) Has been cancelled
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
import React from "react"
|
|
import { Modal as AntModal } from "antd"
|
|
|
|
/* ============================================================
|
|
* UploadProgressModal — 上传进度弹窗(圆形动画 + 百分比)
|
|
* ============================================================ */
|
|
export interface UploadProgressModalProps {
|
|
open: boolean
|
|
progress: number
|
|
}
|
|
|
|
const UploadProgressModal: React.FC<UploadProgressModalProps> = ({ open, progress }) => (
|
|
<AntModal
|
|
open={open}
|
|
footer={null}
|
|
closable={false}
|
|
centered
|
|
width={260}
|
|
maskClosable={false}
|
|
className="xx-upload-progress-modal"
|
|
>
|
|
<div className="xx-upload-progress-body">
|
|
<svg className="xx-upload-progress-ring" viewBox="0 0 120 120" width={120} height={120}>
|
|
{/* 背景圆环 */}
|
|
<circle
|
|
cx="60"
|
|
cy="60"
|
|
r="52"
|
|
fill="none"
|
|
stroke="var(--border-primary, #e5e7eb)"
|
|
strokeWidth="8"
|
|
/>
|
|
{/* 进度圆弧 */}
|
|
<circle
|
|
cx="60"
|
|
cy="60"
|
|
r="52"
|
|
fill="none"
|
|
stroke="var(--primary-color, #6366f1)"
|
|
strokeWidth="8"
|
|
strokeLinecap="round"
|
|
strokeDasharray={`${2 * Math.PI * 52}`}
|
|
strokeDashoffset={`${2 * Math.PI * 52 * (1 - progress / 100)}`}
|
|
transform="rotate(-90 60 60)"
|
|
style={{ transition: "stroke-dashoffset 0.3s ease" }}
|
|
/>
|
|
</svg>
|
|
<div className="xx-upload-progress-text">
|
|
<span className="xx-upload-progress-pct">{progress}%</span>
|
|
<span className="xx-upload-progress-label">上传中…</span>
|
|
</div>
|
|
</div>
|
|
</AntModal>
|
|
)
|
|
|
|
export default UploadProgressModal
|