feat: 实现成长路径功能
All checks were successful
continuous-integration/drone/push Build is passing

- 新增数据库表: growth_path_nodes, user_growth_path_progress, user_node_completions
- 新增 Model: GrowthPathNode, UserGrowthPathProgress, UserNodeCompletion
- 新增 Service: GrowthPathService(管理端CRUD、学员端进度追踪)
- 新增 API: 学员端获取成长路径、管理端CRUD
- 前端学员端从API动态加载成长路径数据
- 更新管理端API接口定义
This commit is contained in:
yuliang_guo
2026-01-30 15:37:14 +08:00
parent d44111e712
commit b4906c543b
11 changed files with 1816 additions and 154 deletions

View File

@@ -102,28 +102,97 @@ export interface CourseDetailForManager extends CourseInfo {
}>
}
// 成长路径配置
export interface GrowthPathConfig {
// 成长路径节点
export interface GrowthPathNode {
id: number
positionId: number
positionName: string
growth_path_id: number
course_id: number
course_name?: string
stage_name?: string
title: string
description?: string
order_num: number
is_required: boolean
prerequisites?: number[]
estimated_days: number
created_at: string
updated_at: string
}
// 阶段配置
export interface StageConfig {
name: string
description?: string
courses: Array<{
courseId: number
courseName: string
isRequired: boolean
prerequisites: number[]
order: number
estimatedDays: number
}>
totalCourses: number
requiredCourses: number
optionalCourses: number
estimatedDays: number
status: 'active' | 'inactive'
createdAt: string
updatedAt: string
order: number
}
// 成长路径配置(新版)
export interface GrowthPathConfig {
id: number
name: string
description?: string
target_role?: string
position_id?: number
position_name?: string
stages?: StageConfig[]
estimated_duration_days?: number
is_active: boolean
sort_order: number
nodes: GrowthPathNode[]
node_count: number
created_at: string
updated_at: string
}
// 成长路径列表项
export interface GrowthPathListItem {
id: number
name: string
description?: string
position_id?: number
position_name?: string
is_active: boolean
node_count: number
estimated_duration_days?: number
created_at: string
}
// 创建节点请求
export interface CreateGrowthPathNode {
course_id: number
stage_name?: string
title: string
description?: string
order_num: number
is_required: boolean
prerequisites?: number[]
estimated_days: number
}
// 创建成长路径请求
export interface CreateGrowthPathRequest {
name: string
description?: string
target_role?: string
position_id?: number
stages?: StageConfig[]
estimated_duration_days?: number
is_active?: boolean
sort_order?: number
nodes?: CreateGrowthPathNode[]
}
// 更新成长路径请求
export interface UpdateGrowthPathRequest {
name?: string
description?: string
target_role?: string
position_id?: number
stages?: StageConfig[]
estimated_duration_days?: number
is_active?: boolean
sort_order?: number
nodes?: CreateGrowthPathNode[]
}
// AI陪练场景管理视图
@@ -364,49 +433,44 @@ export const analyzeKnowledgePoints = (courseId: number) => {
*/
export const getGrowthPathConfigs = (params: {
page?: number
size?: number
positionId?: number
status?: string
page_size?: number
position_id?: number
is_active?: boolean
} = {}) => {
return request.get<{
items: GrowthPathConfig[]
items: GrowthPathListItem[]
total: number
page: number
size: number
page_size: number
}>('/api/v1/manager/growth-paths', { params })
}
/**
* 获取成长路径详情
*/
export const getGrowthPathDetail = (pathId: number) => {
return request.get<GrowthPathConfig>(`/api/v1/manager/growth-paths/${pathId}`)
}
/**
* 创建成长路径
*/
export const createGrowthPath = (data: {
positionId: number
name: string
description?: string
courses: Array<{
courseId: number
isRequired: boolean
prerequisites?: number[]
estimatedDays?: number
}>
}) => {
return request.post<GrowthPathConfig>('/api/v1/manager/growth-paths', data)
export const createGrowthPath = (data: CreateGrowthPathRequest) => {
return request.post<{ success: boolean; message: string; id: number }>('/api/v1/manager/growth-paths', data)
}
/**
* 更新成长路径
*/
export const updateGrowthPath = (pathId: number, data: {
name?: string
description?: string
courses?: Array<{
courseId: number
isRequired: boolean
prerequisites?: number[]
estimatedDays?: number
}>
}) => {
return request.put<GrowthPathConfig>(`/api/v1/manager/growth-paths/${pathId}`, data)
export const updateGrowthPath = (pathId: number, data: UpdateGrowthPathRequest) => {
return request.put<{ success: boolean; message: string }>(`/api/v1/manager/growth-paths/${pathId}`, data)
}
/**
* 删除成长路径
*/
export const deleteGrowthPath = (pathId: number) => {
return request.delete<{ success: boolean; message: string }>(`/api/v1/manager/growth-paths/${pathId}`)
}
/**

View File

@@ -40,7 +40,48 @@ export interface CourseMaterial {
createdAt: string
}
// 成长路径节点
// 成长路径节点(学员端)
export interface TraineeGrowthPathNode {
id: number
course_id: number
title: string
description?: string
stage_name?: string
is_required: boolean
estimated_days: number
order_num: number
status: 'locked' | 'unlocked' | 'in_progress' | 'completed'
progress: number
course_name?: string
course_cover?: string
}
// 成长路径阶段
export interface TraineeGrowthPathStage {
name: string
description?: string
completed: number
total: number
nodes: TraineeGrowthPathNode[]
}
// 成长路径(学员端响应)
export interface TraineeGrowthPath {
id: number
name: string
description?: string
position_id?: number
position_name?: string
total_progress: number
completed_nodes: number
total_nodes: number
status: 'not_started' | 'in_progress' | 'completed'
started_at?: string
estimated_completion_days?: number
stages: TraineeGrowthPathStage[]
}
// 兼容旧接口
export interface GrowthPathNode {
id: number
courseId: number
@@ -54,7 +95,7 @@ export interface GrowthPathNode {
order: number
}
// 成长路径
// 兼容旧接口
export interface GrowthPath {
id: number
name: string
@@ -226,10 +267,35 @@ export const markMaterialCompleted = (materialId: number) => {
}
/**
* 获取成长路径
* 获取成长路径(学员端)
*/
export const getGrowthPath = () => {
return request.get<GrowthPath>('/api/v1/trainee/growth-path')
export const getGrowthPath = (positionId?: number) => {
return request.get<TraineeGrowthPath>('/api/v1/trainee/growth-path', {
params: positionId ? { position_id: positionId } : {}
})
}
/**
* 开始学习成长路径
*/
export const startGrowthPath = (growthPathId: number) => {
return request.post<{ success: boolean; message: string; progress_id: number }>('/api/v1/trainee/growth-path/start', {
growth_path_id: growthPathId
})
}
/**
* 完成成长路径节点
*/
export const completeGrowthPathNode = (nodeId: number) => {
return request.post<{
completed: boolean
total_progress: number
is_path_completed: boolean
unlocked_nodes: number[]
}>('/api/v1/trainee/growth-path/node/complete', {
node_id: nodeId
})
}
/**