Merge pull request #99 from vinland100/fix/gitea-display-type
fix: 修复项目详情页中Gitea类型仍然显示为'其他'的问题
This commit is contained in:
commit
0a8133aab2
|
|
@ -9,7 +9,7 @@ import {
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { GitBranch, Zap, Info } from "lucide-react";
|
import { GitBranch, Zap, Info } from "lucide-react";
|
||||||
import type { Project, CreateAuditTaskForm } from "@/shared/types";
|
import type { Project, CreateAuditTaskForm } from "@/shared/types";
|
||||||
import { isRepositoryProject, isZipProject } from "@/shared/utils/projectUtils";
|
import { isRepositoryProject, isZipProject, getRepositoryPlatformLabel } from "@/shared/utils/projectUtils";
|
||||||
import ZipFileSection from "./ZipFileSection";
|
import ZipFileSection from "./ZipFileSection";
|
||||||
import type { ZipFileMeta } from "@/shared/utils/zipStorage";
|
import type { ZipFileMeta } from "@/shared/utils/zipStorage";
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ function ProjectInfoCard({ project }: { project: Project }) {
|
||||||
{isRepo && (
|
{isRepo && (
|
||||||
<>
|
<>
|
||||||
<p>
|
<p>
|
||||||
仓库平台:{project.repository_type?.toUpperCase() || "OTHER"}
|
仓库平台:{getRepositoryPlatformLabel(project.repository_type)}
|
||||||
</p>
|
</p>
|
||||||
<p>默认分支:{project.default_branch}</p>
|
<p>默认分支:{project.default_branch}</p>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,13 @@ import { api } from "@/shared/config/database";
|
||||||
import { runRepositoryAudit, scanStoredZipFile } from "@/features/projects/services";
|
import { runRepositoryAudit, scanStoredZipFile } from "@/features/projects/services";
|
||||||
import type { Project, AuditTask, CreateProjectForm } from "@/shared/types";
|
import type { Project, AuditTask, CreateProjectForm } from "@/shared/types";
|
||||||
import { hasZipFile } from "@/shared/utils/zipStorage";
|
import { hasZipFile } from "@/shared/utils/zipStorage";
|
||||||
import { isRepositoryProject, getSourceTypeLabel } from "@/shared/utils/projectUtils";
|
import { isRepositoryProject, getSourceTypeLabel, getRepositoryPlatformLabel } from "@/shared/utils/projectUtils";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import CreateTaskDialog from "@/components/audit/CreateTaskDialog";
|
import CreateTaskDialog from "@/components/audit/CreateTaskDialog";
|
||||||
import FileSelectionDialog from "@/components/audit/FileSelectionDialog";
|
import FileSelectionDialog from "@/components/audit/FileSelectionDialog";
|
||||||
import TerminalProgressDialog from "@/components/audit/TerminalProgressDialog";
|
import TerminalProgressDialog from "@/components/audit/TerminalProgressDialog";
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
||||||
import { SUPPORTED_LANGUAGES } from "@/shared/constants";
|
import { SUPPORTED_LANGUAGES, REPOSITORY_PLATFORMS } from "@/shared/constants";
|
||||||
|
|
||||||
export default function ProjectDetail() {
|
export default function ProjectDetail() {
|
||||||
const { id } = useParams<{ id: string }>();
|
const { id } = useParams<{ id: string }>();
|
||||||
|
|
@ -475,8 +475,7 @@ export default function ProjectDetail() {
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-sm text-muted-foreground uppercase">仓库平台</span>
|
<span className="text-sm text-muted-foreground uppercase">仓库平台</span>
|
||||||
<Badge className="cyber-badge-muted">
|
<Badge className="cyber-badge-muted">
|
||||||
{project.repository_type === 'github' ? 'GitHub' :
|
{getRepositoryPlatformLabel(project.repository_type)}
|
||||||
project.repository_type === 'gitlab' ? 'GitLab' : '其他'}
|
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -529,12 +528,11 @@ export default function ProjectDetail() {
|
||||||
className="flex items-center justify-between p-3 bg-muted/50 rounded-lg hover:bg-muted transition-all group"
|
className="flex items-center justify-between p-3 bg-muted/50 rounded-lg hover:bg-muted transition-all group"
|
||||||
>
|
>
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<div className={`w-8 h-8 rounded-lg flex items-center justify-center ${
|
<div className={`w-8 h-8 rounded-lg flex items-center justify-center ${task.status === 'completed' ? 'bg-emerald-500/20' :
|
||||||
task.status === 'completed' ? 'bg-emerald-500/20' :
|
|
||||||
task.status === 'running' ? 'bg-sky-500/20' :
|
task.status === 'running' ? 'bg-sky-500/20' :
|
||||||
task.status === 'failed' ? 'bg-rose-500/20' :
|
task.status === 'failed' ? 'bg-rose-500/20' :
|
||||||
'bg-muted'
|
'bg-muted'
|
||||||
}`}>
|
}`}>
|
||||||
{getStatusIcon(task.status)}
|
{getStatusIcon(task.status)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -579,12 +577,11 @@ export default function ProjectDetail() {
|
||||||
<div key={task.id} className="cyber-card p-6">
|
<div key={task.id} className="cyber-card p-6">
|
||||||
<div className="flex items-center justify-between mb-4 pb-4 border-b border-border">
|
<div className="flex items-center justify-between mb-4 pb-4 border-b border-border">
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<div className={`w-10 h-10 rounded-lg flex items-center justify-center ${
|
<div className={`w-10 h-10 rounded-lg flex items-center justify-center ${task.status === 'completed' ? 'bg-emerald-500/20' :
|
||||||
task.status === 'completed' ? 'bg-emerald-500/20' :
|
|
||||||
task.status === 'running' ? 'bg-sky-500/20' :
|
task.status === 'running' ? 'bg-sky-500/20' :
|
||||||
task.status === 'failed' ? 'bg-rose-500/20' :
|
task.status === 'failed' ? 'bg-rose-500/20' :
|
||||||
'bg-muted'
|
'bg-muted'
|
||||||
}`}>
|
}`}>
|
||||||
{getStatusIcon(task.status)}
|
{getStatusIcon(task.status)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -676,12 +673,11 @@ export default function ProjectDetail() {
|
||||||
<div key={index} className="cyber-card p-4 hover:border-border transition-all">
|
<div key={index} className="cyber-card p-4 hover:border-border transition-all">
|
||||||
<div className="flex items-start justify-between">
|
<div className="flex items-start justify-between">
|
||||||
<div className="flex items-start space-x-3">
|
<div className="flex items-start space-x-3">
|
||||||
<div className={`w-8 h-8 rounded-lg flex items-center justify-center ${
|
<div className={`w-8 h-8 rounded-lg flex items-center justify-center ${issue.severity === 'critical' ? 'bg-rose-500/20 text-rose-600 dark:text-rose-400' :
|
||||||
issue.severity === 'critical' ? 'bg-rose-500/20 text-rose-600 dark:text-rose-400' :
|
|
||||||
issue.severity === 'high' ? 'bg-orange-500/20 text-orange-600 dark:text-orange-400' :
|
issue.severity === 'high' ? 'bg-orange-500/20 text-orange-600 dark:text-orange-400' :
|
||||||
issue.severity === 'medium' ? 'bg-amber-500/20 text-amber-600 dark:text-amber-400' :
|
issue.severity === 'medium' ? 'bg-amber-500/20 text-amber-600 dark:text-amber-400' :
|
||||||
'bg-sky-500/20 text-sky-600 dark:text-sky-400'
|
'bg-sky-500/20 text-sky-600 dark:text-sky-400'
|
||||||
}`}>
|
}`}>
|
||||||
<AlertTriangle className="w-4 h-4" />
|
<AlertTriangle className="w-4 h-4" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -695,13 +691,13 @@ export default function ProjectDetail() {
|
||||||
<Badge className={`
|
<Badge className={`
|
||||||
${issue.severity === 'critical' ? 'severity-critical' :
|
${issue.severity === 'critical' ? 'severity-critical' :
|
||||||
issue.severity === 'high' ? 'severity-high' :
|
issue.severity === 'high' ? 'severity-high' :
|
||||||
issue.severity === 'medium' ? 'severity-medium' :
|
issue.severity === 'medium' ? 'severity-medium' :
|
||||||
'severity-low'}
|
'severity-low'}
|
||||||
font-bold uppercase px-2 py-1 rounded text-xs
|
font-bold uppercase px-2 py-1 rounded text-xs
|
||||||
`}>
|
`}>
|
||||||
{issue.severity === 'critical' ? '严重' :
|
{issue.severity === 'critical' ? '严重' :
|
||||||
issue.severity === 'high' ? '高' :
|
issue.severity === 'high' ? '高' :
|
||||||
issue.severity === 'medium' ? '中等' : '低'}
|
issue.severity === 'medium' ? '中等' : '低'}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-3 text-sm text-muted-foreground font-mono border-t border-border pt-3">
|
<p className="mt-3 text-sm text-muted-foreground font-mono border-t border-border pt-3">
|
||||||
|
|
@ -783,9 +779,11 @@ export default function ProjectDetail() {
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="cyber-dialog border-border">
|
<SelectContent className="cyber-dialog border-border">
|
||||||
<SelectItem value="github">GitHub</SelectItem>
|
{REPOSITORY_PLATFORMS.map((platform) => (
|
||||||
<SelectItem value="gitlab">GitLab</SelectItem>
|
<SelectItem key={platform.value} value={platform.value}>
|
||||||
<SelectItem value="other">其他</SelectItem>
|
{platform.label}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -831,14 +829,14 @@ export default function ProjectDetail() {
|
||||||
className={`flex items-center space-x-2 p-3 border cursor-pointer transition-all rounded ${editForm.programming_languages?.includes(lang)
|
className={`flex items-center space-x-2 p-3 border cursor-pointer transition-all rounded ${editForm.programming_languages?.includes(lang)
|
||||||
? 'border-primary bg-primary/10 text-primary'
|
? 'border-primary bg-primary/10 text-primary'
|
||||||
: 'border-border hover:border-border text-muted-foreground'
|
: 'border-border hover:border-border text-muted-foreground'
|
||||||
}`}
|
}`}
|
||||||
onClick={() => handleToggleLanguage(lang)}
|
onClick={() => handleToggleLanguage(lang)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`w-4 h-4 border-2 rounded-sm flex items-center justify-center ${editForm.programming_languages?.includes(lang)
|
className={`w-4 h-4 border-2 rounded-sm flex items-center justify-center ${editForm.programming_languages?.includes(lang)
|
||||||
? 'bg-primary border-primary'
|
? 'bg-primary border-primary'
|
||||||
: 'border-border'
|
: 'border-border'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{editForm.programming_languages?.includes(lang) && (
|
{editForm.programming_languages?.includes(lang) && (
|
||||||
<CheckCircle className="w-3 h-3 text-foreground" />
|
<CheckCircle className="w-3 h-3 text-foreground" />
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import { Link } from "react-router-dom";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import CreateTaskDialog from "@/components/audit/CreateTaskDialog";
|
import CreateTaskDialog from "@/components/audit/CreateTaskDialog";
|
||||||
import TerminalProgressDialog from "@/components/audit/TerminalProgressDialog";
|
import TerminalProgressDialog from "@/components/audit/TerminalProgressDialog";
|
||||||
import { SUPPORTED_LANGUAGES } from "@/shared/constants";
|
import { SUPPORTED_LANGUAGES, REPOSITORY_PLATFORMS } from "@/shared/constants";
|
||||||
|
|
||||||
export default function Projects() {
|
export default function Projects() {
|
||||||
const [projects, setProjects] = useState<Project[]>([]);
|
const [projects, setProjects] = useState<Project[]>([]);
|
||||||
|
|
@ -485,10 +485,11 @@ export default function Projects() {
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="cyber-dialog border-border">
|
<SelectContent className="cyber-dialog border-border">
|
||||||
<SelectItem value="github">GITHUB</SelectItem>
|
{REPOSITORY_PLATFORMS.map((platform) => (
|
||||||
<SelectItem value="gitlab">GITLAB</SelectItem>
|
<SelectItem key={platform.value} value={platform.value}>
|
||||||
<SelectItem value="gitea">GITEA</SelectItem>
|
{platform.label}
|
||||||
<SelectItem value="other">OTHER</SelectItem>
|
</SelectItem>
|
||||||
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1016,10 +1017,11 @@ export default function Projects() {
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="cyber-dialog border-border">
|
<SelectContent className="cyber-dialog border-border">
|
||||||
<SelectItem value="github">GITHUB</SelectItem>
|
{REPOSITORY_PLATFORMS.map((platform) => (
|
||||||
<SelectItem value="gitlab">GITLAB</SelectItem>
|
<SelectItem key={platform.value} value={platform.value}>
|
||||||
<SelectItem value="gitea">GITEA</SelectItem>
|
{platform.label}
|
||||||
<SelectItem value="other">OTHER</SelectItem>
|
</SelectItem>
|
||||||
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import type { AuditTask, AuditIssue } from "@/shared/types";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import ExportReportDialog from "@/components/reports/ExportReportDialog";
|
import ExportReportDialog from "@/components/reports/ExportReportDialog";
|
||||||
import { calculateTaskProgress } from "@/shared/utils/utils";
|
import { calculateTaskProgress } from "@/shared/utils/utils";
|
||||||
import { isRepositoryProject, getSourceTypeLabel } from "@/shared/utils/projectUtils";
|
import { isRepositoryProject, getSourceTypeLabel, getRepositoryPlatformLabel } from "@/shared/utils/projectUtils";
|
||||||
|
|
||||||
// AI explanation parser
|
// AI explanation parser
|
||||||
function parseAIExplanation(aiExplanation: string) {
|
function parseAIExplanation(aiExplanation: string) {
|
||||||
|
|
@ -86,12 +86,11 @@ function IssuesList({ issues }: { issues: AuditIssue[] }) {
|
||||||
<div key={issue.id || index} className="cyber-card p-4 hover:border-border transition-all group">
|
<div key={issue.id || index} className="cyber-card p-4 hover:border-border transition-all group">
|
||||||
<div className="flex items-start justify-between mb-3">
|
<div className="flex items-start justify-between mb-3">
|
||||||
<div className="flex items-start space-x-3">
|
<div className="flex items-start space-x-3">
|
||||||
<div className={`w-10 h-10 rounded-lg flex items-center justify-center ${
|
<div className={`w-10 h-10 rounded-lg flex items-center justify-center ${issue.severity === 'critical' ? 'bg-rose-500/20 text-rose-400' :
|
||||||
issue.severity === 'critical' ? 'bg-rose-500/20 text-rose-400' :
|
issue.severity === 'high' ? 'bg-orange-500/20 text-orange-400' :
|
||||||
issue.severity === 'high' ? 'bg-orange-500/20 text-orange-400' :
|
issue.severity === 'medium' ? 'bg-amber-500/20 text-amber-400' :
|
||||||
issue.severity === 'medium' ? 'bg-amber-500/20 text-amber-400' :
|
'bg-sky-500/20 text-sky-400'
|
||||||
'bg-sky-500/20 text-sky-400'
|
}`}>
|
||||||
}`}>
|
|
||||||
{getTypeIcon(issue.issue_type)}
|
{getTypeIcon(issue.issue_type)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
|
|
@ -112,7 +111,7 @@ function IssuesList({ issues }: { issues: AuditIssue[] }) {
|
||||||
<Badge className={`${getSeverityClasses(issue.severity)} font-bold uppercase px-2 py-1 rounded text-xs`}>
|
<Badge className={`${getSeverityClasses(issue.severity)} font-bold uppercase px-2 py-1 rounded text-xs`}>
|
||||||
{issue.severity === 'critical' ? '严重' :
|
{issue.severity === 'critical' ? '严重' :
|
||||||
issue.severity === 'high' ? '高' :
|
issue.severity === 'high' ? '高' :
|
||||||
issue.severity === 'medium' ? '中等' : '低'}
|
issue.severity === 'medium' ? '中等' : '低'}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -702,7 +701,7 @@ export default function TaskDetail() {
|
||||||
{isRepositoryProject(task.project) && (
|
{isRepositoryProject(task.project) && (
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-bold text-muted-foreground uppercase mb-1">仓库平台</p>
|
<p className="text-xs font-bold text-muted-foreground uppercase mb-1">仓库平台</p>
|
||||||
<p className="text-base font-bold text-foreground">{task.project.repository_type?.toUpperCase() || 'OTHER'}</p>
|
<p className="text-base font-bold text-foreground">{getRepositoryPlatformLabel(task.project.repository_type)}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{task.project.programming_languages && (
|
{task.project.programming_languages && (
|
||||||
|
|
|
||||||
|
|
@ -62,13 +62,6 @@ export const PROJECT_SOURCE_TYPES = {
|
||||||
ZIP: 'zip',
|
ZIP: 'zip',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// 仓库平台类型
|
|
||||||
export const REPOSITORY_TYPES = {
|
|
||||||
GITHUB: 'github',
|
|
||||||
GITLAB: 'gitlab',
|
|
||||||
OTHER: 'other',
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
// 分析深度
|
// 分析深度
|
||||||
export const ANALYSIS_DEPTH = {
|
export const ANALYSIS_DEPTH = {
|
||||||
BASIC: 'basic',
|
BASIC: 'basic',
|
||||||
|
|
|
||||||
|
|
@ -22,17 +22,23 @@ export const PROJECT_SOURCE_TYPES: Array<{
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 仓库平台显示名称
|
||||||
|
export const REPOSITORY_PLATFORM_LABELS: Record<RepositoryPlatform, string> = {
|
||||||
|
github: 'GitHub',
|
||||||
|
gitlab: 'GitLab',
|
||||||
|
gitea: 'Gitea',
|
||||||
|
other: '其他',
|
||||||
|
};
|
||||||
|
|
||||||
// 仓库平台选项
|
// 仓库平台选项
|
||||||
export const REPOSITORY_PLATFORMS: Array<{
|
export const REPOSITORY_PLATFORMS: Array<{
|
||||||
value: RepositoryPlatform;
|
value: RepositoryPlatform;
|
||||||
label: string;
|
label: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
}> = [
|
}> = Object.entries(REPOSITORY_PLATFORM_LABELS).map(([value, label]) => ({
|
||||||
{ value: 'github', label: 'GitHub' },
|
value: value as RepositoryPlatform,
|
||||||
{ value: 'gitlab', label: 'GitLab' },
|
label
|
||||||
{ value: 'gitea', label: 'Gitea' },
|
}));
|
||||||
{ value: 'other', label: '其他' }
|
|
||||||
];
|
|
||||||
|
|
||||||
// 项目来源类型的颜色配置
|
// 项目来源类型的颜色配置
|
||||||
export const SOURCE_TYPE_COLORS: Record<ProjectSourceType, {
|
export const SOURCE_TYPE_COLORS: Record<ProjectSourceType, {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Project, ProjectSourceType } from '@/shared/types';
|
import type { Project, ProjectSourceType } from '@/shared/types';
|
||||||
|
import { REPOSITORY_PLATFORM_LABELS } from '@/shared/constants/projectTypes';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断项目是否为仓库类型
|
* 判断项目是否为仓库类型
|
||||||
|
|
@ -45,13 +46,7 @@ export function getSourceTypeBadge(sourceType: ProjectSourceType): string {
|
||||||
* 获取仓库平台的显示名称
|
* 获取仓库平台的显示名称
|
||||||
*/
|
*/
|
||||||
export function getRepositoryPlatformLabel(platform?: string): string {
|
export function getRepositoryPlatformLabel(platform?: string): string {
|
||||||
const labels: Record<string, string> = {
|
return REPOSITORY_PLATFORM_LABELS[platform as keyof typeof REPOSITORY_PLATFORM_LABELS] || REPOSITORY_PLATFORM_LABELS.other;
|
||||||
github: 'GitHub',
|
|
||||||
gitlab: 'GitLab',
|
|
||||||
gitea: 'Gitea',
|
|
||||||
other: '其他'
|
|
||||||
};
|
|
||||||
return labels[platform || 'other'] || '其他';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue