diff --git a/model/ability.go b/model/ability.go index a3e0af4..7911920 100644 --- a/model/ability.go +++ b/model/ability.go @@ -59,6 +59,13 @@ func GetAllEnableAbilities() []Ability { return abilities } +// GetAbilitiesByChannelId 获取指定渠道的所有能力 +func GetAbilitiesByChannelId(channelId int) ([]*Ability, error) { + var abilities []*Ability + err := DB.Where("channel_id = ?", channelId).Find(&abilities).Error + return abilities, err +} + func getPriority(group string, model string, retry int) (int, error) { var priorities []int diff --git a/test_channel_pricing.sh b/test_channel_pricing.sh new file mode 100644 index 0000000..0bf80ee --- /dev/null +++ b/test_channel_pricing.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +# 渠道定价功能端到端测试脚本 +# 使用方法: ./test_channel_pricing.sh + +BASE_URL="http://localhost:3000" +ADMIN_TOKEN="${1:-}" + +if [ -z "$ADMIN_TOKEN" ]; then + echo "错误: 请提供管理员 token" + echo "使用方法: ./test_channel_pricing.sh " + exit 1 +fi + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +pass_count=0 +fail_count=0 + +check_success() { + local result="$1" + local test_name="$2" + if echo "$result" | grep -q '"success":true'; then + echo -e "${GREEN}✓ $test_name${NC}" + ((pass_count++)) + return 0 + else + echo -e "${RED}✗ $test_name${NC}" + echo " 响应: $result" + ((fail_count++)) + return 1 + fi +} + +check_failure() { + local result="$1" + local test_name="$2" + if echo "$result" | grep -q '"success":false'; then + echo -e "${GREEN}✓ $test_name (预期失败)${NC}" + ((pass_count++)) + return 0 + else + echo -e "${RED}✗ $test_name (应该失败但成功了)${NC}" + ((fail_count++)) + return 1 + fi +} + +echo "======================================" +echo " 渠道定价功能端到端测试" +echo "======================================" +echo "" + +# ========== 模块 1: 定价标签 ========== +echo -e "${YELLOW}【模块 1: 定价标签 API】${NC}" + +echo "" +echo "TC-1.1 创建定价标签..." +RESULT=$(curl -s -X POST "$BASE_URL/api/pricing_tag/" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"name":"E2E测试标签","color":"#52c41a","description":"端到端测试","sort_order":1}') +check_success "$RESULT" "创建定价标签" +TAG_ID=$(echo "$RESULT" | grep -o '"id":[0-9]*' | head -1 | grep -o '[0-9]*') + +echo "" +echo "TC-1.2 获取所有标签..." +RESULT=$(curl -s "$BASE_URL/api/pricing_tag/" -H "Authorization: Bearer $ADMIN_TOKEN") +check_success "$RESULT" "获取所有标签" + +echo "" +echo "TC-1.3 创建重复名称标签 (应失败)..." +RESULT=$(curl -s -X POST "$BASE_URL/api/pricing_tag/" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"name":"E2E测试标签","color":"#ff0000"}') +check_failure "$RESULT" "创建重复名称标签" + +if [ -n "$TAG_ID" ]; then + echo "" + echo "TC-1.4 更新标签..." + RESULT=$(curl -s -X PUT "$BASE_URL/api/pricing_tag/$TAG_ID" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"name":"E2E测试标签-更新","color":"#1890ff","description":"更新后"}') + check_success "$RESULT" "更新标签" +fi + +# ========== 模块 2: 渠道定价 ========== +echo "" +echo -e "${YELLOW}【模块 2: 渠道定价 API】${NC}" + +echo "" +echo "TC-2.1 创建渠道定价 (按量计费)..." +RESULT=$(curl -s -X POST "$BASE_URL/api/channel_pricing/" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"model_name":"e2e-test-model","channel_id":1,"quota_type":0,"model_ratio":10,"completion_ratio":1.5,"model_price":0}') +check_success "$RESULT" "创建渠道定价(按量)" +PRICING_ID=$(echo "$RESULT" | grep -o '"id":[0-9]*' | head -1 | grep -o '[0-9]*') + +echo "" +echo "TC-2.2 创建渠道定价 (按次计费)..." +RESULT=$(curl -s -X POST "$BASE_URL/api/channel_pricing/" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"model_name":"e2e-test-model-call","channel_id":1,"quota_type":1,"model_ratio":0,"completion_ratio":0,"model_price":0.05}') +check_success "$RESULT" "创建渠道定价(按次)" + +echo "" +echo "TC-2.3 获取所有渠道定价..." +RESULT=$(curl -s "$BASE_URL/api/channel_pricing/?p=1&page_size=10" -H "Authorization: Bearer $ADMIN_TOKEN") +check_success "$RESULT" "获取所有渠道定价" + +echo "" +echo "TC-2.4 获取指定模型的渠道定价..." +RESULT=$(curl -s "$BASE_URL/api/channel_pricing/model/e2e-test-model" -H "Authorization: Bearer $ADMIN_TOKEN") +check_success "$RESULT" "获取指定模型的渠道定价" + +echo "" +echo "TC-2.5 获取带标签的渠道定价..." +RESULT=$(curl -s "$BASE_URL/api/channel_pricing/with_tags?p=1&page_size=10" -H "Authorization: Bearer $ADMIN_TOKEN") +check_success "$RESULT" "获取带标签的渠道定价" + +echo "" +echo "TC-2.6 批量创建渠道定价..." +RESULT=$(curl -s -X POST "$BASE_URL/api/channel_pricing/batch" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"items":[{"model_name":"batch-model-1","channel_id":1,"quota_type":0,"model_ratio":5},{"model_name":"batch-model-2","channel_id":1,"quota_type":0,"model_ratio":8}]}') +check_success "$RESULT" "批量创建渠道定价" + +# ========== 模块 3: 清理测试数据 ========== +echo "" +echo -e "${YELLOW}【清理测试数据】${NC}" + +if [ -n "$TAG_ID" ]; then + echo "" + echo "删除测试标签..." + RESULT=$(curl -s -X DELETE "$BASE_URL/api/pricing_tag/$TAG_ID" -H "Authorization: Bearer $ADMIN_TOKEN") + check_success "$RESULT" "删除测试标签" +fi + +if [ -n "$PRICING_ID" ]; then + echo "" + echo "删除测试渠道定价..." + RESULT=$(curl -s -X DELETE "$BASE_URL/api/channel_pricing/$PRICING_ID" -H "Authorization: Bearer $ADMIN_TOKEN") + check_success "$RESULT" "删除测试渠道定价" +fi + +# 删除其他测试数据 +echo "" +echo "清理批量创建的测试数据..." +for model in "batch-model-1" "batch-model-2" "e2e-test-model-call"; do + RESULT=$(curl -s "$BASE_URL/api/channel_pricing/model/$model" -H "Authorization: Bearer $ADMIN_TOKEN") + IDS=$(echo "$RESULT" | grep -o '"id":[0-9]*' | grep -o '[0-9]*') + for id in $IDS; do + curl -s -X DELETE "$BASE_URL/api/channel_pricing/$id" -H "Authorization: Bearer $ADMIN_TOKEN" > /dev/null + done +done +echo -e "${GREEN}✓ 清理完成${NC}" + +# ========== 测试总结 ========== +echo "" +echo "======================================" +echo " 测试结果汇总" +echo "======================================" +echo -e "通过: ${GREEN}$pass_count${NC}" +echo -e "失败: ${RED}$fail_count${NC}" +echo "" + +if [ $fail_count -eq 0 ]; then + echo -e "${GREEN}所有测试通过! ✓${NC}" + exit 0 +else + echo -e "${RED}有 $fail_count 个测试失败${NC}" + exit 1 +fi diff --git a/web/src/components/settings/RatioSetting.jsx b/web/src/components/settings/RatioSetting.jsx index 078dbb9..24668ec 100644 --- a/web/src/components/settings/RatioSetting.jsx +++ b/web/src/components/settings/RatioSetting.jsx @@ -19,7 +19,7 @@ For commercial licensing, please contact support@quantumnous.com import React, { useEffect, useState } from 'react'; import { Card, Spin, Tabs } from '@douyinfe/semi-ui'; -import { Tag } from '@douyinfe/semi-icons'; +import { IconPriceTag } from '@douyinfe/semi-icons'; import { useTranslation } from 'react-i18next'; import GroupRatioSettings from '../../pages/Setting/Ratio/GroupRatioSettings'; @@ -118,7 +118,7 @@ const RatioSetting = () => { - + {t('标签管理')} }