443 lines
22 KiB
Bash
Executable File
443 lines
22 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
API="http://127.0.0.1:8080/api"
|
||
|
||
extract_id() { sed -n -E 's/.*"id":([0-9]+).*/\1/p'; }
|
||
|
||
# 使用变量承载 JSON,避免直接使用管道导致的 broken pipe
|
||
get_menu_id_by_parent_and_path(){
|
||
local parent_id="$1"; local path="$2"
|
||
local MENUS
|
||
MENUS=$(curl -s -X GET "$API/menus" -H "$H_AUTH")
|
||
echo "$MENUS" | P="$path" PID="$parent_id" python3 - <<'PY'
|
||
import json,sys,os
|
||
try:
|
||
data=json.load(sys.stdin)
|
||
except Exception:
|
||
sys.exit(0)
|
||
menus=data.get("data", [])
|
||
P=os.environ.get("P")
|
||
PID=os.environ.get("PID")
|
||
try:
|
||
pid_int=None if PID in (None, "", "null") else int(PID)
|
||
except Exception:
|
||
pid_int=None
|
||
for m in menus:
|
||
if m.get("path")==P and ((pid_int is None and m.get("parent_id") is None) or (pid_int is not None and m.get("parent_id")==pid_int)):
|
||
print(m.get("id"), end="")
|
||
break
|
||
PY
|
||
}
|
||
get_menu_id_by_parent_and_name(){
|
||
local parent_id="$1"; local name="$2"
|
||
local MENUS
|
||
MENUS=$(curl -s -X GET "$API/menus" -H "$H_AUTH")
|
||
echo "$MENUS" | N="$name" PID="$parent_id" python3 - <<'PY'
|
||
import json,sys,os
|
||
try:
|
||
data=json.load(sys.stdin)
|
||
except Exception:
|
||
sys.exit(0)
|
||
menus=data.get("data", [])
|
||
N=os.environ.get("N")
|
||
PID=os.environ.get("PID")
|
||
try:
|
||
pid_int=None if PID in (None, "", "null") else int(PID)
|
||
except Exception:
|
||
pid_int=None
|
||
for m in menus:
|
||
if m.get("name")==N and ((pid_int is None and m.get("parent_id") is None) or (pid_int is not None and m.get("parent_id")==pid_int)):
|
||
print(m.get("id"), end="")
|
||
break
|
||
PY
|
||
}
|
||
create_or_get_menu(){
|
||
# parent_id name type path component icon order_no [visible] [status] [keep_alive]
|
||
local parent_id="$1"; local name="$2"; local mtype="$3"; local path="$4"; local component="$5"; local icon="$6"; local order_no="$7"; local visible="${8:-true}"; local status="${9:-1}"; local keep_alive="${10:-true}"
|
||
local id=""
|
||
if [ -n "$path" ]; then id=$(get_menu_id_by_parent_and_path "$parent_id" "$path") || true; fi
|
||
if [ -z "$id" ]; then id=$(get_menu_id_by_parent_and_name "$parent_id" "$name") || true; fi
|
||
if [ -n "$id" ]; then echo "$id"; return 0; fi
|
||
# 规范化可选字段为 JSON 合法值
|
||
local j_parent j_path j_comp j_icon j_order
|
||
if [ -n "${parent_id:-}" ]; then j_parent="$parent_id"; else j_parent="null"; fi
|
||
if [ -n "${path:-}" ]; then j_path="\"$path\""; else j_path="null"; fi
|
||
if [ -n "${component:-}" ]; then j_comp="\"$component\""; else j_comp="null"; fi
|
||
if [ -n "${icon:-}" ]; then j_icon="\"$icon\""; else j_icon="null"; fi
|
||
j_order="${order_no:-0}"
|
||
local payload
|
||
payload=$(cat <<JSON
|
||
{"parent_id":$j_parent,"name":"$name","path":$j_path,"component":$j_comp,"type":$mtype,"icon":$j_icon,"order_no":$j_order,"visible":$visible,"status":$status,"keep_alive":$keep_alive}
|
||
JSON
|
||
)
|
||
local resp; resp=$(echo "$payload" | curl -s -X POST "$API/menus" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
id=$(echo "$resp" | extract_id)
|
||
echo "$id"
|
||
}
|
||
|
||
# 1) Admin login
|
||
LOGIN_JSON=$(printf '{"username":"admin","password":"Admin@123"}' | curl -s -X POST "$API/auth/login" -H "Content-Type: application/json" --data-binary @-)
|
||
TOKEN=$(echo "$LOGIN_JSON" | sed -n -E 's/.*"access_token":"([^"]*)".*/\1/p')
|
||
if [ -z "$TOKEN" ]; then echo "[ERROR] Admin 登录失败: $LOGIN_JSON"; exit 1; fi
|
||
H_AUTH="Authorization: Bearer $TOKEN"
|
||
echo "[OK] Admin 登录成功"
|
||
|
||
# 1b) 去重清理:仅保留最早创建的根菜单,删除其余重复的根及子树
|
||
cleanup_duplicate_roots(){
|
||
local ROOT_NAME="$1"; local ROOT_TYPE="$2"
|
||
local MENUS JSON
|
||
MENUS=$(curl -s -X GET "$API/menus" -H "$H_AUTH")
|
||
# 计算应保留的 root_id 与需要删除的 root_ids
|
||
JSON=$(echo "$MENUS" | NAME="$ROOT_NAME" RTYPE="$ROOT_TYPE" python3 - <<'PY'
|
||
import json,sys,os
|
||
try:
|
||
data=json.load(sys.stdin)
|
||
menus=data.get("data", [])
|
||
except Exception:
|
||
menus=[]
|
||
NAME=os.environ.get("NAME")
|
||
RTYPE=int(os.environ.get("RTYPE") or 0)
|
||
roots=[m for m in menus if m.get("name")==NAME and m.get("parent_id") is None and m.get("type")==RTYPE]
|
||
roots=sorted(roots, key=lambda m: m.get("id") or 1<<30)
|
||
keep_id=str(roots[0].get("id")) if roots else ""
|
||
duplicates=[str(m.get("id")) for m in roots[1:]]
|
||
# 构建子树映射
|
||
children={}
|
||
for m in menus:
|
||
pid=m.get("parent_id")
|
||
if pid is None: continue
|
||
children.setdefault(str(pid), []).append(str(m.get("id")))
|
||
# 计算每个重复根的删除顺序(自底向上)
|
||
orders={}
|
||
from collections import deque
|
||
for rid in duplicates:
|
||
order=[]
|
||
# BFS 收集所有节点
|
||
q=deque([rid])
|
||
seen=set()
|
||
while q:
|
||
x=q.popleft()
|
||
if x in seen: continue
|
||
seen.add(x)
|
||
for c in children.get(x, []):
|
||
q.append(c)
|
||
order.append(x)
|
||
# 逆序删除(叶 -> 根)
|
||
orders[rid]=list(reversed(order))
|
||
print(json.dumps({"keep": keep_id, "dups": duplicates, "orders": orders}))
|
||
PY
|
||
)
|
||
local KEEP_ID; KEEP_ID=$(echo "$JSON" | sed -n -E 's/.*"keep":"?([0-9]+)"?.*/\1/p')
|
||
local DUPS; DUPS=$(echo "$JSON" | sed -n -E 's/.*"dups":\[([^\]]*)\].*/\1/p' | tr -d '" ')
|
||
if [ -n "${DUPS:-}" ]; then
|
||
echo "[INFO] 发现重复根菜单: $ROOT_NAME (type=$ROOT_TYPE),保留ID=$KEEP_ID,待清理: [$DUPS]"
|
||
# 逐个根依次删除其子树
|
||
for rid in $(echo "$DUPS" | tr ',' ' '); do
|
||
local ORDER; ORDER=$(echo "$JSON" | RID="$rid" python3 - <<'PY'
|
||
import json,sys,os
|
||
obj=json.load(sys.stdin)
|
||
rid=os.environ.get("RID")
|
||
print(",".join(obj.get("orders", {}).get(rid, [])), end="")
|
||
PY
|
||
)
|
||
for id in $(echo "$ORDER" | tr ',' ' '); do
|
||
# 逐个删除(叶优先),失败重试一次
|
||
RES=$(curl -s -X DELETE "$API/menus/$id" -H "$H_AUTH" || true)
|
||
echo "$RES" | grep -q '"code":0' || {
|
||
sleep 0.2
|
||
RES=$(curl -s -X DELETE "$API/menus/$id" -H "$H_AUTH" || true)
|
||
echo "$RES" | grep -q '"code":0' || echo "[WARN] 删除菜单失败(id=$id): $RES"
|
||
}
|
||
done
|
||
done
|
||
echo "[OK] 已清理 $ROOT_NAME 重复根菜单"
|
||
fi
|
||
}
|
||
|
||
# 如数据库已存在相同根菜单,先做去重清理
|
||
cleanup_duplicate_roots "演示-系统管理" 0 || true
|
||
cleanup_duplicate_roots "系统管理" 1 || true
|
||
|
||
# 2) Create demo menus(可通过环境变量 SKIP_DEMO=1 跳过)
|
||
if [ "${SKIP_DEMO:-0}" != "1" ]; then
|
||
# 幂等:优先查找已存在的“演示-系统管理”,否则创建(基于 Python 解析)
|
||
MENUS_JSON=$(curl -s -X GET "$API/menus" -H "$H_AUTH")
|
||
DEMO_ROOT_ID=$(echo "$MENUS_JSON" | python3 - <<'PY'
|
||
import json,sys
|
||
try:
|
||
data=json.load(sys.stdin)
|
||
menus=data.get("data", [])
|
||
except Exception:
|
||
menus=[]
|
||
for m in menus:
|
||
if m.get("name")=="演示-系统管理" and m.get("type")==0 and m.get("parent_id") is None:
|
||
print(m.get("id"), end="")
|
||
break
|
||
PY
|
||
)
|
||
if [ -z "${DEMO_ROOT_ID:-}" ]; then
|
||
DEMO_ROOT_JSON=$(printf '{"name":"演示-系统管理","type":0,"order_no":100,"visible":true,"status":1}' | curl -s -X POST "$API/menus" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
DEMO_ROOT_ID=$(echo "$DEMO_ROOT_JSON" | extract_id)
|
||
fi
|
||
if [ -z "${DEMO_ROOT_ID:-}" ]; then echo "[ERROR] 创建/获取 演示-系统管理 根菜单失败"; exit 1; fi
|
||
|
||
USERS_ID=$(create_or_get_menu "$DEMO_ROOT_ID" "演示-用户管理" 1 "/demo/users" "Users" "" 10)
|
||
ROLES_ID=$(create_or_get_menu "$DEMO_ROOT_ID" "演示-角色管理" 1 "/demo/roles" "Roles" "" 20)
|
||
MENUS_ID=$(create_or_get_menu "$DEMO_ROOT_ID" "演示-菜单管理" 1 "/demo/menus" "Menus" "" 30)
|
||
PERMS_ID=$(create_or_get_menu "$DEMO_ROOT_ID" "演示-权限管理" 1 "/demo/perms" "Permissions" "" 40)
|
||
DEPT_ID=$(create_or_get_menu "$DEMO_ROOT_ID" "演示-部门管理" 1 "/demo/departments" "Departments" "" 50)
|
||
POS_ID=$(create_or_get_menu "$DEMO_ROOT_ID" "演示-岗位管理" 1 "/demo/positions" "Positions" "" 60)
|
||
|
||
echo "[OK] 演示菜单准备完成: ROOT=$DEMO_ROOT_ID USERS=$USERS_ID ROLES=$ROLES_ID MENUS=$MENUS_ID PERMS=$PERMS_ID DEPT=$DEPT_ID POS=$POS_ID"
|
||
else
|
||
echo "[INFO] 已设置 SKIP_DEMO=1,跳过演示菜单创建"
|
||
fi
|
||
|
||
# [INFO] 演示菜单已通过幂等逻辑创建/获取,避免重复
|
||
# 3) Create demo role
|
||
TS=$(date +%s)
|
||
ROLE_NAME="演示-经理-${TS}"
|
||
ROLE_CODE="demo_manager_${TS}"
|
||
ROLE_JSON=$(printf '{"name":"%s","code":"%s","status":1}' "$ROLE_NAME" "$ROLE_CODE" | curl -s -X POST "$API/roles" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
ROLE_ID=$(echo "$ROLE_JSON" | extract_id); if [ -z "$ROLE_ID" ]; then echo "[ERROR] 创建角色失败: $ROLE_JSON"; exit 1; fi
|
||
|
||
echo "[OK] 创建角色成功: $ROLE_NAME (id=$ROLE_ID)"
|
||
|
||
# 4) Bind menus to the role
|
||
IDS=""
|
||
for v in "${USERS_ID:-}" "${ROLES_ID:-}" "${MENUS_ID:-}" "${PERMS_ID:-}" "${DEPT_ID:-}" "${POS_ID:-}"; do
|
||
if [ -n "$v" ]; then
|
||
if [ -n "$IDS" ]; then IDS="$IDS,$v"; else IDS="$v"; fi
|
||
fi
|
||
done
|
||
if [ -n "$IDS" ]; then
|
||
BIND_MENU_JSON=$(printf '{"ids":[%s]}' "$IDS" | curl -s -X PUT "$API/roles/$ROLE_ID/menus" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
echo "$BIND_MENU_JSON" | grep -q '"code":0' || { echo "[ERROR] 绑定角色菜单失败: $BIND_MENU_JSON"; exit 1; }
|
||
echo "[OK] 绑定角色菜单成功"
|
||
else
|
||
echo "[WARN] 无可绑定的演示菜单,跳过绑定"
|
||
fi
|
||
|
||
# 5) Create a user and bind the role
|
||
USER_NAME="alice_${TS}"
|
||
USER_PASS="Password@123"
|
||
USER_JSON=$(printf '{"username":"%s","password":"%s","nickname":"Alice","status":1}' "$USER_NAME" "$USER_PASS" | curl -s -X POST "$API/users" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
USER_ID=$(echo "$USER_JSON" | extract_id); if [ -z "$USER_ID" ]; then echo "[ERROR] 创建用户失败: $USER_JSON"; exit 1; fi
|
||
|
||
echo "[OK] 创建用户成功: $USER_NAME (id=$USER_ID)"
|
||
|
||
BIND_ROLE_JSON=$(printf '{"ids":[%s]}' "$ROLE_ID" | curl -s -X PUT "$API/users/$USER_ID/roles" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
echo "$BIND_ROLE_JSON" | grep -q '"code":0' || { echo "[ERROR] 绑定用户角色失败: $BIND_ROLE_JSON"; exit 1; }
|
||
|
||
echo "[OK] 绑定用户角色成功"
|
||
|
||
# 5b) Bind demo role to admin and verify menus
|
||
ADMIN_JSON=$(curl -s -X GET "$API/users?page=1&page_size=50&keyword=admin" -H "$H_AUTH")
|
||
ADMIN_ID=$(echo "$ADMIN_JSON" | sed -n -E 's/.*"id":([0-9]+).*"username":"admin".*/\1/p')
|
||
if [ -z "$ADMIN_ID" ]; then
|
||
echo "[WARN] 未找到 admin 用户ID"
|
||
else
|
||
BIND_ADMIN_JSON=$(printf '{"ids":[%s]}' "$ROLE_ID" | curl -s -X PUT "$API/users/$ADMIN_ID/roles" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
echo "$BIND_ADMIN_JSON" | grep -q '"code":0' && echo "[OK] 已为 admin 绑定演示角色(id=$ROLE_ID)" || echo "[WARN] 为 admin 绑定角色可能失败: $BIND_ADMIN_JSON"
|
||
MENUS_ADMIN=$(curl -s -X GET "$API/auth/menus" -H "$H_AUTH")
|
||
echo "[RESULT] Admin 可见菜单响应: $MENUS_ADMIN"
|
||
fi
|
||
|
||
# 6) Login as new user and fetch menus
|
||
LOGIN2_JSON=$(printf '{"username":"%s","password":"%s"}' "$USER_NAME" "$USER_PASS" | curl -s -X POST "$API/auth/login" -H "Content-Type: application/json" --data-binary @-)
|
||
TOKEN2=$(echo "$LOGIN2_JSON" | sed -n -E 's/.*"access_token":"([^\"]*)".*/\1/p')
|
||
if [ -z "$TOKEN2" ]; then echo "[ERROR] 新用户登录失败: $LOGIN2_JSON"; exit 1; fi
|
||
|
||
MENUS2=$(curl -s -X GET "$API/auth/menus" -H "Authorization: Bearer $TOKEN2")
|
||
echo "[RESULT] 新用户可见菜单响应: $MENUS2"
|
||
|
||
# 7) Check permissions and seed defaults if empty
|
||
PERMS_LIST=$(curl -s -X GET "$API/permissions?page=1&page_size=100" -H "$H_AUTH") || true
|
||
PERMS_TOTAL=$(echo "$PERMS_LIST" | sed -n -E 's/.*"total":([0-9]+).*/\1/p') || true
|
||
[ -z "${PERMS_TOTAL:-}" ] && PERMS_TOTAL=0
|
||
|
||
echo "[RESULT] 当前权限总数: $PERMS_TOTAL"
|
||
if [ "$PERMS_TOTAL" = "0" ]; then
|
||
echo "[INFO] 权限为空,开始初始化默认权限"
|
||
curl -s -X POST "$API/permissions" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary '{"code":"users:view","name":"用户查看","description":"查看用户"}' >/dev/null || true
|
||
curl -s -X POST "$API/permissions" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary '{"code":"users:edit","name":"用户编辑","description":"编辑用户"}' >/dev/null || true
|
||
curl -s -X POST "$API/permissions" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary '{"code":"roles:view","name":"角色查看","description":"查看角色"}' >/dev/null || true
|
||
curl -s -X POST "$API/permissions" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary '{"code":"roles:edit","name":"角色编辑","description":"编辑角色"}' >/dev/null || true
|
||
curl -s -X POST "$API/permissions" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary '{"code":"menus:view","name":"菜单查看","description":"查看菜单"}' >/dev/null || true
|
||
curl -s -X POST "$API/permissions" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary '{"code":"menus:edit","name":"菜单编辑","description":"编辑菜单"}' >/dev/null || true
|
||
curl -s -X POST "$API/permissions" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary '{"code":"permissions:view","name":"权限查看","description":"查看权限"}' >/dev/null || true
|
||
curl -s -X POST "$API/permissions" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary '{"code":"permissions:edit","name":"权限编辑","description":"编辑权限"}' >/dev/null || true
|
||
curl -s -X POST "$API/permissions" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary '{"code":"departments:view","name":"部门查看","description":"查看部门"}' >/dev/null || true
|
||
curl -s -X POST "$API/permissions" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary '{"code":"departments:edit","name":"部门编辑","description":"编辑部门"}' >/dev/null || true
|
||
|
||
PERMS_LIST=$(curl -s -X GET "$API/permissions?page=1&page_size=100" -H "$H_AUTH") || true
|
||
PERMS_TOTAL=$(echo "$PERMS_LIST" | sed -n -E 's/.*"total":([0-9]+).*/\1/p') || true
|
||
[ -z "${PERMS_TOTAL:-}" ] && PERMS_TOTAL=0
|
||
echo "[RESULT] 初始化后权限总数: $PERMS_TOTAL"
|
||
fi
|
||
|
||
echo "[SUMMARY] DEMO_ROOT=${DEMO_ROOT_ID:-} USERS=${USERS_ID:-} ROLES=${ROLES_ID:-} MENUS=${MENUS_ID:-} PERMS=${PERMS_ID:-} ROLE=$ROLE_ID USER=$USER_ID USERNAME=$USER_NAME"
|
||
|
||
# 8) Seed formal "系统管理" menus and Super Admin role
|
||
# 获取或创建 系统管理 根菜单:查找时不依赖字段顺序
|
||
MENUS_JSON=$(curl -s -X GET "$API/menus" -H "$H_AUTH")
|
||
SYS_ROOT_ID=$(echo "$MENUS_JSON" | python3 - <<'PY'
|
||
import json,sys
|
||
try:
|
||
data=json.load(sys.stdin)
|
||
menus=data.get("data", [])
|
||
except Exception:
|
||
menus=[]
|
||
for m in menus:
|
||
if m.get("name")=="系统管理" and m.get("type")==1 and m.get("parent_id") is None:
|
||
print(m.get("id"), end="")
|
||
break
|
||
PY
|
||
)
|
||
if [ -z "${SYS_ROOT_ID:-}" ]; then
|
||
SYS_ROOT_JSON=$(printf '{"name":"系统管理","type":1,"icon":"SettingOutlined","order_no":10,"visible":true,"status":1}' | curl -s -X POST "$API/menus" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
SYS_ROOT_ID=$(echo "$SYS_ROOT_JSON" | extract_id)
|
||
fi
|
||
if [ -z "${SYS_ROOT_ID:-}" ]; then echo "[ERROR] 创建/获取 系统管理 根菜单失败"; exit 1; fi
|
||
|
||
# helper to create child menu under 系统管理
|
||
create_menu_under_sys(){
|
||
local name="$1"; local path="$2"; local component="$3"; local icon="$4"; local order_no="$5"
|
||
local id
|
||
id=$(get_menu_id_by_parent_and_path "$SYS_ROOT_ID" "$path") || true
|
||
if [ -z "$id" ]; then id=$(get_menu_id_by_parent_and_name "$SYS_ROOT_ID" "$name") || true; fi
|
||
if [ -n "$id" ]; then echo "$id"; return 0; fi
|
||
id=$(create_or_get_menu "$SYS_ROOT_ID" "$name" 1 "$path" "$component" "$icon" "$order_no")
|
||
echo "$id"
|
||
}
|
||
|
||
USERS2_ID=$(create_menu_under_sys "用户管理" "/users" "Users" "UserOutlined" 20); [ -z "$USERS2_ID" ] && echo "[WARN] 用户管理 菜单ID获取失败"
|
||
ROLES2_ID=$(create_menu_under_sys "角色管理" "/roles" "Roles" "TeamOutlined" 30); [ -z "$ROLES2_ID" ] && echo "[WARN] 角色管理 菜单ID获取失败"
|
||
MENUS2_ID=$(create_menu_under_sys "菜单管理" "/menus" "Menus" "AppstoreOutlined" 40); [ -z "$MENUS2_ID" ] && echo "[WARN] 菜单管理 菜单ID获取失败"
|
||
PERMS2_ID=$(create_menu_under_sys "权限管理" "/permissions" "Permissions" "KeyOutlined" 50); [ -z "$PERMS2_ID" ] && echo "[WARN] 权限管理 菜单ID获取失败"
|
||
DEPTS2_ID=$(create_menu_under_sys "部门管理" "/departments" "Departments" "AppstoreOutlined" 60); [ -z "$DEPTS2_ID" ] && echo "[WARN] 部门管理 菜单ID获取失败"
|
||
POSITIONS2_ID=$(create_menu_under_sys "岗位管理" "/positions" "Positions" "IdcardOutlined" 65); [ -z "$POSITIONS2_ID" ] && echo "[WARN] 岗位管理 菜单ID获取失败"
|
||
|
||
echo "[OK] 正式系统菜单准备完成: ROOT=$SYS_ROOT_ID USERS=$USERS2_ID ROLES=$ROLES2_ID MENUS=$MENUS2_ID PERMS=$PERMS2_ID DEPTS=$DEPTS2_ID POSITIONS=$POSITIONS2_ID"
|
||
|
||
# 工具函数:根据 parent_id + perms 查找或创建按钮菜单(使用 Python 解析)
|
||
create_or_get_button(){
|
||
local parent_id="$1"; local name="$2"; local perms="$3"; local order_no="${4:-0}"
|
||
local id MENUS
|
||
MENUS=$(curl -s -X GET "$API/menus" -H "$H_AUTH")
|
||
id=$(echo "$MENUS" | PERM="$perms" PID="$parent_id" python3 - <<'PY'
|
||
import json,sys,os
|
||
try:
|
||
data=json.load(sys.stdin)
|
||
menus=data.get("data", [])
|
||
except Exception:
|
||
menus=[]
|
||
PERM=os.environ.get("PERM")
|
||
PID=os.environ.get("PID")
|
||
pid_int=None
|
||
try:
|
||
pid_int=int(PID)
|
||
except Exception:
|
||
pass
|
||
for m in menus:
|
||
if m.get("type")==3 and m.get("perms")==PERM and m.get("parent_id")==pid_int:
|
||
print(m.get("id"), end="")
|
||
break
|
||
PY
|
||
) || true
|
||
if [ -n "$id" ]; then echo "$id"; return 0; fi
|
||
local resp; resp=$(printf '{"parent_id":%s,"name":"%s","type":3,"order_no":%s,"visible":false,"status":1,"keep_alive":false,"perms":"%s"}' \
|
||
"$parent_id" "$name" "${order_no:-0}" "$perms" | curl -s -X POST "$API/menus" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
id=$(echo "$resp" | extract_id)
|
||
echo "$id"
|
||
}
|
||
|
||
# 为系统管理下添加按钮权限(幂等)
|
||
[ -n "${USERS2_ID:-}" ] && {
|
||
create_or_get_button "$USERS2_ID" "新增" "system:user:create" 10 >/dev/null || true
|
||
create_or_get_button "$USERS2_ID" "编辑" "system:user:update" 20 >/dev/null || true
|
||
create_or_get_button "$USERS2_ID" "重置密码" "system:user:reset" 30 >/dev/null || true
|
||
create_or_get_button "$USERS2_ID" "删除" "system:user:delete" 40 >/dev/null || true
|
||
create_or_get_button "$USERS2_ID" "分配岗位" "system:user:assignPosition" 50 >/dev/null || true
|
||
}
|
||
[ -n "${ROLES2_ID:-}" ] && {
|
||
create_or_get_button "$ROLES2_ID" "新增" "system:role:create" 10 >/dev/null || true
|
||
create_or_get_button "$ROLES2_ID" "编辑" "system:role:update" 20 >/dev/null || true
|
||
create_or_get_button "$ROLES2_ID" "分配菜单" "system:role:assign" 30 >/dev/null || true
|
||
create_or_get_button "$ROLES2_ID" "删除" "system:role:delete" 40 >/dev/null || true
|
||
}
|
||
[ -n "${MENUS2_ID:-}" ] && {
|
||
create_or_get_button "$MENUS2_ID" "新增" "system:menu:create" 10 >/dev/null || true
|
||
create_or_get_button "$MENUS2_ID" "编辑" "system:menu:update" 20 >/dev/null || true
|
||
create_or_get_button "$MENUS2_ID" "删除" "system:menu:delete" 30 >/dev/null || true
|
||
}
|
||
[ -n "${POSITIONS2_ID:-}" ] && {
|
||
create_or_get_button "$POSITIONS2_ID" "新增" "system:position:create" 10 >/dev/null || true
|
||
create_or_get_button "$POSITIONS2_ID" "编辑" "system:position:update" 20 >/dev/null || true
|
||
create_or_get_button "$POSITIONS2_ID" "删除" "system:position:delete" 30 >/dev/null || true
|
||
}
|
||
|
||
# 9) Create Super Admin role if not exists (code=super_admin)
|
||
SUPER_JSON=$(curl -s -X GET "$API/roles?page=1&page_size=100&keyword=super_admin" -H "$H_AUTH")
|
||
SUPER_ROLE_ID=$(echo "$SUPER_JSON" | sed -n -E 's/.*"id":([0-9]+).*"code":"super_admin".*/\1/p')
|
||
if [ -z "${SUPER_ROLE_ID:-}" ]; then
|
||
SUPER_CREATE_JSON=$(printf '{"name":"超级管理员","code":"super_admin","status":1}' | curl -s -X POST "$API/roles" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
SUPER_ROLE_ID=$(echo "$SUPER_CREATE_JSON" | extract_id)
|
||
fi
|
||
if [ -z "${SUPER_ROLE_ID:-}" ]; then echo "[ERROR] 创建/获取 超级管理员 角色失败"; exit 1; fi
|
||
|
||
echo "[OK] 超级管理员 角色ID=$SUPER_ROLE_ID"
|
||
|
||
# 10) Bind ALL menus to Super Admin (幂等)
|
||
ALL_MENU_IDS=$(curl -s -X GET "$API/menus" -H "$H_AUTH" | python3 - <<'PY'
|
||
import json,sys
|
||
try:
|
||
data=json.load(sys.stdin)
|
||
menus=data.get("data", [])
|
||
except Exception:
|
||
menus=[]
|
||
ids=[str(m.get("id")) for m in menus if isinstance(m.get("id"), int)]
|
||
print(",".join(ids), end="")
|
||
PY
|
||
)
|
||
BIND_SUPER_JSON=$(printf '{"ids":[%s]}' "$ALL_MENU_IDS" | curl -s -X PUT "$API/roles/$SUPER_ROLE_ID/menus" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
echo "$BIND_SUPER_JSON" | grep -q '"code":0' || { echo "[ERROR] 绑定全部菜单到 超级管理员 失败: $BIND_SUPER_JSON"; exit 1; }
|
||
|
||
echo "[OK] 已将全部菜单绑定到 超级管理员 角色"
|
||
|
||
# 11) Assign Super Admin role to admin (保留演示角色)
|
||
if [ -z "${ADMIN_ID:-}" ]; then
|
||
ADMIN_JSON=$(curl -s -X GET "$API/users?page=1&page_size=50&keyword=admin" -H "$H_AUTH")
|
||
ADMIN_ID=$(echo "$ADMIN_JSON" | sed -n -E 's/.*"id":([0-9]+).*"username":"admin".*/\1/p')
|
||
fi
|
||
if [ -n "${ADMIN_ID:-}" ]; then
|
||
CUR_ROLES_JSON=$(curl -s -X GET "$API/users/$ADMIN_ID/roles" -H "$H_AUTH")
|
||
NEW_ROLE_IDS=$(echo "$CUR_ROLES_JSON" | SUPER_ROLE_ID="$SUPER_ROLE_ID" python3 -c 'import json,sys,os
|
||
|
||
try:
|
||
data=json.load(sys.stdin)
|
||
except Exception:
|
||
data={}
|
||
ids=[]
|
||
for it in data.get("data", []):
|
||
try:
|
||
i=int(it.get("id"))
|
||
s=str(i)
|
||
if s not in ids:
|
||
ids.append(s)
|
||
except Exception:
|
||
pass
|
||
sid=os.environ.get("SUPER_ROLE_ID")
|
||
if sid and sid not in ids:
|
||
ids.append(sid)
|
||
print("".join([",".join(ids)]), end="")')
|
||
if [ -z "$NEW_ROLE_IDS" ]; then NEW_ROLE_IDS="$SUPER_ROLE_ID"; fi
|
||
ASSIGN_ADMIN_JSON=$(printf '{"ids":[%s]}' "$NEW_ROLE_IDS" | curl -s -X PUT "$API/users/$ADMIN_ID/roles" -H "$H_AUTH" -H "Content-Type: application/json" --data-binary @-)
|
||
echo "$ASSIGN_ADMIN_JSON" | grep -q '"code":0' && echo "[OK] 已为 admin 分配 超级管理员 角色(id=$SUPER_ROLE_ID) 合并现有角色: [$NEW_ROLE_IDS]" || echo "[WARN] 为 admin 分配 超级管理员 可能失败: $ASSIGN_ADMIN_JSON"
|
||
MENUS_ADMIN2=$(curl -s -X GET "$API/auth/menus" -H "$H_AUTH")
|
||
echo "[RESULT] Admin 可见菜单(包含正式菜单): $MENUS_ADMIN2"
|
||
else
|
||
echo "[WARN] 未能获取 admin 用户ID,跳过角色分配"
|
||
fi
|
||
|
||
echo "[SUMMARY] DEMO_ROOT=${DEMO_ROOT_ID:-} USERS=${USERS_ID:-} ROLES=${ROLES_ID:-} MENUS=${MENUS_ID:-} PERMS=${PERMS_ID:-}" |