diff --git a/doc/软件需求构思及描述-基于软件工厂的群智协作贡献评估系统.docx b/doc/软件需求构思及描述-基于软件工厂的群智协作贡献评估系统.docx index 3e69773..e2dac2a 100644 Binary files a/doc/软件需求构思及描述-基于软件工厂的群智协作贡献评估系统.docx and b/doc/软件需求构思及描述-基于软件工厂的群智协作贡献评估系统.docx differ diff --git a/doc/软件需求规格说明书-基于软件工厂的群智协作贡献评估系统.docx b/doc/软件需求规格说明书-基于软件工厂的群智协作贡献评估系统.docx index a6715fd..6667826 100644 Binary files a/doc/软件需求规格说明书-基于软件工厂的群智协作贡献评估系统.docx and b/doc/软件需求规格说明书-基于软件工厂的群智协作贡献评估系统.docx differ diff --git a/picture/openrank用例图.vsdx b/picture/openrank用例图.vsdx index 989a25e..673bdd2 100644 Binary files a/picture/openrank用例图.vsdx and b/picture/openrank用例图.vsdx differ diff --git a/picture/体系结构图.vsdx b/picture/体系结构图.vsdx index 5bbeef2..5ad6556 100644 Binary files a/picture/体系结构图.vsdx and b/picture/体系结构图.vsdx differ diff --git a/picture/前端子系统设计类图.mermaid b/picture/前端子系统设计类图.mermaid new file mode 100644 index 0000000..e6ec35c --- /dev/null +++ b/picture/前端子系统设计类图.mermaid @@ -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 \ No newline at end of file diff --git a/picture/后端子系统设计类图.mermaid b/picture/后端子系统设计类图.mermaid new file mode 100644 index 0000000..f4fd470 --- /dev/null +++ b/picture/后端子系统设计类图.mermaid @@ -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 \ No newline at end of file diff --git a/picture/整体页面流转图.vsdx b/picture/整体页面流转图.vsdx new file mode 100644 index 0000000..8f36e5f Binary files /dev/null and b/picture/整体页面流转图.vsdx differ diff --git a/picture/界面跳转图.puml b/picture/界面跳转图.puml deleted file mode 100644 index b333929..0000000 --- a/picture/界面跳转图.puml +++ /dev/null @@ -1,64 +0,0 @@ -@startuml -skinparam dpi 180 -skinparam shadowing false -skinparam ArrowColor #00AEEF -skinparam DefaultFontName Microsoft YaHei -skinparam ArrowThickness 1.2 - -title 界面跳转图(OpenRank 可视化系统) - -[*] --> 主界面 : 进入系统 - -state 主界面 -state 开发者分析 -state 仓库概览 -state 网络图谱 -state 项目模式概览 -state 计算弹窗 -state 算法配置界面 -state "仓库详情 Modal" as 仓库详情 -state "项目 Overview (approx)" as 项目Approx -state "项目 Overview (full)" as 项目Full - -' 主界面导航 -主界面 --> 开发者分析 -主界面 --> 仓库概览 -主界面 --> 网络图谱 -主界面 --> 项目模式概览 -主界面 --> 计算弹窗 : 一键计算 - -' 计算弹窗返回刷新各视图 -计算弹窗 --> 主界面 : 提交 owner/repo -计算弹窗 --> 开发者分析 : 结果刷新 -计算弹窗 --> 仓库概览 : 结果刷新 -计算弹窗 --> 项目模式概览 : 可切换模式 - -' 仓库概览交互 -仓库概览 --> 仓库详情 : 查看详情 -仓库概览 --> 开发者分析 : 贡献分析 -仓库概览 --> 仓库概览 : 关键词/筛选 - -' 仓库详情交互 -仓库详情 --> 仓库详情 : 时间窗口/粒度 -仓库详情 --> 仓库概览 : 关闭 -仓库详情 --> 开发者分析 : 跳转贡献者 - -' 项目模式(approx/full)交互 -项目模式概览 --> 项目Approx : 选择仓库 -项目Approx --> 项目Full : 触发正式重算 -项目Full --> 项目Approx : 计算完成 替换 approx -项目Approx --> 项目Approx : 贡献者 Top/活动占比 -项目Approx --> 开发者分析 : 跳转贡献者分析 - -' 网络图谱与算法配置 -网络图谱 --> 算法配置界面 : 参数调节 -算法配置界面 --> 网络图谱 : 保存参数 -算法配置界面 --> 主界面 : 近似预览/正式重算 - -' 返回导航 -开发者分析 --> 主界面 : 返回 -仓库概览 --> 主界面 : 返回 -网络图谱 --> 主界面 : 返回 -项目模式概览 --> 主界面 : 返回 - -@enduml \ No newline at end of file diff --git a/picture/设计类图/前端子系统设计类图.vsdx b/picture/设计类图/前端子系统设计类图.vsdx new file mode 100644 index 0000000..8ea67f3 Binary files /dev/null and b/picture/设计类图/前端子系统设计类图.vsdx differ diff --git a/picture/设计类图/后端子系统设计类图.vsdx b/picture/设计类图/后端子系统设计类图.vsdx new file mode 100644 index 0000000..43871dd Binary files /dev/null and b/picture/设计类图/后端子系统设计类图.vsdx differ diff --git a/picture/设计类图/测评代码质量.puml b/picture/设计类图/测评代码质量.puml new file mode 100644 index 0000000..3290367 --- /dev/null +++ b/picture/设计类图/测评代码质量.puml @@ -0,0 +1,135 @@ +@startuml + +skinparam class { + BackgroundColor<> LightSkyBlue + BackgroundColor<> LightGreen + BackgroundColor<> Gold +} + +class MainUI <> { + - checkUI: CheckUI + + startPage() + + showMainInterface() + + navigateToCodeAssessmentPage() +} + +class CheckUI <> { + - pylint: Pylint + - currentAssessment: CodeAssessment + + showCodeAssessmentPage() + + uploadCodeToBeTested(code: CodeFile): boolean + + displayAssessmentResult(result: AssessmentResult) +} + +class Pylint <> { + - database: DateBase + + assessCodeQuality(code: CodeFile): AssessmentResult + + generateQualityReport(assessment: AssessmentResult): QualityReport +} + +class DateBase <> { + - codeAssessments: List + - qualityScores: List + - assessmentHistory: List + + storeCodeScore(assessment: CodeAssessment): boolean + + getAssessmentHistory(codeId: String): List + + getAverageQualityScore(projectId: String): double +} + +class CodeFile <> { + - codeId: String + - fileName: String + - filePath: String + - language: String + - content: String + - size: long + + getCodeId(): String + + getFileName(): String + + getLanguage(): String + + getContent(): String +} + +class AssessmentResult <> { + - assessmentId: String + - codeId: String + - qualityScore: double + - issues: List + - assessmentTime: Date + + getQualityScore(): double + + getIssues(): List + + generateSummary(): String +} + +class CodeAssessment <> { + - assessmentId: String + - codeFile: CodeFile + - result: AssessmentResult + - assessmentDate: Date + + getAssessmentId(): String + + getAssessmentDate(): Date + + getResult(): AssessmentResult +} + +class CodeIssue <> { + - issueId: String + - type: String + - severity: String + - lineNumber: int + - description: String + - suggestion: String + + getIssueId(): String + + getType(): String + + getSeverity(): String + + getDescription(): String +} + +class QualityScore <> { + - scoreId: String + - codeId: String + - overallScore: double + - maintainabilityScore: double + - reliabilityScore: double + - efficiencyScore: double + + getOverallScore(): double + + getMaintainabilityScore(): double + + calculateCompositeScore(): double +} + +class QualityReport <> { + - reportId: String + - assessmentId: String + - summary: String + - detailedAnalysis: String + - recommendations: List + + generateReport(): String + + exportAsPDF(): void +} + +class AssessmentHistory <> { + - 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 \ No newline at end of file diff --git a/picture/顺序图/测评代码质量.vsdx b/picture/顺序图/测评代码质量.vsdx new file mode 100644 index 0000000..371ac48 Binary files /dev/null and b/picture/顺序图/测评代码质量.vsdx differ