feat: 初始化考培练系统项目

- 从服务器拉取完整代码
- 按框架规范整理项目结构
- 配置 Drone CI 测试环境部署
- 包含后端(FastAPI)、前端(Vue3)、管理端

技术栈: Vue3 + TypeScript + FastAPI + MySQL
This commit is contained in:
111
2026-01-24 19:33:28 +08:00
commit 998211c483
1197 changed files with 228429 additions and 0 deletions

View File

@@ -0,0 +1,854 @@
openapi: 3.0.0
info:
title: Training Module API
description: 考培练系统陪练模块API契约
version: 1.0.0
servers:
- url: http://localhost:8000/api/v1
description: 本地开发服务器
paths:
/training/scenes:
get:
summary: 获取陪练场景列表
tags:
- 陪练场景
security:
- bearerAuth: []
parameters:
- name: category
in: query
description: 场景分类
schema:
type: string
- name: status
in: query
description: 场景状态
schema:
type: string
enum: [draft, active, inactive]
- name: is_public
in: query
description: 是否公开
schema:
type: boolean
- name: search
in: query
description: 搜索关键词
schema:
type: string
- name: page
in: query
description: 页码
schema:
type: integer
minimum: 1
default: 1
- name: page_size
in: query
description: 每页数量
schema:
type: integer
minimum: 1
maximum: 100
default: 20
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedScenesResponse'
'401':
$ref: '#/components/responses/Unauthorized'
post:
summary: 创建陪练场景(管理员)
tags:
- 陪练场景
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TrainingSceneCreate'
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/TrainingSceneResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/training/scenes/{scene_id}:
get:
summary: 获取陪练场景详情
tags:
- 陪练场景
security:
- bearerAuth: []
parameters:
- name: scene_id
in: path
required: true
description: 场景ID
schema:
type: integer
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/TrainingSceneResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
summary: 更新陪练场景(管理员)
tags:
- 陪练场景
security:
- bearerAuth: []
parameters:
- name: scene_id
in: path
required: true
description: 场景ID
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TrainingSceneUpdate'
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/TrainingSceneResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
delete:
summary: 删除陪练场景(管理员)
tags:
- 陪练场景
security:
- bearerAuth: []
parameters:
- name: scene_id
in: path
required: true
description: 场景ID
schema:
type: integer
responses:
'200':
description: 成功
content:
application/json:
schema:
type: object
properties:
code:
type: integer
example: 200
message:
type: string
example: "删除陪练场景成功"
data:
type: boolean
example: true
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/training/sessions:
post:
summary: 开始陪练会话
tags:
- 陪练会话
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/StartTrainingRequest'
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/StartTrainingResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
description: 场景不存在
get:
summary: 获取用户的陪练会话列表
tags:
- 陪练会话
security:
- bearerAuth: []
parameters:
- name: scene_id
in: query
description: 场景ID
schema:
type: integer
- name: status
in: query
description: 会话状态
schema:
type: string
enum: [created, in_progress, completed, cancelled, error]
- name: page
in: query
schema:
type: integer
minimum: 1
default: 1
- name: page_size
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedSessionsResponse'
'401':
$ref: '#/components/responses/Unauthorized'
/training/sessions/{session_id}:
get:
summary: 获取陪练会话详情
tags:
- 陪练会话
security:
- bearerAuth: []
parameters:
- name: session_id
in: path
required: true
description: 会话ID
schema:
type: integer
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/TrainingSessionResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/training/sessions/{session_id}/end:
post:
summary: 结束陪练会话
tags:
- 陪练会话
security:
- bearerAuth: []
parameters:
- name: session_id
in: path
required: true
description: 会话ID
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/EndTrainingRequest'
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/EndTrainingResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/training/sessions/{session_id}/messages:
get:
summary: 获取陪练会话的消息列表
tags:
- 陪练消息
security:
- bearerAuth: []
parameters:
- name: session_id
in: path
required: true
description: 会话ID
schema:
type: integer
- name: skip
in: query
description: 跳过数量
schema:
type: integer
minimum: 0
default: 0
- name: limit
in: query
description: 返回数量
schema:
type: integer
minimum: 1
maximum: 500
default: 100
responses:
'200':
description: 成功
content:
application/json:
schema:
type: object
properties:
code:
type: integer
message:
type: string
data:
type: array
items:
$ref: '#/components/schemas/TrainingMessage'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/training/reports:
get:
summary: 获取用户的陪练报告列表
tags:
- 陪练报告
security:
- bearerAuth: []
parameters:
- name: page
in: query
schema:
type: integer
minimum: 1
default: 1
- name: page_size
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedReportsResponse'
'401':
$ref: '#/components/responses/Unauthorized'
/training/reports/{report_id}:
get:
summary: 获取陪练报告详情
tags:
- 陪练报告
security:
- bearerAuth: []
parameters:
- name: report_id
in: path
required: true
description: 报告ID
schema:
type: integer
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/TrainingReportResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/training/sessions/{session_id}/report:
get:
summary: 根据会话ID获取陪练报告
tags:
- 陪练报告
security:
- bearerAuth: []
parameters:
- name: session_id
in: path
required: true
description: 会话ID
schema:
type: integer
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/TrainingReportResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
responses:
Unauthorized:
description: 未授权
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Forbidden:
description: 禁止访问
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
NotFound:
description: 资源未找到
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
schemas:
ErrorResponse:
type: object
properties:
code:
type: integer
message:
type: string
detail:
type: object
BaseResponse:
type: object
properties:
code:
type: integer
example: 200
message:
type: string
example: "success"
request_id:
type: string
PaginationMeta:
type: object
properties:
total:
type: integer
page:
type: integer
page_size:
type: integer
pages:
type: integer
TrainingSceneCreate:
type: object
required:
- name
- category
properties:
name:
type: string
maxLength: 100
description: 场景名称
description:
type: string
description: 场景描述
category:
type: string
maxLength: 50
description: 场景分类
ai_config:
type: object
description: AI配置
prompt_template:
type: string
description: 提示词模板
evaluation_criteria:
type: object
description: 评估标准
is_public:
type: boolean
default: true
description: 是否公开
required_level:
type: integer
description: 所需用户等级
status:
type: string
enum: [draft, active, inactive]
default: draft
TrainingSceneUpdate:
type: object
properties:
name:
type: string
maxLength: 100
description:
type: string
category:
type: string
maxLength: 50
ai_config:
type: object
prompt_template:
type: string
evaluation_criteria:
type: object
status:
type: string
enum: [draft, active, inactive]
is_public:
type: boolean
required_level:
type: integer
TrainingScene:
type: object
properties:
id:
type: integer
name:
type: string
description:
type: string
category:
type: string
ai_config:
type: object
prompt_template:
type: string
evaluation_criteria:
type: object
status:
type: string
enum: [draft, active, inactive]
is_public:
type: boolean
required_level:
type: integer
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
TrainingSceneResponse:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/TrainingScene'
PaginatedScenesResponse:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
data:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/TrainingScene'
total:
type: integer
page:
type: integer
page_size:
type: integer
pages:
type: integer
StartTrainingRequest:
type: object
required:
- scene_id
properties:
scene_id:
type: integer
description: 场景ID
config:
type: object
description: 会话配置
StartTrainingResponse:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
data:
type: object
properties:
session_id:
type: integer
coze_conversation_id:
type: string
scene:
$ref: '#/components/schemas/TrainingScene'
websocket_url:
type: string
EndTrainingRequest:
type: object
properties:
generate_report:
type: boolean
default: true
description: 是否生成报告
EndTrainingResponse:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
data:
type: object
properties:
session:
$ref: '#/components/schemas/TrainingSession'
report:
$ref: '#/components/schemas/TrainingReport'
TrainingSession:
type: object
properties:
id:
type: integer
user_id:
type: integer
scene_id:
type: integer
coze_conversation_id:
type: string
start_time:
type: string
format: date-time
end_time:
type: string
format: date-time
duration_seconds:
type: integer
status:
type: string
enum: [created, in_progress, completed, cancelled, error]
session_config:
type: object
total_score:
type: number
evaluation_result:
type: object
scene:
$ref: '#/components/schemas/TrainingScene'
message_count:
type: integer
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
TrainingSessionResponse:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/TrainingSession'
PaginatedSessionsResponse:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
data:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/TrainingSession'
total:
type: integer
page:
type: integer
page_size:
type: integer
pages:
type: integer
TrainingMessage:
type: object
properties:
id:
type: integer
session_id:
type: integer
role:
type: string
enum: [user, assistant, system]
type:
type: string
enum: [text, voice, system]
content:
type: string
voice_url:
type: string
voice_duration:
type: number
metadata:
type: object
coze_message_id:
type: string
created_at:
type: string
format: date-time
TrainingReport:
type: object
properties:
id:
type: integer
session_id:
type: integer
user_id:
type: integer
overall_score:
type: number
dimension_scores:
type: object
additionalProperties:
type: number
strengths:
type: array
items:
type: string
weaknesses:
type: array
items:
type: string
suggestions:
type: array
items:
type: string
detailed_analysis:
type: string
transcript:
type: string
statistics:
type: object
session:
$ref: '#/components/schemas/TrainingSession'
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
TrainingReportResponse:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/TrainingReport'
PaginatedReportsResponse:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
data:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/TrainingReport'
total:
type: integer
page:
type: integer
page_size:
type: integer
pages:
type: integer