#!/usr/bin/env bash # EBOM API 测试脚本(依据 docs/Testing/EBOM-API测试文档.md) # 使用:先启动后端(如 mvn spring-boot:run -pl ktg-admin),再执行本脚本。 # 环境变量:BASE_URL(默认 http://localhost:8080)、TOKEN(可选,不设则尝试登录)、USERNAME、PASSWORD set -e BASE_URL="${BASE_URL:-http://localhost:8080}" USERNAME="${USERNAME:-admin}" PASSWORD="${PASSWORD:-admin123}" RESULT_DIR="${RESULT_DIR:-./test-results}" mkdir -p "$RESULT_DIR" REPORT="$RESULT_DIR/ebom-api-test-$(date +%Y%m%d-%H%M%S).txt" PASS=0 FAIL=0 log() { echo "[$(date +%H:%M:%S)] $*" | tee -a "$REPORT"; } run() { local name="$1" local method="$2" local path="$3" local data="$4" local extra="$5" local url="${BASE_URL}${path}" local out="$RESULT_DIR/response_${name}.json" local code="" if [[ "$method" == GET ]]; then if [[ -n "$extra" ]]; then url="${url}${extra}" fi code=$(curl -s -w '%{http_code}' -o "$out" -H "Authorization: Bearer ${TOKEN}" "$url") elif [[ "$method" == POST ]]; then code=$(curl -s -w '%{http_code}' -o "$out" -X POST -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}" -d "$data" "$url") elif [[ "$method" == PUT ]]; then code=$(curl -s -w '%{http_code}' -o "$out" -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}" -d "$data" "$url") elif [[ "$method" == DELETE ]]; then code=$(curl -s -w '%{http_code}' -o "$out" -X DELETE -H "Authorization: Bearer ${TOKEN}" "$url") fi local json_code="" if [[ -f "$out" ]] && [[ -s "$out" ]]; then json_code=$(grep -o '"code"[[:space:]]*:[[:space:]]*[0-9]*' "$out" | head -1 | grep -o '[0-9]*' || true) fi if [[ "$code" == 200 ]] && { [[ -z "$json_code" ]] || [[ "$json_code" == "200" ]]; }; then log "PASS $name ($method $path)" ((PASS++)) || true return 0 else log "FAIL $name ($method $path) HTTP=$code jsonCode=$json_code" [[ -f "$out" ]] && log " body: $(head -c 500 "$out")" ((FAIL++)) || true return 1 fi } # 登录获取 token(若未设置 TOKEN) if [[ -z "$TOKEN" ]]; then log "Login to get token..." login_out="$RESULT_DIR/login.json" http=$(curl -s -w '%{http_code}' -o "$login_out" -X POST -H "Content-Type: application/json" \ -d "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\",\"code\":\"\",\"uuid\":\"\"}" \ "$BASE_URL/login") if [[ "$http" != 200 ]]; then log "Login failed (HTTP $http). Set TOKEN manually or disable captcha. body: $(cat "$login_out")" exit 1 fi TOKEN=$(grep -o '"token"[[:space:]]*:[[:space:]]*"[^"]*"' "$login_out" | sed 's/.*:"\(.*\)"/\1/') if [[ -z "$TOKEN" ]]; then log "Login response had no token. body: $(cat "$login_out")" exit 1 fi log "Token obtained." fi log "========== EBOM API Tests ==========" log "BASE_URL=$BASE_URL" # 2.1 列表 run "bom-list" "GET" "/mes/md/bom/list" "" "" run "bom-list-status" "GET" "/mes/md/bom/list" "" "?pageNum=1&pageSize=10&status=DRAFT" run "bom-list-itemCode" "GET" "/mes/md/bom/list" "" "?pageNum=1&pageSize=10" # 2.2 详情(先取一条 id:从列表结果取第一个 bomId,若无则跳过) if [[ -f "$RESULT_DIR/response_bom-list.json" ]] && [[ -s "$RESULT_DIR/response_bom-list.json" ]]; then first_id=$(grep -o '"bomId"[[:space:]]*:[[:space:]]*[0-9]*' "$RESULT_DIR/response_bom-list.json" | head -1 | grep -o '[0-9]*' || true) if [[ -n "$first_id" ]]; then run "bom-get" "GET" "/mes/md/bom/$first_id" "" "" else log "SKIP bom-get (no bomId in list)" fi else log "SKIP bom-get (no list response)" fi # 2.3 新增 add_body='{"bomCode":"API-TEST-BOM-'$(date +%s)'","bomName":"API测试BOM","itemId":1,"itemCode":"ITEM01","itemName":"产品A","unitName":"台","baseQty":1,"version":"V1.0","versionDesc":"初版","status":"DRAFT","enableFlag":"Y","remark":"脚本测试"}' run "bom-add" "POST" "/mes/md/bom" "$add_body" # 从新增响应取 bomId 用于后续修改/审核/删除 new_bom_id="" if [[ -f "$RESULT_DIR/response_bom-add.json" ]]; then new_bom_id=$(grep -o '"bomId"[[:space:]]*:[[:space:]]*[0-9]*' "$RESULT_DIR/response_bom-add.json" | head -1 | grep -o '[0-9]*' || true) # 也可能在 data 里 if [[ -z "$new_bom_id" ]]; then new_bom_id=$(grep -o '"data"[[:space:]]*:[[:space:]]*{[^}]*"bomId"[^}]*}' "$RESULT_DIR/response_bom-add.json" | grep -o '"bomId"[[:space:]]*:[[:space:]]*[0-9]*' | grep -o '[0-9]*' || true) fi fi # 2.4 修改(若有新 id) if [[ -n "$new_bom_id" ]]; then update_body="{\"bomId\":$new_bom_id,\"bomCode\":\"API-TEST-BOM-UPD\",\"bomName\":\"API测试BOM(已改)\",\"itemId\":1,\"baseQty\":1,\"version\":\"V1.0\",\"status\":\"DRAFT\"}" run "bom-update" "PUT" "/mes/md/bom" "$update_body" fi # 2.6 审核 if [[ -n "$new_bom_id" ]]; then run "bom-approve" "PUT" "/mes/md/bom/approve" "{\"bomId\":$new_bom_id}" fi # 2.7 反审核 if [[ -n "$new_bom_id" ]]; then run "bom-reject" "PUT" "/mes/md/bom/reject" "{\"bomId\":$new_bom_id}" fi # 2.8 导出(只检查 HTTP 200 或 403) export_url="${BASE_URL}/mes/md/bom/export?pageNum=1&pageSize=10" export_code=$(curl -s -w '%{http_code}' -o "$RESULT_DIR/response_bom-export.bin" -H "Authorization: Bearer ${TOKEN}" "$export_url") if [[ "$export_code" == 200 ]]; then log "PASS bom-export (GET /mes/md/bom/export)" ((PASS++)) || true else log "FAIL bom-export HTTP=$export_code (may be 403 if no permission)" ((FAIL++)) || true fi # 3.1 明细列表 run "line-list" "GET" "/mes/md/bom/line/list" "" "?pageNum=1&pageSize=10" # 3.3 新增明细(需要有效的 bomCode/bomId,用上面 new_bom_id 或列表第一条的 bomCode) bom_code="API-TEST-BOM-UPD" if [[ -n "$new_bom_id" ]]; then line_add_body="{\"bomCode\":\"$bom_code\",\"itemId\":1,\"bomItemId\":2,\"bomItemCode\":\"MAT01\",\"bomItemName\":\"物料1\",\"quantity\":2,\"unitOfMeasure\":\"个\",\"lineNo\":1,\"supplyType\":\"PRODUCE\"}" run "line-add" "POST" "/mes/md/bom/line" "$line_add_body" fi # 2.5 删除(放在最后,删除本次新增的 BOM) if [[ -n "$new_bom_id" ]]; then run "bom-delete" "DELETE" "/mes/md/bom/$new_bom_id" "" "" fi log "========== Result: PASS=$PASS FAIL=$FAIL ==========" [[ $FAIL -gt 0 ]] && exit 1 || exit 0