v1.0.1: 课程成绩异常诊断与报告生成 - 初版骨架
基于匠厂 skill-template 主仓 v1.0.108 派生的业务技能。 核心业务: - 教师在教务系统录完成绩后自动触发 - 统计指标计算 + 三种异常模式识别(高分低能 / 两极分化 / 挂科异常) - 生成三段式 AI 评语(总体 / 问题 / 建议) 输出形态: - HTML 报告(含统计表 + 正态分布图 + AI 评语) - 高风险课程自动标记 + 异常预警通知 预期提效:教师撰写成绩分析报告的时间从半天 → 10 分钟。 业务行生命周期:无(一次性报告存档,不重复处理) Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
123
assets/actions.json
Normal file
123
assets/actions.json
Normal file
@@ -0,0 +1,123 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"skill": "analyze-grade-distribution-aa",
|
||||
"actions": [
|
||||
{
|
||||
"id": "health",
|
||||
"label": "运行检查",
|
||||
"description": "检查技能运行环境、教务系统 API 连通性、历史成绩库完整性。",
|
||||
"placements": ["skill-detail", "agent"],
|
||||
"executionProfile": "sync",
|
||||
"entrypoint": {
|
||||
"type": "cli",
|
||||
"command": "health",
|
||||
"args": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "version",
|
||||
"label": "查看版本",
|
||||
"description": "返回技能版本和机器标识。",
|
||||
"placements": ["skill-detail"],
|
||||
"executionProfile": "sync",
|
||||
"entrypoint": {
|
||||
"type": "cli",
|
||||
"command": "version",
|
||||
"args": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "config-path",
|
||||
"label": "查看配置位置",
|
||||
"description": "返回技能配置文件位置。",
|
||||
"placements": ["skill-detail"],
|
||||
"executionProfile": "sync",
|
||||
"entrypoint": {
|
||||
"type": "cli",
|
||||
"command": "config-path",
|
||||
"args": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "analyze-grade-distribution",
|
||||
"label": "分析这份成绩",
|
||||
"description": "对指定课程的成绩执行统计指标计算 + 三种异常模式识别 + AI 三段式评语生成,10~30 秒内返回报告。",
|
||||
"placements": ["row", "agent"],
|
||||
"executionProfile": "sync",
|
||||
"bind": {
|
||||
"tables": ["课程成绩"],
|
||||
"selectionMode": "required",
|
||||
"labelColumn": "课程名称"
|
||||
},
|
||||
"entrypoint": {
|
||||
"type": "cli",
|
||||
"command": "analyze-grade-distribution",
|
||||
"args": ["--course-id", "{row.课程ID}"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "batch-analyze-courses",
|
||||
"label": "批量分析本学期",
|
||||
"description": "批量分析某学期所有课程的成绩,按顺序逐门执行并汇总结果。",
|
||||
"placements": ["toolbar", "agent"],
|
||||
"executionProfile": "async",
|
||||
"bind": {
|
||||
"tables": ["课程成绩"]
|
||||
},
|
||||
"entrypoint": {
|
||||
"type": "cli",
|
||||
"command": "batch-analyze-courses",
|
||||
"args": ["--semester-id", "{form.semester_id}"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "render-html",
|
||||
"label": "查看分析报告",
|
||||
"description": "渲染指定分析报告的 HTML 页面,宿主 iframe 预览。",
|
||||
"placements": ["row", "skill-detail", "agent"],
|
||||
"executionProfile": "sync",
|
||||
"bind": {
|
||||
"tables": ["分析报告"],
|
||||
"selectionMode": "required",
|
||||
"labelColumn": "课程名称"
|
||||
},
|
||||
"entrypoint": {
|
||||
"type": "cli",
|
||||
"command": "render-html",
|
||||
"args": ["--report-id", "{row.报告ID}"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "flag-high-risk-course",
|
||||
"label": "标记为高风险课程",
|
||||
"description": "手动将某门课程标记为高风险课程,推送通知给教学督导与学院教学副院长。",
|
||||
"placements": ["row"],
|
||||
"executionProfile": "sync",
|
||||
"bind": {
|
||||
"tables": ["分析报告"],
|
||||
"selectionMode": "required",
|
||||
"labelColumn": "课程名称"
|
||||
},
|
||||
"entrypoint": {
|
||||
"type": "cli",
|
||||
"command": "flag-high-risk-course",
|
||||
"args": ["--report-id", "{row.报告ID}"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "sync-historical-grades",
|
||||
"label": "同步历史成绩",
|
||||
"description": "从教务系统重新拉取历史成绩数据。占位 Action,cron 启用后由定时调度。",
|
||||
"placements": ["cron", "agent", "toolbar"],
|
||||
"executionProfile": "async",
|
||||
"bind": {
|
||||
"tables": ["历史成绩"]
|
||||
},
|
||||
"entrypoint": {
|
||||
"type": "cli",
|
||||
"command": "sync-historical-grades",
|
||||
"args": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
145
assets/html/example-report.html
Normal file
145
assets/html/example-report.html
Normal file
@@ -0,0 +1,145 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>{{TITLE}}</title>
|
||||
<style>
|
||||
/* 数据管理 iframe 预览布局基线 */
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 16px;
|
||||
font-family: -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
color: #1f2329;
|
||||
background: #fafbfc;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.report { max-width: 100%; }
|
||||
.header {
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #7c3aed 0%, #a855f7 100%);
|
||||
color: #fff;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.header h1 { margin: 0 0 8px; font-size: 22px; }
|
||||
.header .meta { color: #ede9fe; font-size: 13px; }
|
||||
.risk-badge {
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin-left: 8px;
|
||||
}
|
||||
.risk-badge.high { background: #fef2f2; color: #c53030; }
|
||||
.risk-badge.normal { background: #ecfdf5; color: #059669; }
|
||||
.section {
|
||||
padding: 16px 20px;
|
||||
background: #fff;
|
||||
border: 1px solid #e5e6eb;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.section h2 { margin: 0 0 12px; font-size: 16px; color: #6d28d9; }
|
||||
.stat-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
.stat-card {
|
||||
padding: 12px 16px;
|
||||
background: #faf5ff;
|
||||
border: 1px solid #e9d5ff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.stat-card .label { color: #8b5cf6; font-size: 12px; }
|
||||
.stat-card .value { font-size: 20px; font-weight: 700; margin-top: 4px; color: #4c1d95; }
|
||||
.stat-card .unit { font-size: 12px; color: #8b5cf6; margin-left: 4px; }
|
||||
.distribution {
|
||||
padding: 16px;
|
||||
background: #faf5ff;
|
||||
border: 1px dashed #c4b5fd;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
color: #6d28d9;
|
||||
font-style: italic;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.anomaly-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.anomaly-list li {
|
||||
padding: 12px 16px;
|
||||
border-left: 4px solid #cbd5e1;
|
||||
background: #f8fafc;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.anomaly-list li.high { border-left-color: #c53030; background: #fef2f2; color: #991b1b; }
|
||||
.anomaly-list li.normal { border-left-color: #059669; background: #ecfdf5; color: #065f46; }
|
||||
.anomaly-list li strong { display: block; margin-bottom: 4px; }
|
||||
.comment-block {
|
||||
padding: 14px 18px;
|
||||
background: #faf5ff;
|
||||
border-left: 4px solid #a855f7;
|
||||
border-radius: 4px;
|
||||
color: #4c1d95;
|
||||
margin-bottom: 8px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.comment-block strong { display: block; margin-bottom: 6px; color: #6d28d9; }
|
||||
.footer { margin-top: 16px; color: #8c959f; font-size: 12px; text-align: right; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="report">
|
||||
<div class="header">
|
||||
<h1>{{TITLE}}<span class="risk-badge {{RISK_CLASS}}">{{RISK_LABEL}}</span></h1>
|
||||
<div class="meta">报告编号:{{REPORT_ID}} · 课程:{{COURSE_NAME}} · 任课教师:{{TEACHER_NAME}}</div>
|
||||
<div class="meta">学期:{{SEMESTER}} · 分析完成时间:{{GENERATED_AT}}</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>统计指标</h2>
|
||||
<div class="stat-grid">
|
||||
<div class="stat-card"><div class="label">最高分</div><div class="value">{{MAX_SCORE}}<span class="unit">分</span></div></div>
|
||||
<div class="stat-card"><div class="label">最低分</div><div class="value">{{MIN_SCORE}}<span class="unit">分</span></div></div>
|
||||
<div class="stat-card"><div class="label">平均分</div><div class="value">{{AVG_SCORE}}<span class="unit">分</span></div></div>
|
||||
<div class="stat-card"><div class="label">中位数</div><div class="value">{{MEDIAN_SCORE}}<span class="unit">分</span></div></div>
|
||||
<div class="stat-card"><div class="label">标准差</div><div class="value">{{STD_SCORE}}</div></div>
|
||||
<div class="stat-card"><div class="label">及格率</div><div class="value">{{PASS_RATE}}<span class="unit">%</span></div></div>
|
||||
<div class="stat-card"><div class="label">优秀率</div><div class="value">{{EXCELLENT_RATE}}<span class="unit">%</span></div></div>
|
||||
<div class="stat-card"><div class="label">学生数</div><div class="value">{{STUDENT_COUNT}}</div></div>
|
||||
</div>
|
||||
<div class="distribution">{{DISTRIBUTION_PLACEHOLDER}}</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>异常模式识别</h2>
|
||||
<ul class="anomaly-list">
|
||||
{{ANOMALY_BODY}}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>AI 评语(草稿,请教师修改后存档)</h2>
|
||||
<div class="comment-block">
|
||||
<strong>📊 总体描述</strong>
|
||||
{{COMMENT_OVERVIEW}}
|
||||
</div>
|
||||
<div class="comment-block">
|
||||
<strong>⚠️ 存在问题</strong>
|
||||
{{COMMENT_ISSUES}}
|
||||
</div>
|
||||
<div class="comment-block">
|
||||
<strong>💡 改进建议</strong>
|
||||
{{COMMENT_SUGGESTIONS}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">本报告由「课程成绩异常诊断与报告生成」技能自动生成 · 最终评价权归教学督导与学院</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user