Compare commits
24 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
02bf0c89c7 | 1 month ago |
|
|
b0565cd5b6 | 1 month ago |
|
|
7e0d804ccc | 1 month ago |
|
|
f6f0f71305 | 1 month ago |
|
|
f8807a0353 | 1 month ago |
|
|
0faf294fff | 1 month ago |
|
|
ea0852b7b8 | 2 months ago |
|
|
ff0e88ba39 | 2 months ago |
|
|
4cee1f479b | 2 months ago |
|
|
135d0f4569 | 2 months ago |
|
|
e3144b6e27 | 2 months ago |
|
|
e9acf78a4a | 2 months ago |
|
|
9841112827 | 2 months ago |
|
|
65aee1e35d | 2 months ago |
|
|
1d884069e3 | 2 months ago |
|
|
abd5d7ff2e | 2 months ago |
|
|
f2a7ccf2cf | 2 months ago |
|
|
dd7f896e19 | 2 months ago |
|
|
91fe671a40 | 2 months ago |
|
|
3c7bcef3a9 | 2 months ago |
|
|
f320554ea0 | 2 months ago |
|
|
e96e9251d6 | 2 months ago |
|
|
62040df04d | 2 months ago |
|
|
65e3b5f927 | 2 months ago |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,90 @@
|
||||
classDiagram
|
||||
direction TB
|
||||
|
||||
class OpenRankDashboard {
|
||||
-currentTab: string
|
||||
-mode: string
|
||||
-charts: object
|
||||
-mockData: object
|
||||
-projectState: object
|
||||
+init()
|
||||
+setupEventListeners()
|
||||
+setupTabNavigation()
|
||||
+switchTab(tab: string)
|
||||
+switchMode(mode: string)
|
||||
+loadMockData()
|
||||
+initCharts()
|
||||
+generateMockData()
|
||||
}
|
||||
|
||||
class Overview {
|
||||
+updateStats()
|
||||
+updateRankingTable()
|
||||
+initDistributionChart()
|
||||
+initActivityChart()
|
||||
}
|
||||
|
||||
class Repositories {
|
||||
+updateRepositoryGrid()
|
||||
+filterRepositories(filter: string)
|
||||
+onViewRepoDetails(repoName: string)
|
||||
+onViewRepoContributions(repoName: string)
|
||||
+showRepoDetails(owner: string, repo: string)
|
||||
}
|
||||
|
||||
class Developers {
|
||||
+displayDeveloperAnalysis(developers: array)
|
||||
+filterDevelopers(keyword: string)
|
||||
}
|
||||
|
||||
class Network {
|
||||
+initNetworkGraph()
|
||||
}
|
||||
|
||||
class CodeReview {
|
||||
+setupCodeReviewPage()
|
||||
+loadExampleCode()
|
||||
+runCodeLinting()
|
||||
+simulatePylintAnalysis(code: string)
|
||||
+displayLintResults(score: number, issues: array)
|
||||
+resetCodeReviewResults()
|
||||
}
|
||||
|
||||
class Settings {
|
||||
+setupConfigListeners()
|
||||
+updateConfig(id: string, value: any)
|
||||
}
|
||||
|
||||
class ProjectMode {
|
||||
+buildProjectListFromGlobal()
|
||||
+renderProjectList(keyword: string)
|
||||
+renderApproxProject(fullName: string, days: number)
|
||||
+mountProjectView(snapshot: object)
|
||||
+triggerFullProjectCalculation(fullName: string)
|
||||
+autoTriggerFull(fullName: string, days: number)
|
||||
+pollTask(taskId: string, fullName: string, silent: boolean)
|
||||
}
|
||||
|
||||
OpenRankDashboard --> Overview: contains
|
||||
OpenRankDashboard --> Repositories: contains
|
||||
OpenRankDashboard --> Developers: contains
|
||||
OpenRankDashboard --> Network: contains
|
||||
OpenRankDashboard --> CodeReview: contains
|
||||
OpenRankDashboard --> Settings: contains
|
||||
OpenRankDashboard --> ProjectMode: contains
|
||||
|
||||
class DataLoader {
|
||||
+fetchProjectOverview(owner: string, repo: string)
|
||||
+fetchRepoDetails(owner: string, repo: string)
|
||||
+fetchContributors(owner: string, repo: string)
|
||||
}
|
||||
|
||||
class UIHelper {
|
||||
+showNotification(message: string, type: string)
|
||||
+updateLastUpdateTime()
|
||||
+pushURLState()
|
||||
+hydrateFromURL()
|
||||
}
|
||||
|
||||
OpenRankDashboard --> DataLoader: uses
|
||||
OpenRankDashboard --> UIHelper: uses
|
||||
Binary file not shown.
@ -0,0 +1,166 @@
|
||||
classDiagram
|
||||
direction TB
|
||||
|
||||
%% 核心算法类
|
||||
class OpenRankCalculator {
|
||||
- config: OpenRankConfig
|
||||
- graph: Graph
|
||||
- calculationStatus: CalculationStatus
|
||||
+ calculate(activityData: ActivityData[], lastMonthOpenRank: Map~string, number~): Promise~OpenRankResult[]~
|
||||
- buildGraph(activityData: ActivityData[], lastMonthOpenRank: Map~string, number~): void
|
||||
- iterativeCalculation(): Promise~void~
|
||||
- generateResults(): OpenRankResult[]
|
||||
+ getCalculationStatus(): CalculationStatus
|
||||
+ getGraphStats()
|
||||
+ cleanup(): void
|
||||
}
|
||||
|
||||
class ProjectOpenRankCalculator {
|
||||
- config: OpenRankConfig
|
||||
- graph: Graph
|
||||
- calculationStatus: CalculationStatus
|
||||
- weightingFramework: WeightingFramework
|
||||
+ calculateProjectOpenRank(issueData: IssueData[], pullRequestData: PullRequestData[], lastMonthOpenRank: Map~string, number~, repoEvents?: RepoEventActivity[]): Promise~OpenRankResult[]~
|
||||
- buildProjectGraph(issueData: IssueData[], pullRequestData: PullRequestData[], lastMonthOpenRank: Map~string, number~, repoEvents?: RepoEventActivity[]): void
|
||||
- computeCodeImpactPools(pr: any, totalLines: number, filesChanged: number, ...): object
|
||||
}
|
||||
|
||||
class SimpleGraph {
|
||||
+ nodes: Map~string, GraphNode~
|
||||
+ edges: GraphEdge[]
|
||||
- adjacencyList: Map~string, Set~string~~
|
||||
- incomingEdges: Map~string, GraphEdge[]~
|
||||
- outgoingEdges: Map~string, GraphEdge[]~
|
||||
+ addNode(node: GraphNode): void
|
||||
+ addEdge(edge: GraphEdge): void
|
||||
+ getNode(id: string): GraphNode | undefined
|
||||
+ getNeighbors(nodeId: string): GraphNode[]
|
||||
+ getIncomingEdges(nodeId: string): GraphEdge[]
|
||||
+ getOutgoingEdges(nodeId: string): GraphEdge[]
|
||||
+ clear(): void
|
||||
+ getStats()
|
||||
+ isConnected(): boolean
|
||||
+ getDegree(nodeId: string)
|
||||
+ getNodesByType(type: string): GraphNode[]
|
||||
}
|
||||
|
||||
%% 数据收集类
|
||||
class ProjectData {
|
||||
issues: IssueData[]
|
||||
pullRequests: PullRequestData[]
|
||||
}
|
||||
class GitHubDataCollector {
|
||||
- config: GitHubConfig
|
||||
- baseUrl: string
|
||||
+ collectProjectData(repo: GitHubRepo, startDate: Date, endDate: Date): Promise~ProjectData~
|
||||
- listIssues(repo: GitHubRepo, startDate: Date, endDate: Date): Promise~number[]~
|
||||
- listPulls(repo: GitHubRepo, startDate: Date, endDate: Date): Promise~number[]~
|
||||
- collectIssueData(repo: GitHubRepo, issueIds: number[], events: any[]): Promise~IssueData[]~
|
||||
- collectPullRequestData(repo: GitHubRepo, prIds: number[], events: any[]): Promise~PullRequestData[]~
|
||||
}
|
||||
|
||||
%% API服务类
|
||||
class APIServer {
|
||||
- app: Express.Application
|
||||
- calculationCache: Record~string, CalcCacheEntry~
|
||||
- projectCache: Record~string, ProjectSnapshotCacheEntry~
|
||||
- tasks: Record~string, TaskEntry~
|
||||
+ start(): void
|
||||
- cleanupCaches(): void
|
||||
- createTask(): TaskEntry
|
||||
- getTask(id: string): TaskEntry | null
|
||||
- updateTask(id: string, patch: Partial~TaskEntry~): void
|
||||
}
|
||||
|
||||
%% 数据库类
|
||||
class MySQLConnection {
|
||||
+ pool: Pool
|
||||
+ closePool(): Promise~void~
|
||||
}
|
||||
|
||||
%% 接口和类型
|
||||
class ActivityData {
|
||||
platform: PlatformType
|
||||
repoId: number
|
||||
repoName: string
|
||||
orgId?: number
|
||||
orgName?: string
|
||||
actorId: number
|
||||
actorLogin: string
|
||||
issueComment: number
|
||||
openIssue: number
|
||||
openPull: number
|
||||
reviewComment: number
|
||||
mergedPull: number
|
||||
createdAt: Date
|
||||
}
|
||||
|
||||
class IssueData {
|
||||
id: number
|
||||
number?: number
|
||||
platform: PlatformType
|
||||
repoId: number
|
||||
repoName: string
|
||||
title: string
|
||||
authorId: number
|
||||
authorLogin: string
|
||||
createdAt: Date
|
||||
closedAt?: Date
|
||||
state: 'open' | 'closed'
|
||||
activities: any[]
|
||||
reactions: any
|
||||
}
|
||||
|
||||
class PullRequestData {
|
||||
id: number
|
||||
number?: number
|
||||
platform: PlatformType
|
||||
repoId: number
|
||||
repoName: string
|
||||
title: string
|
||||
authorId: number
|
||||
authorLogin: string
|
||||
createdAt: Date
|
||||
mergedAt?: Date
|
||||
closedAt?: Date
|
||||
state: 'open' | 'closed' | 'merged'
|
||||
activities: any[]
|
||||
reactions: any
|
||||
filesChanged?: number
|
||||
additions?: number
|
||||
deletions?: number
|
||||
}
|
||||
|
||||
class GraphNode {
|
||||
id: string
|
||||
type: NodeType
|
||||
platform: PlatformType
|
||||
name: string
|
||||
openrank: number
|
||||
lastOpenrank: number
|
||||
initValue: number
|
||||
retentionFactor: number
|
||||
converged: boolean
|
||||
metadata?: Record~string, any~
|
||||
}
|
||||
|
||||
class GraphEdge {
|
||||
source: string
|
||||
target: string
|
||||
weight: number
|
||||
type: 'activity' | 'belong' | 'reverse_belong' | 'reverse_activity'
|
||||
activityDetails?: any
|
||||
}
|
||||
|
||||
%% 关系
|
||||
OpenRankCalculator --> SimpleGraph: uses
|
||||
ProjectOpenRankCalculator --> SimpleGraph: uses
|
||||
APIServer --> OpenRankCalculator: calls
|
||||
APIServer --> ProjectOpenRankCalculator: calls
|
||||
APIServer --> GitHubDataCollector: uses
|
||||
APIServer --> MySQLConnection: uses
|
||||
OpenRankCalculator --> ActivityData: processes
|
||||
ProjectOpenRankCalculator --> IssueData: processes
|
||||
ProjectOpenRankCalculator --> PullRequestData: processes
|
||||
SimpleGraph --> GraphNode: contains
|
||||
SimpleGraph --> GraphEdge: contains
|
||||
Binary file not shown.
@ -0,0 +1,135 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- checkUI: CheckUI
|
||||
+ startPage()
|
||||
+ showMainInterface()
|
||||
+ navigateToCodeAssessmentPage()
|
||||
}
|
||||
|
||||
class CheckUI <<boundary>> {
|
||||
- pylint: Pylint
|
||||
- currentAssessment: CodeAssessment
|
||||
+ showCodeAssessmentPage()
|
||||
+ uploadCodeToBeTested(code: CodeFile): boolean
|
||||
+ displayAssessmentResult(result: AssessmentResult)
|
||||
}
|
||||
|
||||
class Pylint <<control>> {
|
||||
- database: DateBase
|
||||
+ assessCodeQuality(code: CodeFile): AssessmentResult
|
||||
+ generateQualityReport(assessment: AssessmentResult): QualityReport
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- codeAssessments: List<CodeAssessment>
|
||||
- qualityScores: List<QualityScore>
|
||||
- assessmentHistory: List<AssessmentHistory>
|
||||
+ storeCodeScore(assessment: CodeAssessment): boolean
|
||||
+ getAssessmentHistory(codeId: String): List<AssessmentHistory>
|
||||
+ getAverageQualityScore(projectId: String): double
|
||||
}
|
||||
|
||||
class CodeFile <<entity>> {
|
||||
- codeId: String
|
||||
- fileName: String
|
||||
- filePath: String
|
||||
- language: String
|
||||
- content: String
|
||||
- size: long
|
||||
+ getCodeId(): String
|
||||
+ getFileName(): String
|
||||
+ getLanguage(): String
|
||||
+ getContent(): String
|
||||
}
|
||||
|
||||
class AssessmentResult <<entity>> {
|
||||
- assessmentId: String
|
||||
- codeId: String
|
||||
- qualityScore: double
|
||||
- issues: List<CodeIssue>
|
||||
- assessmentTime: Date
|
||||
+ getQualityScore(): double
|
||||
+ getIssues(): List<CodeIssue>
|
||||
+ generateSummary(): String
|
||||
}
|
||||
|
||||
class CodeAssessment <<entity>> {
|
||||
- assessmentId: String
|
||||
- codeFile: CodeFile
|
||||
- result: AssessmentResult
|
||||
- assessmentDate: Date
|
||||
+ getAssessmentId(): String
|
||||
+ getAssessmentDate(): Date
|
||||
+ getResult(): AssessmentResult
|
||||
}
|
||||
|
||||
class CodeIssue <<entity>> {
|
||||
- issueId: String
|
||||
- type: String
|
||||
- severity: String
|
||||
- lineNumber: int
|
||||
- description: String
|
||||
- suggestion: String
|
||||
+ getIssueId(): String
|
||||
+ getType(): String
|
||||
+ getSeverity(): String
|
||||
+ getDescription(): String
|
||||
}
|
||||
|
||||
class QualityScore <<entity>> {
|
||||
- scoreId: String
|
||||
- codeId: String
|
||||
- overallScore: double
|
||||
- maintainabilityScore: double
|
||||
- reliabilityScore: double
|
||||
- efficiencyScore: double
|
||||
+ getOverallScore(): double
|
||||
+ getMaintainabilityScore(): double
|
||||
+ calculateCompositeScore(): double
|
||||
}
|
||||
|
||||
class QualityReport <<entity>> {
|
||||
- reportId: String
|
||||
- assessmentId: String
|
||||
- summary: String
|
||||
- detailedAnalysis: String
|
||||
- recommendations: List<String>
|
||||
+ generateReport(): String
|
||||
+ exportAsPDF(): void
|
||||
}
|
||||
|
||||
class AssessmentHistory <<entity>> {
|
||||
- historyId: String
|
||||
- codeId: String
|
||||
- assessmentDate: Date
|
||||
- qualityScore: double
|
||||
- trend: String
|
||||
+ getHistoryId(): String
|
||||
+ getAssessmentDate(): Date
|
||||
+ getQualityScore(): double
|
||||
+ calculateTrend(): String
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> CheckUI : "跳转"
|
||||
CheckUI --> Pylint : "调用测评"
|
||||
Pylint --> DateBase : "存储分数"
|
||||
Pylint ..> AssessmentResult : "生成"
|
||||
DateBase "1" *-- "many" CodeAssessment : "存储"
|
||||
DateBase "1" *-- "many" QualityScore : "包含"
|
||||
DateBase "1" *-- "many" AssessmentHistory : "记录历史"
|
||||
CodeAssessment "1" *-- "1" CodeFile : "测评"
|
||||
CodeAssessment "1" *-- "1" AssessmentResult : "包含结果"
|
||||
AssessmentResult "1" *-- "many" CodeIssue : "包含问题"
|
||||
AssessmentResult "1" *-- "1" QualityScore : "关联分数"
|
||||
Pylint ..> QualityReport : "生成报告"
|
||||
|
||||
|
||||
@enduml
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue