通知
build / build-push (push) Failing after 1m13s

This commit is contained in:
wanghu
2026-09-10 15:40:38 +08:00
parent 3016a97f1b
commit e20ba5f38b
25 changed files with 955 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
#!/bin/bash
# CampusNotice 接口 curl 测试脚本 v2
# 用法: ./api-curl-test.sh [BASE] [PLATFORM]
# BASE 默认 http://localhost:8101
# PLATFORM 默认 manage(CAS 仅拦 /api/* 与 /mobiapi/*,manage 为匿名通道;生产环境应封死,见安全提醒)
# 注意:中文 JSON 体必须走 UTF-8 文件(--data-binary @file),
# 直接 -d '中文' 会被 Git Bash→curl.exe 的 argv 转换变成 GBK,服务端报
# Invalid UTF-8 start byte(HttpMessageNotReadable → code=6),属测试工具问题。
BASE="${1:-http://localhost:8101}"
PF="${2:-manage}"
U="$BASE/$PF"
TMPB="$(dirname "$0")/.curl-body.json"
PASS=0; BIZ=0; FAIL=0
CREATED_IDS=()
req() { # req 名称 方法 路径 [json体]
local name="$1" method="$2" path="$3" body="$4"
local args=(-s --max-time 15 -w "\n%{http_code}" -H "Accept: application/json")
if [ -n "$body" ]; then
printf '%s' "$body" > "$TMPB" # UTF-8 原样字节落盘
args+=(-X POST -H "Content-Type: application/json; charset=utf-8" --data-binary "@$(cygpath -w "$TMPB" 2>/dev/null || echo "$TMPB")")
elif [ "$method" = "POST" ]; then
args+=(-X POST)
fi
local out; out=$(curl "${args[@]}" "$U$path" 2>/dev/null)
local http="${out##*$'\n'}"; local json="${out%$'\n'*}"
local parsed; parsed=$(node -e "
try{const j=JSON.parse(process.argv[1]);
const d=j.data;
const ds=d===null||d===undefined?'null':Array.isArray(d)?'array['+d.length+']':typeof d==='object'?'{'+Object.keys(d).slice(0,4).join(',')+'}':String(d).slice(0,30);
console.log([j.code,(j.msg||'').slice(0,46),ds].join('\u0001'));
}catch(e){console.log(['-','-','-'].join('\u0001'))}" "$json" 2>/dev/null)
local code msg data
code=$(echo "$parsed" | cut -d$'\001' -f1)
msg=$(echo "$parsed" | cut -d$'\001' -f2)
data=$(echo "$parsed" | cut -d$'\001' -f3)
local st
if [ "$code" = "0" ]; then PASS=$((PASS+1)); st="✅PASS";
elif [ "$code" = "-" ] || [ "$http" != "200" ]; then FAIL=$((FAIL+1)); st="❌FAIL";
else BIZ=$((BIZ+1)); st="🟡BIZ"; fi
printf "%-26s | HTTP %s | code=%-3s | msg=%-46s | data=%s\n" "$name" "$http" "$code" "$msg" "$data"
}
extract_id() { # 从最近一次输出无法跨函数取值,改为调用方直接用 node 从 curl 结果提取
node -e "try{console.log(JSON.parse(require('fs').readFileSync(process.argv[1],'utf8')).data ?? '')}catch(e){console.log('')}" "$1" 2>/dev/null
}
echo "================ CampusNotice curl 矩阵 (BASE=$BASE PF=$PF) ================"
echo "---- A. 静态(直连 BASE,不经 platform 前缀) ----"
for p in "/" "/api-test.html"; do
http=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$BASE$p")
if [ "$http" = "200" ]; then PASS=$((PASS+1)); printf "%-26s | HTTP %s\n" "静态 $p" "$http"; else FAIL=$((FAIL+1)); printf "%-26s | HTTP %s ❌\n" "静态 $p" "$http"; fi
done
http=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$BASE/api/notice/Statis")
if [ "$http" = "302" ]; then PASS=$((PASS+1)); printf "%-26s | HTTP 302 → CAS 登录墙(符合预期)\n" "/api 登录墙对照"; else FAIL=$((FAIL+1)); printf "%-26s | HTTP $http ❌(预期302)\n" "/api 登录墙对照"; fi
echo "---- B. 平台/基础(匿名语义) ----"
req "GetUserInfo" GET "/base/GetUserInfo"
req "GetUserMod(匿名预期拒)" GET "/base/GetUserMod"
req "GetSchoolAll" GET "/base/GetSchoolAll"
req "GetGroupUser(未接入桩)" GET "/base/GetGroupUser?gid=1&role=2"
echo "---- C. 通知查询 ----"
req "notice/List" GET "/notice/List?pageIndex=1&pageSize=3"
req "notice/SendList" GET "/notice/SendList?pageIndex=1&pageSize=3&status=1&scope=user"
req "notice/Statis" GET "/notice/Statis"
req "notice/GetNextPrev" GET "/notice/GetNextPrev?serid=1&type=0"
req "notice/DraftList" GET "/notice/DraftList?pageIndex=1&pageSize=3"
req "notice/ApproverSuggest" GET "/notice/ApproverSuggest"
req "ApprovalList(pending)" GET "/notice/ApprovalList?auditState=pending&pageIndex=1&pageSize=3"
req "ApprovalList(reviewed)" GET "/notice/ApprovalList?auditState=reviewed&pageIndex=1&pageSize=3"
echo "---- D. 推送范围(匿名预期拒) ----"
req "notice/ScopeTree" GET "/notice/ScopeTree"
req "notice/ScopePreview" GET "/notice/ScopePreview?scopes=%5B%7B%22scopeType%22%3A1%2C%22scopeId%22%3A0%2C%22scopeName%22%3A%22%E5%85%A8%E6%A0%A1%22%7D%5D"
echo "---- E. 写链路(UTF-8 文件体,测后自清理) ----"
printf '%s' '{"title":"【测试】curl直发","content":"<p>curl</p>","type":1,"deptId":"1","deptName":"校长室","topmost":0,"receiveList":"ALL","fileIds":"","timingSendTime":null,"smsFlag":0,"receiptFlag":1,"publishType":"direct"}' > "$TMPB"
resp=$(curl -s --max-time 15 -X POST -H "Content-Type: application/json; charset=utf-8" --data-binary "@$(cygpath -w "$TMPB" 2>/dev/null || echo "$TMPB")" "$U/notice/Create")
echo "$resp" > "$TMPB.out"
ID_DIRECT=$(extract_id "$TMPB.out")
if [ -n "$ID_DIRECT" ]; then PASS=$((PASS+1)); printf "%-26s | code=0 | id=%s ✅\n" "Create(direct)" "$ID_DIRECT"; else FAIL=$((FAIL+1)); printf "%-26s | ❌ 未返回id\n" "Create(direct)"; fi
CREATED_IDS+=("$ID_DIRECT")
printf '%s' '{"title":"【测试】curl草稿","content":"<p>curl</p>","type":1,"deptId":"1","deptName":"校长室","topmost":0,"receiveList":"ALL","fileIds":"","timingSendTime":null,"smsFlag":0,"receiptFlag":1}' > "$TMPB"
resp=$(curl -s --max-time 15 -X POST -H "Content-Type: application/json; charset=utf-8" --data-binary "@$(cygpath -w "$TMPB" 2>/dev/null || echo "$TMPB")" "$U/notice/SaveDraft")
echo "$resp" > "$TMPB.out"
ID_DRAFT=$(extract_id "$TMPB.out")
if [ -n "$ID_DRAFT" ]; then PASS=$((PASS+1)); printf "%-26s | code=0 | id=%s ✅\n" "SaveDraft" "$ID_DRAFT"; else FAIL=$((FAIL+1)); printf "%-26s | ❌ 未返回id\n" "SaveDraft"; fi
CREATED_IDS+=("$ID_DRAFT")
if [ -n "$ID_DRAFT" ]; then
printf '%s' "{\"serid\":$ID_DRAFT,\"approverAccounts\":[\"lijing\"],\"opinion\":\"请审批\"}" > "$TMPB"
resp=$(curl -s --max-time 15 -X POST -H "Content-Type: application/json; charset=utf-8" --data-binary "@$(cygpath -w "$TMPB" 2>/dev/null || echo "$TMPB")" "$U/notice/Submit")
code=$(node -e "try{console.log(JSON.parse(process.argv[1]).code)}catch(e){console.log('-')}" "$resp")
if [ "$code" = "0" ]; then PASS=$((PASS+1)); printf "%-26s | code=0 | 草稿→待审批 ✅\n" "Submit"; else BIZ=$((BIZ+1)); printf "%-26s | code=%s 🟡\n" "Submit" "$code"; fi
fi
req "Approve(匿名预期拒)" POST "/notice/Approve?serid=${ID_DRAFT:-0}&opinion=x"
req "Reject(匿名预期拒)" POST "/notice/Reject?serid=${ID_DRAFT:-0}&opinion=x"
echo "---- F. 其他模块 ----"
req "dict/ManageList" GET "/dict/ManageList"
req "template/Typelist" GET "/template/Typelist"
req "contacts/GetGroup" GET "/contacts/GetGroup"
req "sms/GetSchool" GET "/sms/GetSchool"
echo "---- G. 附件 ----"
f="$(dirname "$0")/.curl-upload-sample.txt"; echo "curl upload sample $(date +%s)" > "$f"
req "base/FileUpload" POST "/base/FileUpload" "" "file=@$(cygpath -w "$f" 2>/dev/null || echo "$f")"
rm -f "$f"
echo "---- H. 清理测试数据 ----"
if [ "${#CREATED_IDS[@]}" -gt 0 ]; then
ids=$(IFS=,; echo "${CREATED_IDS[*]}")
printf '%s' "[$ids]" > "$TMPB"
resp=$(curl -s --max-time 15 -X POST -H "Content-Type: application/json; charset=utf-8" --data-binary "@$(cygpath -w "$TMPB" 2>/dev/null || echo "$TMPB")" "$U/notice/Delete")
code=$(node -e "try{console.log(JSON.parse(process.argv[1]).code)}catch(e){console.log('-')}" "$resp")
if [ "$code" = "0" ]; then PASS=$((PASS+1)); printf "%-26s | code=0 | ids=[$ids] 已清理 ✅\n" "Delete清理"; else FAIL=$((FAIL+1)); printf "%-26s | code=%s ❌\n" "Delete清理" "$code"; fi
fi
rm -f "$TMPB" "$TMPB.out"
echo "================ 统计: PASS=$PASS BIZ(业务拒绝/环境预期)=$BIZ FAIL=$FAIL ================"
echo "提醒: /manage 匿名可访问全部业务接口——CAS 仅拦 /api/* 与 /mobiapi/*,生产环境务必封死(安全项)。"