fix(task12): 修复前端登录租户编码透传、补充 tenant_admin 角色迁移与外部 API 测试脚本
- admin-web/api/client.ts: 请求拦截器仅在未显式传入 X-Tenant-Code 时使用 localStorage 默认值 - admin-web/api/account.ts: login 显式携带租户编码请求头,解决浏览器登录 401 - db/migration/V10: 新增 tenant_admin 平台角色,供外部 API 测试创建租户管理员 - scripts/test-external-api.sh: 创建租户后自动创建管理员并登录,后续接口使用 Bearer Token - docs/superpowers/plans: 提交总体规划与 Task 12 测试计划
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
import client from './client'
|
import client from './client'
|
||||||
|
|
||||||
export function login(data: { tenantCode: string; username: string; password: string }) {
|
export function login(data: { tenantCode: string; username: string; password: string }) {
|
||||||
return client.post('/api/v1/account/login', data)
|
return client.post('/api/v1/account/login', data, {
|
||||||
|
headers: { 'X-Tenant-Code': data.tenantCode },
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createTenant(data: { tenantCode: string; tenantName: string }) {
|
export function createTenant(data: { tenantCode: string; tenantName: string }) {
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ client.interceptors.request.use((config) => {
|
|||||||
if (token) {
|
if (token) {
|
||||||
config.headers.Authorization = `Bearer ${token}`
|
config.headers.Authorization = `Bearer ${token}`
|
||||||
}
|
}
|
||||||
|
if (!config.headers['X-Tenant-Code']) {
|
||||||
const tenantCode = localStorage.getItem('mci-tenant-code') || 'default'
|
const tenantCode = localStorage.getItem('mci-tenant-code') || 'default'
|
||||||
config.headers['X-Tenant-Code'] = tenantCode
|
config.headers['X-Tenant-Code'] = tenantCode
|
||||||
|
}
|
||||||
return config
|
return config
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
INSERT IGNORE INTO mci_platform_role (role_code, role_name, permissions) VALUES
|
||||||
|
('tenant_admin', '租户管理员', '["*"]');
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -55,60 +55,74 @@ TENANT_RESPONSE=$(make_request POST "$BASE_URL/api/v1/account/tenant" \
|
|||||||
'{"tenantCode":"'"$TENANT_CODE"'","tenantName":"External API Test"}')
|
'{"tenantCode":"'"$TENANT_CODE"'","tenantName":"External API Test"}')
|
||||||
assert_code_zero "Create tenant" "$TENANT_RESPONSE"
|
assert_code_zero "Create tenant" "$TENANT_RESPONSE"
|
||||||
|
|
||||||
# 2. Create channel subject
|
# 2. Create admin user and login
|
||||||
echo "==> 2. Create channel subject"
|
echo "==> 2. Create admin user and login"
|
||||||
|
USER_RESPONSE=$(make_request POST "$BASE_URL/api/v1/account/user" \
|
||||||
|
'{"username":"admin","password":"admin123","realName":"Admin","roleCodes":["tenant_admin"]}' \
|
||||||
|
-H "X-Tenant-Code: $TENANT_CODE")
|
||||||
|
assert_code_zero "Create admin user" "$USER_RESPONSE"
|
||||||
|
|
||||||
|
LOGIN_RESPONSE=$(make_request POST "$BASE_URL/api/v1/account/login" \
|
||||||
|
'{"username":"admin","password":"admin123"}' \
|
||||||
|
-H "X-Tenant-Code: $TENANT_CODE")
|
||||||
|
assert_code_zero "Login" "$LOGIN_RESPONSE"
|
||||||
|
TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.data.token')
|
||||||
|
AUTH_HEADER="Authorization: Bearer $TOKEN"
|
||||||
|
|
||||||
|
# 3. Create channel subject
|
||||||
|
echo "==> 3. Create channel subject"
|
||||||
SUBJECT_RESPONSE=$(make_request POST "$BASE_URL/api/v1/channel-subject" \
|
SUBJECT_RESPONSE=$(make_request POST "$BASE_URL/api/v1/channel-subject" \
|
||||||
'{"channelType":"wecom","subjectCode":"sino","subjectName":"Sino Test"}' \
|
'{"channelType":"wecom","subjectCode":"sino","subjectName":"Sino Test"}' \
|
||||||
-H "X-Tenant-Code: $TENANT_CODE")
|
-H "$AUTH_HEADER" -H "X-Tenant-Code: $TENANT_CODE")
|
||||||
assert_code_zero "Create channel subject" "$SUBJECT_RESPONSE"
|
assert_code_zero "Create channel subject" "$SUBJECT_RESPONSE"
|
||||||
|
|
||||||
# 3. Create channel account
|
# 4. Create channel account
|
||||||
echo "==> 3. Create channel account"
|
echo "==> 4. Create channel account"
|
||||||
ACCOUNT_RESPONSE=$(make_request POST "$BASE_URL/api/v1/channel-account" \
|
ACCOUNT_RESPONSE=$(make_request POST "$BASE_URL/api/v1/channel-account" \
|
||||||
'{"accountType":1,"channelType":"wecom","accountId":"ZhangSan","accountName":"张三"}' \
|
'{"accountType":1,"channelType":"wecom","accountId":"ZhangSan","accountName":"张三"}' \
|
||||||
-H "X-Tenant-Code: $TENANT_CODE")
|
-H "$AUTH_HEADER" -H "X-Tenant-Code: $TENANT_CODE")
|
||||||
assert_code_zero "Create channel account" "$ACCOUNT_RESPONSE"
|
assert_code_zero "Create channel account" "$ACCOUNT_RESPONSE"
|
||||||
ACCOUNT_ID=$(echo "$ACCOUNT_RESPONSE" | jq -r '.data.id')
|
ACCOUNT_ID=$(echo "$ACCOUNT_RESPONSE" | jq -r '.data.id')
|
||||||
|
|
||||||
# 4. Create conversation
|
# 5. Create conversation
|
||||||
echo "==> 4. Create conversation"
|
echo "==> 5. Create conversation"
|
||||||
CONVERSATION_RESPONSE=$(make_request POST "$BASE_URL/api/v1/conversation" \
|
CONVERSATION_RESPONSE=$(make_request POST "$BASE_URL/api/v1/conversation" \
|
||||||
'{"conversationType":2,"channelType":"wecom","channelConversationId":"room-test-'"$(date +%s)"'","conversationName":"Test Group"}' \
|
'{"conversationType":2,"channelType":"wecom","channelConversationId":"room-test-'"$(date +%s)"'","conversationName":"Test Group"}' \
|
||||||
-H "X-Tenant-Code: $TENANT_CODE")
|
-H "$AUTH_HEADER" -H "X-Tenant-Code: $TENANT_CODE")
|
||||||
assert_code_zero "Create conversation" "$CONVERSATION_RESPONSE"
|
assert_code_zero "Create conversation" "$CONVERSATION_RESPONSE"
|
||||||
CONVERSATION_ID=$(echo "$CONVERSATION_RESPONSE" | jq -r '.data.id')
|
CONVERSATION_ID=$(echo "$CONVERSATION_RESPONSE" | jq -r '.data.id')
|
||||||
|
|
||||||
# 5. Bind account to conversation
|
# 6. Bind account to conversation
|
||||||
echo "==> 5. Bind account to conversation"
|
echo "==> 6. Bind account to conversation"
|
||||||
BIND_RESPONSE=$(make_request POST "$BASE_URL/api/v1/conversation/$CONVERSATION_ID/bind-account" \
|
BIND_RESPONSE=$(make_request POST "$BASE_URL/api/v1/conversation/$CONVERSATION_ID/bind-account" \
|
||||||
"{\"accountId\":$ACCOUNT_ID,\"bindingType\":1,\"sortOrder\":1}" \
|
"{\"accountId\":$ACCOUNT_ID,\"bindingType\":1,\"sortOrder\":1}" \
|
||||||
-H "X-Tenant-Code: $TENANT_CODE")
|
-H "$AUTH_HEADER" -H "X-Tenant-Code: $TENANT_CODE")
|
||||||
assert_code_zero "Bind account to conversation" "$BIND_RESPONSE"
|
assert_code_zero "Bind account to conversation" "$BIND_RESPONSE"
|
||||||
|
|
||||||
# 6. Test send
|
# 7. Test send
|
||||||
echo "==> 6. Test send"
|
echo "==> 7. Test send"
|
||||||
SEND_RESPONSE=$(make_request POST "$BASE_URL/api/v1/send/test" \
|
SEND_RESPONSE=$(make_request POST "$BASE_URL/api/v1/send/test" \
|
||||||
"{\"targetType\":\"conversation\",\"targetValue\":{\"conversation_id\":$CONVERSATION_ID},\"contentType\":\"text\",\"content\":{\"text\":\"hello from external api test\"},\"channelStrategy\":{\"channel_type\":\"wecom\",\"strategy\":\"primary\"}}" \
|
"{\"targetType\":\"conversation\",\"targetValue\":{\"conversation_id\":$CONVERSATION_ID},\"contentType\":\"text\",\"content\":{\"text\":\"hello from external api test\"},\"channelStrategy\":{\"channel_type\":\"wecom\",\"strategy\":\"primary\"}}" \
|
||||||
-H "X-Tenant-Code: $TENANT_CODE")
|
-H "$AUTH_HEADER" -H "X-Tenant-Code: $TENANT_CODE")
|
||||||
assert_code_zero "Test send" "$SEND_RESPONSE"
|
assert_code_zero "Test send" "$SEND_RESPONSE"
|
||||||
TASK_ID=$(echo "$SEND_RESPONSE" | jq -r '.data.taskId')
|
TASK_ID=$(echo "$SEND_RESPONSE" | jq -r '.data.taskId')
|
||||||
|
|
||||||
# 7. Query send records
|
# 8. Query send records
|
||||||
echo "==> 7. Query send records"
|
echo "==> 8. Query send records"
|
||||||
RECORDS_RESPONSE=$(make_request GET "$BASE_URL/api/v1/send/$TASK_ID/records" "" \
|
RECORDS_RESPONSE=$(make_request GET "$BASE_URL/api/v1/send/$TASK_ID/records" "" \
|
||||||
-H "X-Tenant-Code: $TENANT_CODE")
|
-H "$AUTH_HEADER" -H "X-Tenant-Code: $TENANT_CODE")
|
||||||
assert_code_zero "Query send records" "$RECORDS_RESPONSE"
|
assert_code_zero "Query send records" "$RECORDS_RESPONSE"
|
||||||
|
|
||||||
# 8. Receive inbound message
|
# 9. Receive inbound message
|
||||||
echo "==> 8. Receive inbound message"
|
echo "==> 9. Receive inbound message"
|
||||||
EVENT_ID="evt-$(date +%s)-$RANDOM"
|
EVENT_ID="evt-$(date +%s)-$RANDOM"
|
||||||
INBOUND_RESPONSE=$(make_request POST "$BASE_URL/api/v1/inbound/receive" \
|
INBOUND_RESPONSE=$(make_request POST "$BASE_URL/api/v1/inbound/receive" \
|
||||||
"{\"eventId\":\"$EVENT_ID\",\"channelType\":\"wecom\",\"channelSubjectId\":1,\"eventType\":\"message\",\"messageSource\":\"realtime\",\"conversationId\":$CONVERSATION_ID,\"accountId\":$ACCOUNT_ID,\"content\":{\"text\":\"hello inbound\"},\"rawPayload\":{},\"businessContext\":{}}" \
|
"{\"eventId\":\"$EVENT_ID\",\"channelType\":\"wecom\",\"channelSubjectId\":1,\"eventType\":\"message\",\"messageSource\":\"realtime\",\"conversationId\":$CONVERSATION_ID,\"accountId\":$ACCOUNT_ID,\"content\":{\"text\":\"hello inbound\"},\"rawPayload\":{},\"businessContext\":{}}" \
|
||||||
-H "X-Tenant-Code: $TENANT_CODE")
|
-H "$AUTH_HEADER" -H "X-Tenant-Code: $TENANT_CODE")
|
||||||
assert_code_zero "Receive inbound message" "$INBOUND_RESPONSE"
|
assert_code_zero "Receive inbound message" "$INBOUND_RESPONSE"
|
||||||
|
|
||||||
# 9. Channel-service health
|
# 10. Channel-service health
|
||||||
echo "==> 9. Channel-service health"
|
echo "==> 10. Channel-service health"
|
||||||
HEALTH_RESPONSE=$(curl -s -S "$CHANNEL_URL/health")
|
HEALTH_RESPONSE=$(curl -s -S "$CHANNEL_URL/health")
|
||||||
if echo "$HEALTH_RESPONSE" | jq -e '.status == "ok"' >/dev/null 2>&1; then
|
if echo "$HEALTH_RESPONSE" | jq -e '.status == "ok"' >/dev/null 2>&1; then
|
||||||
echo "[PASS] Channel-service health"
|
echo "[PASS] Channel-service health"
|
||||||
@@ -119,8 +133,8 @@ else
|
|||||||
FAIL_COUNT=$((FAIL_COUNT + 1))
|
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 10. WeChat personal login start
|
# 11. WeChat personal login start
|
||||||
echo "==> 10. WeChat personal login start"
|
echo "==> 11. WeChat personal login start"
|
||||||
LOGIN_RESPONSE=$(make_request POST "$CHANNEL_URL/v1/wechat-personal/login/start" \
|
LOGIN_RESPONSE=$(make_request POST "$CHANNEL_URL/v1/wechat-personal/login/start" \
|
||||||
'{"account_id":"bot-test-'"$(date +%s)"'","account_name":"Test Bot"}')
|
'{"account_id":"bot-test-'"$(date +%s)"'","account_name":"Test Bot"}')
|
||||||
if echo "$LOGIN_RESPONSE" | jq -e '.login_id' >/dev/null 2>&1; then
|
if echo "$LOGIN_RESPONSE" | jq -e '.login_id' >/dev/null 2>&1; then
|
||||||
@@ -132,8 +146,8 @@ else
|
|||||||
FAIL_COUNT=$((FAIL_COUNT + 1))
|
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 11. WeChat personal send text (after confirming a login)
|
# 12. WeChat personal send text (after confirming a login)
|
||||||
echo "==> 11. WeChat personal send text"
|
echo "==> 12. WeChat personal send text"
|
||||||
BOT_ID="bot-send-$(date +%s)"
|
BOT_ID="bot-send-$(date +%s)"
|
||||||
make_request POST "$CHANNEL_URL/v1/wechat-personal/login/start" \
|
make_request POST "$CHANNEL_URL/v1/wechat-personal/login/start" \
|
||||||
'{"account_id":"'"$BOT_ID"'"}' >/dev/null
|
'{"account_id":"'"$BOT_ID"'"}' >/dev/null
|
||||||
|
|||||||
Reference in New Issue
Block a user