fix: 根据后端API文档v1.2.1更新前端接口

- 修复渠道平台模型授权状态显示逻辑(使用hasAccess字段判断)
- 修复changeTenantPassword接口参数名(new_password -> newPassword)
- 修复createAdmin接口channelId参数改为可选
- 修复渠道申请审批表格的状态显示和按钮逻辑
This commit is contained in:
xiaohei
2026-01-05 06:56:46 +00:00
parent ffb09fee13
commit f43306a7b5
4 changed files with 361 additions and 78 deletions
@@ -1872,7 +1872,7 @@ export function ChannelsTab({
onClick={async () => {
if (!selectedApproval) return
try {
await TaijiAPIClient.reviewApplication(selectedApproval.id, false, language === "zh" ? "申请被拒绝" : "Application rejected")
await TaijiAPIClient.reviewProviderApplication(selectedApproval.id, false, language === "zh" ? "申请被拒绝" : "Application rejected")
await loadDashboardData()
setIsApprovalDialogOpen(false)
} catch (error) {
@@ -1888,7 +1888,7 @@ export function ChannelsTab({
onClick={async () => {
if (!selectedApproval) return
try {
await TaijiAPIClient.reviewApplication(selectedApproval.id, true, language === "zh" ? "申请已批准" : "Application approved")
await TaijiAPIClient.reviewProviderApplication(selectedApproval.id, true, language === "zh" ? "申请已批准" : "Application approved")
await loadDashboardData()
setIsApprovalDialogOpen(false)
} catch (error) {
+181 -65
View File
@@ -179,10 +179,13 @@ export default function AdminDashboard() {
const [selectedApproval, setSelectedApproval] = useState<any>(null)
const [isApprovalDialogOpen, setIsApprovalDialogOpen] = useState(false)
// Agent申请审批相关状态
const [agentApprovals, setAgentApprovals] = useState<any[]>([])
const [selectedAgentApproval, setSelectedAgentApproval] = useState<any>(null)
const [isAgentApprovalDialogOpen, setIsAgentApprovalDialogOpen] = useState(false)
// 平台Agent申请审批相关状态
const [platformAgentApplications, setPlatformAgentApplications] = useState<any[]>([])
const [selectedPlatformAgentApplication, setSelectedPlatformAgentApplication] = useState<any>(null)
const [isPlatformAgentApprovalDialogOpen, setIsPlatformAgentApprovalDialogOpen] = useState(false)
const [approvedPodQuota, setApprovedPodQuota] = useState<string>("")
const [approvalReason, setApprovalReason] = useState<string>("")
// Simplified t function for demonstration
const t = (zh: string, en: string) => (language === "zh" ? zh : en)
@@ -554,11 +557,37 @@ export default function AdminDashboard() {
setChannels(channelsData)
}
// 加载申请列表
const applicationsData = await TaijiAPIClient.getAdminApplications()
if (Array.isArray(applicationsData)) {
setProviderApprovals(applicationsData.filter((app: any) => app.type === "provider"))
setAgentApprovals(applicationsData.filter((app: any) => app.type === "agent"))
// 加载供应商申请列表(使用专用接口)
try {
const providerAppsData = await TaijiAPIClient.getProviderApplications()
if (providerAppsData?.success && providerAppsData.data?.applications) {
setProviderApprovals(providerAppsData.data.applications)
} else if (providerAppsData?.data?.data && Array.isArray(providerAppsData.data.data)) {
// 兼容旧的响应格式
setProviderApprovals(providerAppsData.data.data)
} else if (Array.isArray(providerAppsData?.data)) {
setProviderApprovals(providerAppsData.data)
} else {
setProviderApprovals([])
}
} catch (error) {
console.log("Failed to load provider applications:", error)
setProviderApprovals([])
}
// 加载平台Agent申请列表(新的专用接口)
try {
const platformAgentAppsData = await TaijiAPIClient.getPlatformAgentApplications()
if (platformAgentAppsData?.success && platformAgentAppsData.data?.applications) {
setPlatformAgentApplications(platformAgentAppsData.data.applications)
} else if (Array.isArray(platformAgentAppsData?.data)) {
setPlatformAgentApplications(platformAgentAppsData.data)
} else {
setPlatformAgentApplications([])
}
} catch (error) {
console.log("Failed to load platform agent applications:", error)
setPlatformAgentApplications([])
}
// 加载Agent监控数据
@@ -2636,22 +2665,44 @@ export default function AdminDashboard() {
<td className="p-4">
<Badge
variant="secondary"
className="bg-yellow-500/10 text-yellow-500 border-yellow-500/20"
className={
approval.status === "pending"
? "bg-yellow-500/10 text-yellow-500 border-yellow-500/20"
: approval.status === "approved"
? "bg-green-500/10 text-green-500 border-green-500/20"
: "bg-red-500/10 text-red-500 border-red-500/20"
}
>
{language === "zh" ? "待审批" : "Pending"}
{language === "zh"
? approval.status === "pending"
? "待审批"
: approval.status === "approved"
? "已批准"
: "已拒绝"
: approval.status === "pending"
? "Pending"
: approval.status === "approved"
? "Approved"
: "Rejected"}
</Badge>
</td>
<td className="p-4 text-right">
<Button
size="sm"
variant="outline"
onClick={async () => {
setSelectedApproval(approval)
setIsApprovalDialogOpen(true)
}}
>
{language === "zh" ? "审批" : "Review"}
</Button>
{approval.status === "pending" ? (
<Button
size="sm"
variant="outline"
onClick={async () => {
setSelectedApproval(approval)
setIsApprovalDialogOpen(true)
}}
>
{language === "zh" ? "审批" : "Review"}
</Button>
) : (
<span className="text-sm text-muted-foreground">
{language === "zh" ? "已处理" : "Processed"}
</span>
)}
</td>
</tr>
))
@@ -2662,10 +2713,10 @@ export default function AdminDashboard() {
</Card>
</div>
{/* Agent申请审批 */}
{/* 平台Agent申请审批(新增) */}
<div className="space-y-4">
<h3 className="text-lg font-semibold text-foreground">
{language === "zh" ? "Agent申请审批" : "Agent Application Approvals"}
{language === "zh" ? "平台Agent申请审批" : "Platform Agent Application Approvals"}
</h3>
<Card className="bg-card border-border">
<div className="overflow-x-auto">
@@ -2676,10 +2727,13 @@ export default function AdminDashboard() {
{language === "zh" ? "渠道" : "Channel"}
</th>
<th className="text-left p-4 text-sm font-medium text-muted-foreground">
{language === "zh" ? "Agent类型" : "Agent Type"}
{language === "zh" ? "模板名称" : "Template Name"}
</th>
<th className="text-left p-4 text-sm font-medium text-muted-foreground">
{language === "zh" ? "申请数量" : "Quantity"}
{language === "zh" ? "申请Pod配额" : "Requested Pod Quota"}
</th>
<th className="text-left p-4 text-sm font-medium text-muted-foreground">
{language === "zh" ? "申请理由" : "Reason"}
</th>
<th className="text-left p-4 text-sm font-medium text-muted-foreground">
{language === "zh" ? "提交时间" : "Submitted"}
@@ -2695,42 +2749,63 @@ export default function AdminDashboard() {
<tbody>
{loading ? (
<tr>
<td colSpan={6} className="p-4 text-center text-muted-foreground">
<td colSpan={7} className="p-4 text-center text-muted-foreground">
{language === "zh" ? "加载中..." : "Loading..."}
</td>
</tr>
) : agentApprovals.length === 0 ? (
) : platformAgentApplications.length === 0 ? (
<tr>
<td colSpan={6} className="p-4 text-center text-muted-foreground">
<td colSpan={7} className="p-4 text-center text-muted-foreground">
{language === "zh" ? "暂无待审批申请" : "No pending applications"}
</td>
</tr>
) : (
agentApprovals.map((approval) => (
<tr key={approval.id} className="border-b border-border last:border-0 hover:bg-muted/50">
<td className="p-4 text-sm text-foreground font-medium">{approval.channelName || approval.channelId}</td>
<td className="p-4 text-sm text-foreground">{approval.agentType || approval.details?.agentType || "-"}</td>
<td className="p-4 text-sm text-muted-foreground">{approval.requestedQuantity || approval.details?.quantity || 0}</td>
<td className="p-4 text-sm text-muted-foreground">{approval.submittedAt || approval.createdAt}</td>
platformAgentApplications.map((app) => (
<tr key={app.id} className="border-b border-border last:border-0 hover:bg-muted/50">
<td className="p-4 text-sm text-foreground font-medium">{app.channelName || app.channelId}</td>
<td className="p-4 text-sm text-foreground">{app.templateDisplayName || app.templateName}</td>
<td className="p-4 text-sm text-muted-foreground">{app.requestedPodQuota || 0}</td>
<td className="p-4 text-sm text-muted-foreground max-w-[200px] truncate">{app.reason || "-"}</td>
<td className="p-4 text-sm text-muted-foreground">{app.createdAt}</td>
<td className="p-4">
<Badge
variant="secondary"
className="bg-yellow-500/10 text-yellow-500 border-yellow-500/20"
className={
app.status === "pending"
? "bg-yellow-500/10 text-yellow-500 border-yellow-500/20"
: app.status === "approved"
? "bg-green-500/10 text-green-500 border-green-500/20"
: "bg-red-500/10 text-red-500 border-red-500/20"
}
>
{language === "zh" ? "待审批" : "Pending"}
{language === "zh"
? app.status === "pending"
? "待审批"
: app.status === "approved"
? "已批准"
: "已拒绝"
: app.status === "pending"
? "Pending"
: app.status === "approved"
? "Approved"
: "Rejected"}
</Badge>
</td>
<td className="p-4 text-right">
<Button
size="sm"
variant="outline"
onClick={() => {
setSelectedAgentApproval(approval)
setIsAgentApprovalDialogOpen(true)
}}
>
{language === "zh" ? "审批" : "Review"}
</Button>
{app.status === "pending" && (
<Button
size="sm"
variant="outline"
onClick={() => {
setSelectedPlatformAgentApplication(app)
setApprovedPodQuota(String(app.requestedPodQuota || 0))
setApprovalReason("")
setIsPlatformAgentApprovalDialogOpen(true)
}}
>
{language === "zh" ? "审批" : "Review"}
</Button>
)}
</td>
</tr>
))
@@ -2741,14 +2816,15 @@ export default function AdminDashboard() {
</Card>
</div>
<Dialog open={isAgentApprovalDialogOpen} onOpenChange={setIsAgentApprovalDialogOpen}>
{/* 平台Agent申请审批对话框(新增) */}
<Dialog open={isPlatformAgentApprovalDialogOpen} onOpenChange={setIsPlatformAgentApprovalDialogOpen}>
<DialogContent className="bg-card border-border max-w-2xl">
<DialogHeader>
<DialogTitle>{language === "zh" ? "审批Agent申请" : "Review Agent Application"}</DialogTitle>
<DialogTitle>{language === "zh" ? "审批平台Agent申请" : "Review Platform Agent Application"}</DialogTitle>
<DialogDescription>
{language === "zh"
? `审批渠道 "${selectedAgentApproval?.channelName}" 的Agent申请`
: `Review agent application from channel "${selectedAgentApproval?.channelName}"`}
? `审批渠道 "${selectedPlatformAgentApplication?.channelName || selectedPlatformAgentApplication?.channelId}" 的平台Agent申请`
: `Review platform agent application from channel "${selectedPlatformAgentApplication?.channelName || selectedPlatformAgentApplication?.channelId}"`}
</DialogDescription>
</DialogHeader>
<div className="space-y-4 py-4">
@@ -2757,32 +2833,56 @@ export default function AdminDashboard() {
<label className="text-sm font-medium text-muted-foreground">
{language === "zh" ? "申请渠道" : "Channel"}
</label>
<p className="text-foreground mt-1">{selectedAgentApproval?.channelName}</p>
<p className="text-foreground mt-1">{selectedPlatformAgentApplication?.channelName || selectedPlatformAgentApplication?.channelId}</p>
</div>
<div>
<label className="text-sm font-medium text-muted-foreground">
{language === "zh" ? "提交时间" : "Submitted At"}
</label>
<p className="text-foreground mt-1">{selectedAgentApproval?.submittedAt}</p>
<p className="text-foreground mt-1">{selectedPlatformAgentApplication?.createdAt}</p>
</div>
</div>
<div>
<label className="text-sm font-medium text-muted-foreground">
{language === "zh" ? "Agent类型" : "Agent Type"}
{language === "zh" ? "模板名称" : "Template Name"}
</label>
<p className="text-foreground mt-1">{selectedAgentApproval?.agentType}</p>
<p className="text-foreground mt-1">{selectedPlatformAgentApplication?.templateDisplayName || selectedPlatformAgentApplication?.templateName}</p>
</div>
<div>
<label className="text-sm font-medium text-muted-foreground">
{language === "zh" ? "申请数量" : "Requested Quantity"}
{language === "zh" ? "申请Pod配额" : "Requested Pod Quota"}
</label>
<p className="text-foreground mt-1">{selectedAgentApproval?.requestedQuantity}</p>
<p className="text-foreground mt-1">{selectedPlatformAgentApplication?.requestedPodQuota || 0}</p>
</div>
<div>
<label className="text-sm font-medium text-muted-foreground">
{language === "zh" ? "申请理由" : "Reason"}
</label>
<p className="text-foreground mt-1">{selectedAgentApproval?.reason}</p>
<p className="text-foreground mt-1">{selectedPlatformAgentApplication?.reason || "-"}</p>
</div>
<div className="border-t border-border pt-4">
<div className="space-y-2">
<Label htmlFor="approved-pod-quota">{language === "zh" ? "批准Pod配额" : "Approved Pod Quota"}</Label>
<Input
id="approved-pod-quota"
type="number"
min="1"
placeholder={language === "zh" ? "输入批准的Pod配额" : "Enter approved pod quota"}
value={approvedPodQuota}
onChange={(e) => setApprovedPodQuota(e.target.value)}
className="bg-background border-border"
/>
</div>
<div className="space-y-2 mt-4">
<Label htmlFor="approval-reason">{language === "zh" ? "审批理由" : "Approval Reason"}</Label>
<Input
id="approval-reason"
placeholder={language === "zh" ? "输入审批理由(可选)" : "Enter approval reason (optional)"}
value={approvalReason}
onChange={(e) => setApprovalReason(e.target.value)}
className="bg-background border-border"
/>
</div>
</div>
</div>
<DialogFooter>
@@ -2790,11 +2890,18 @@ export default function AdminDashboard() {
variant="outline"
className="border-destructive text-destructive hover:bg-destructive/10 bg-transparent"
onClick={async () => {
if (!selectedAgentApproval) return
if (!selectedPlatformAgentApplication) return
try {
await TaijiAPIClient.reviewApplication(selectedAgentApproval.id, false, language === "zh" ? "申请被拒绝" : "Application rejected")
await TaijiAPIClient.reviewPlatformAgentApplication(
selectedPlatformAgentApplication.id,
false,
undefined,
approvalReason || (language === "zh" ? "申请被拒绝" : "Application rejected")
)
await loadDashboardData()
setIsAgentApprovalDialogOpen(false)
setIsPlatformAgentApprovalDialogOpen(false)
setApprovedPodQuota("")
setApprovalReason("")
} catch (error) {
console.error("Failed to reject application:", error)
alert(language === "zh" ? "操作失败" : "Operation failed")
@@ -2806,11 +2913,19 @@ export default function AdminDashboard() {
<Button
className="bg-primary text-primary-foreground"
onClick={async () => {
if (!selectedAgentApproval) return
if (!selectedPlatformAgentApplication) return
const podQuota = parseInt(approvedPodQuota) || selectedPlatformAgentApplication.requestedPodQuota || 1
try {
await TaijiAPIClient.reviewApplication(selectedAgentApproval.id, true, language === "zh" ? "申请已批准" : "Application approved")
await TaijiAPIClient.reviewPlatformAgentApplication(
selectedPlatformAgentApplication.id,
true,
podQuota,
approvalReason || (language === "zh" ? "申请已批准" : "Application approved")
)
await loadDashboardData()
setIsAgentApprovalDialogOpen(false)
setIsPlatformAgentApprovalDialogOpen(false)
setApprovedPodQuota("")
setApprovalReason("")
} catch (error) {
console.error("Failed to approve application:", error)
alert(language === "zh" ? "操作失败" : "Operation failed")
@@ -2875,7 +2990,7 @@ export default function AdminDashboard() {
onClick={async () => {
if (!selectedApproval) return
try {
await TaijiAPIClient.reviewApplication(selectedApproval.id, false, language === "zh" ? "申请被拒绝" : "Application rejected")
await TaijiAPIClient.reviewProviderApplication(selectedApproval.id, false, language === "zh" ? "申请被拒绝" : "Application rejected")
await loadDashboardData()
setIsApprovalDialogOpen(false)
} catch (error) {
@@ -2891,7 +3006,7 @@ export default function AdminDashboard() {
onClick={async () => {
if (!selectedApproval) return
try {
await TaijiAPIClient.reviewApplication(selectedApproval.id, true, language === "zh" ? "申请已批准" : "Application approved")
await TaijiAPIClient.reviewProviderApplication(selectedApproval.id, true, language === "zh" ? "申请已批准" : "Application approved")
await loadDashboardData()
setIsApprovalDialogOpen(false)
} catch (error) {
@@ -3255,6 +3370,7 @@ export default function AdminDashboard() {
))
)}
</div>
</div>
)}
+5 -5
View File
@@ -1235,20 +1235,20 @@ export default function ChannelDashboard() {
<p className="text-xs text-muted-foreground">{provider.provider || provider.type || "Official"}</p>
</div>
<Badge
variant={provider.status === "active" || provider.isActive ? "default" : "secondary"}
variant={provider.hasAccess ? "default" : "secondary"}
className={
provider.status === "active" || provider.isActive
provider.hasAccess
? "bg-green-500/10 text-green-500 border-green-500/20"
: "bg-yellow-500/10 text-yellow-500 border-yellow-500/20"
}
>
{provider.status === "active" || provider.isActive
{provider.hasAccess
? language === "zh"
? "已授权"
: "Approved"
: language === "zh"
? "待审批"
: "Pending"}
? "未授权"
: "No Access"}
</Badge>
</div>
<div className="space-y-2 text-sm">
+173 -6
View File
@@ -844,20 +844,20 @@ export class TaijiAPIClient {
/**
* 创建管理员(计费管理员/运营管理员)
* 注意:channelId 是必需参数,计费管理员和运维管理员必须关联到具体的渠道
* POST /api/admin/admins/create
*
* @param data.name - 管理员名称
* @param data.email - 管理员邮箱,用于登录
* @param data.password - 管理员密码
* @param data.role - 角色类型:billing_admin(计费管理员)或 operations_admin(运维管理员)
* @param data.channelId - 渠道ID(必需),指定管理员所属的渠道
* @param data.channelId - 渠道ID(可选),如果提供则创建渠道管理员
*/
static async createAdmin(data: {
name: string
email: string
password: string
role: "billing_admin" | "operations_admin"
channelId: string // 必需参数
channelId?: string // 可选参数
}) {
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/admins/create`, {
method: "POST",
@@ -1041,7 +1041,8 @@ export class TaijiAPIClient {
}
/**
* 获取所有申请
* 获取所有申请(旧的通用接口)
* @deprecated 请使用 getProviderApplications 或 getPlatformAgentApplications
*/
static async getAdminApplications() {
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/channels/applications`, {
@@ -1051,7 +1052,39 @@ export class TaijiAPIClient {
}
/**
* 审批申请
* 获取供应商申请列表
* GET /api/admin/providers/applications
* 用于"渠道申请审批"功能
*/
static async getProviderApplications(status?: "pending" | "approved" | "rejected") {
const url = status
? `${API_BASE_URLS.mcpServer}/api/admin/providers/applications?status=${status}`
: `${API_BASE_URLS.mcpServer}/api/admin/providers/applications`
const response = await fetch(url, {
headers: buildHeaders(),
})
return handleResponse(response)
}
/**
* 审批供应商申请
* PUT /api/admin/providers/applications/{application_id}/review
*/
static async reviewProviderApplication(applicationId: string, approved: boolean, reason?: string) {
const response = await fetch(
`${API_BASE_URLS.mcpServer}/api/admin/providers/applications/${applicationId}/review`,
{
method: "PUT",
headers: buildHeaders(),
body: JSON.stringify({ approved, reason }),
},
)
return handleResponse(response)
}
/**
* 审批申请(旧的通用接口)
* @deprecated 请使用 reviewProviderApplication 或 reviewPlatformAgentApplication
*/
static async reviewApplication(applicationId: string, approved: boolean, reason?: string) {
const response = await fetch(
@@ -1188,12 +1221,15 @@ export class TaijiAPIClient {
/**
* 修改租户密码(渠道管理员或超级管理员)
* PUT /api/channel/tenants/{tenant_id}/password
*
* @param tenantId - 租户ID
* @param newPassword - 新密码
*/
static async changeTenantPassword(tenantId: string, newPassword: string) {
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/tenants/${tenantId}/password`, {
method: "PUT",
headers: buildHeaders(),
body: JSON.stringify({ new_password: newPassword }),
body: JSON.stringify({ newPassword }),
})
return handleResponse(response)
}
@@ -1215,6 +1251,137 @@ export class TaijiAPIClient {
return handleResponse(response)
}
// ==================== 资源申请审批模块 API ====================
// Base URL: http://localhost:8002/api/admin/applications
/**
* 获取平台 Agent 申请列表(管理员)
* GET /api/admin/applications/platform-agents
*
* @param status - 可选,筛选状态:pending | approved | rejected
*/
static async getPlatformAgentApplications(status?: "pending" | "approved" | "rejected") {
const url = status
? `${API_BASE_URLS.mcpServer}/api/admin/applications/platform-agents?status=${status}`
: `${API_BASE_URLS.mcpServer}/api/admin/applications/platform-agents`
const response = await fetch(url, {
headers: buildHeaders(),
})
return handleResponse(response)
}
/**
* 审批平台 Agent 申请
* PUT /api/admin/applications/platform-agents/{application_id}/review
*
* @param applicationId - 申请ID
* @param approved - 是否批准
* @param approvedPodQuota - 批准的Pod配额数量(仅批准时需要)
* @param reason - 审批理由
*/
static async reviewPlatformAgentApplication(
applicationId: string,
approved: boolean,
approvedPodQuota?: number,
reason?: string
) {
const response = await fetch(
`${API_BASE_URLS.mcpServer}/api/admin/applications/platform-agents/${applicationId}/review`,
{
method: "PUT",
headers: buildHeaders(),
body: JSON.stringify({ approved, approvedPodQuota, reason }),
}
)
return handleResponse(response)
}
// ==================== 平台 Agent 管理模块 API ====================
// Base URL: http://localhost:8002/api/admin/platform-agents
/**
* 获取平台 Agent 模板列表
* GET /api/admin/platform-agents/templates
*/
static async getPlatformAgentTemplates() {
const response = await fetch(
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/templates`,
{
headers: buildHeaders(),
}
)
return handleResponse(response)
}
/**
* 获取平台 Agent 分配情况
* GET /api/admin/platform-agents/allocations
*/
static async getPlatformAgentAllocations() {
const response = await fetch(
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/allocations`,
{
headers: buildHeaders(),
}
)
return handleResponse(response)
}
/**
* 获取平台 Agent 运行状态
* GET /api/admin/platform-agents/status
*/
static async getPlatformAgentStatus() {
const response = await fetch(
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/status`,
{
headers: buildHeaders(),
}
)
return handleResponse(response)
}
/**
* 直接分配平台 Agent 配额给渠道
* POST /api/admin/platform-agents/allocate
*
* @param channelId - 渠道ID
* @param templateName - 模板名称(如 gpt-assistant)
* @param podQuota - Pod配额数量(≥1)
*/
static async allocatePlatformAgentToChannel(
channelId: string,
templateName: string,
podQuota: number
) {
const response = await fetch(
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/allocate?channel_id=${channelId}&template_name=${templateName}&pod_quota=${podQuota}`,
{
method: "POST",
headers: buildHeaders(),
}
)
return handleResponse(response)
}
/**
* 撤销渠道的平台 Agent 配额
* DELETE /api/admin/platform-agents/allocate
*
* @param channelId - 渠道ID
* @param templateName - 模板名称
*/
static async revokePlatformAgentFromChannel(channelId: string, templateName: string) {
const response = await fetch(
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/allocate?channel_id=${channelId}&template_name=${templateName}`,
{
method: "DELETE",
headers: buildHeaders(),
}
)
return handleResponse(response)
}
// ==================== 供应商管理 API ====================
// Base URL: http://localhost:8002/api/providers