#!/usr/bin/env bash # ============================================================================== # 018_common_api_curl.sh # 通用数据接口(/api/common/v1)联调脚本 —— 对应 TrainCommonApiController 的 5 个 # Bearer 鉴权接口:student/list、plan/list、course/list、checkin/upload、score/upload # # 运行前提: # 1) 后端已启动(默认 http://localhost:8096) # 2) 已执行 018_common_api_test_data.sql(提供 student/course/plan 种子数据, # 否则 student/list、plan/list、course/list 返回空数组,上传外键会失败) # 3) sys_user 中存在下方 USERNAME 账号(默认 admin / admin123,按你环境调整) # 4) 已执行 015_train_test_data.sql(阅读机数据,与本脚本无关,仅作环境提示) # # 鉴权方式:先 POST /login 拿 Bearer token,后续接口统一带 Authorization 头 # —— 与“走 RuoYi Bearer 鉴权,Token 来源于 /login”完全一致。 # # 运行:在 Git Bash / WSL / 任意 bash 中执行 bash 018_common_api_curl.sh # 可用环境变量覆盖:BASE / USERNAME / PASSWORD # # 依赖:curl(必需);jq(可选,用于美化 JSON 与自动取 planId,缺失时自动降级) # ============================================================================== set -u BASE="${BASE:-http://localhost:8096}" USERNAME="${USERNAME:-admin}" PASSWORD="${PASSWORD:-admin123}" echo "==> [0] 获取 Bearer Token POST $BASE/login" LOGIN_RESP=$(curl -s -X POST "$BASE/login" \ -H 'Content-Type: application/json' \ -d "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}") if command -v jq >/dev/null 2>&1; then TOKEN=$(printf '%s' "$LOGIN_RESP" | jq -r '.data.token // empty') else TOKEN=$(printf '%s' "$LOGIN_RESP" | sed -n 's/.*"token":"\([^"]*\)".*/\1/p') fi if [ -z "$TOKEN" ]; then echo "✗ 登录失败,原始响应:" printf '%s\n' "$LOGIN_RESP" exit 1 fi echo "✓ 获取 token 成功(前20字符):${TOKEN:0:20}..." AUTH="Authorization: Bearer $TOKEN" # 有 jq 就美化输出,否则原样打印 pretty() { if command -v jq >/dev/null 2>&1; then jq .; else cat; fi } echo echo "==> [1] 学员信息列表 GET $BASE/api/common/v1/student/list" curl -s "$BASE/api/common/v1/student/list" -H "$AUTH" | pretty echo echo "==> [2] 班级(培训计划)列表 GET $BASE/api/common/v1/plan/list" PLAN_RESP=$(curl -s "$BASE/api/common/v1/plan/list" -H "$AUTH") printf '%s' "$PLAN_RESP" | pretty echo # 自动取第一个 planId 供 course/list 使用(无 jq / 空数据时回退占位) PLAN_ID="P2026001" if command -v jq >/dev/null 2>&1; then AUTO_PLAN=$(printf '%s' "$PLAN_RESP" | jq -r '.data[0].planId // empty') [ -n "$AUTO_PLAN" ] && PLAN_ID="$AUTO_PLAN" fi echo "(course/list 使用的 classId = $PLAN_ID,如需手动指定请在下方覆盖)" echo echo "==> [3] 班级课程信息 GET $BASE/api/common/v1/course/list?classId=$PLAN_ID" curl -s "$BASE/api/common/v1/course/list?classId=$PLAN_ID" -H "$AUTH" | pretty echo echo "==> [4] 上传考勤记录 POST $BASE/api/common/v1/checkin/upload" curl -s -X POST "$BASE/api/common/v1/checkin/upload" \ -H "$AUTH" -H 'Content-Type: application/json' \ -d '{ "planId":"'"$PLAN_ID"'", "planName":"2026年第1期接触网工培训班", "studentId":"S20260001", "studentName":"张三", "courseName":"接触网安全规程", "checkinWay":1, "signInTime":1761000000000, "signOutTime":1761003600000, "attendanceStatus":1, "boardSn":"BP-001", "boardName":"一班班牌" }' | pretty echo echo "==> [5] 上传实训成绩 POST $BASE/api/common/v1/score/upload" curl -s -X POST "$BASE/api/common/v1/score/upload" \ -H "$AUTH" -H 'Content-Type: application/json' \ -d '{ "planId":"'"$PLAN_ID"'", "cId":"C0001", "studentId":"S20260001", "courseScore":90.5, "trainScore":88.0, "examScore":95.0, "sourceType":3, "sourceSystem":"IOT", "importTime":1761000000000 }' | pretty echo echo "==> 完成。"