feat(agent-runtime): 接入多服务商安全配置
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}API 服务商 · JobRadar{% endblock %}
|
||||
{% block content %}
|
||||
<div class="provider-layout{% if selected_provider %} has-drawer{% endif %}">
|
||||
<section class="provider-main">
|
||||
<header class="page-heading">
|
||||
<div><h1>API 服务商</h1><p>连接模型服务,为不同 Agent 选择合适的模型</p></div>
|
||||
<a class="primary-button" href="?provider=custom">+ 自定义服务商</a>
|
||||
</header>
|
||||
<div class="provider-tools">
|
||||
<form class="provider-search" method="get">
|
||||
<label class="sr-only" for="provider-search">搜索服务商</label>
|
||||
<input id="provider-search" name="q" value="{{ query }}" placeholder="⌕ 搜索服务商">
|
||||
<input type="hidden" name="category" value="{{ active_category }}">
|
||||
</form>
|
||||
<nav class="filter-tabs" aria-label="服务商分类">
|
||||
{% for code, label in categories.items %}<a href="?category={{ code }}{% if query %}&q={{ query|urlencode }}{% endif %}" {% if active_category == code %}aria-current="page"{% endif %}>{{ label }}</a>{% endfor %}
|
||||
</nav>
|
||||
<span class="security-note">▣ 密钥仅在服务端加密保存</span>
|
||||
</div>
|
||||
<div class="provider-summary"><strong>共 {{ provider_count }} 个内置服务商</strong><span>{{ connected_count }} 个已连接</span></div>
|
||||
<div class="provider-grid">
|
||||
{% for card in cards %}
|
||||
<article class="provider-card{% if selected_provider.code == card.provider.code %} selected{% endif %}">
|
||||
<a class="card-link" href="?provider={{ card.provider.code }}&category={{ active_category }}{% if query %}&q={{ query|urlencode }}{% endif %}" aria-label="配置 {{ card.provider.name }}"></a>
|
||||
<div class="provider-card-head"><span class="provider-mark mark-{{ card.provider.category }}">{{ card.provider.mark }}</span><span><strong>{{ card.provider.name }}</strong><small>{{ card.provider.vendor }}</small></span><span class="card-menu" aria-hidden="true">⋮</span></div>
|
||||
<div class="provider-tags"><span>{{ card.provider.protocol_label }}</span><span>{% if card.provider.key_only %}仅 API Key{% else %}需额外配置{% endif %}</span></div>
|
||||
<p class="connection-status {% if card.config %}connected{% endif %}"><span aria-hidden="true">●</span>{% if card.config %}{{ card.config.get_status_display }}{% else %}未配置{% endif %}{% if card.config.is_default %}<em>默认</em>{% endif %}</p>
|
||||
</article>
|
||||
{% empty %}<div class="empty-panel"><h2>没有匹配的服务商</h2><p>请调整搜索词或分类条件。</p></div>{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% if selected_provider %}
|
||||
<aside class="provider-drawer" aria-labelledby="drawer-title">
|
||||
<div class="drawer-header"><div><h2 id="drawer-title">配置{{ selected_provider.name }}</h2><p>系统已预置接口地址和协议</p></div><a class="drawer-close" href="{% url 'agent_runtime:provider-list' %}" aria-label="关闭">×</a></div>
|
||||
<dl class="preset-details"><div><dt>接口协议</dt><dd>{{ selected_provider.protocol_label }}</dd></div><div><dt>接口地址</dt><dd>{% if selected_provider.base_url %}由系统预置{% else %}需要额外配置{% endif %}</dd></div></dl>
|
||||
{% if selected_provider.key_only %}
|
||||
<form class="provider-form" method="post" action="{% url 'agent_runtime:provider-configure' selected_provider.code %}?provider={{ selected_provider.code }}">
|
||||
{% csrf_token %}
|
||||
{% if provider_form.non_field_errors %}<div class="form-alert">{{ provider_form.non_field_errors }}</div>{% endif %}
|
||||
<div class="field-row"><label for="{{ provider_form.api_key.id_for_label }}">API Key</label>{{ provider_form.api_key }}{% if selected_config %}<small>当前密钥:{{ selected_config.key_hint }};重新保存将覆盖旧密钥。</small>{% endif %}{{ provider_form.api_key.errors }}</div>
|
||||
<div class="key-safety">▣ 密钥加密存储,保存后不可查看</div>
|
||||
{% if selected_config %}<div class="connection-ok"><strong>✓ 已通过连接验证</strong><span>最近验证:{{ selected_config.last_verified_at|date:"Y-m-d H:i" }}</span></div>{% endif %}
|
||||
<div class="field-row"><label for="{{ provider_form.model_id.id_for_label }}">模型选择</label>{{ provider_form.model_id }}<small>留空时自动使用服务商推荐模型。</small>{{ provider_form.model_id.errors }}</div>
|
||||
<label class="checkbox-row">{{ provider_form.use_as_default }} <span>设为 Agent 默认服务商</span></label>
|
||||
<details class="advanced-settings"><summary>高级设置(可选)</summary><p>接口地址和协议由系统预设,当前版本不允许用户覆盖。</p></details>
|
||||
<div class="drawer-actions">{% if selected_config %}<button class="danger-button" form="disconnect-form" type="submit">移除配置</button>{% endif %}<a class="secondary-button" href="{% url 'agent_runtime:provider-list' %}">取消</a><button class="primary-button" type="submit">测试并保存</button></div>
|
||||
</form>
|
||||
{% if selected_config %}<form id="disconnect-form" method="post" action="{% url 'agent_runtime:provider-disconnect' selected_provider.code %}">{% csrf_token %}</form>{% endif %}
|
||||
{% else %}
|
||||
<div class="coming-soon"><span aria-hidden="true">◇</span><h3>需要额外配置</h3><p>{{ selected_provider.note }}</p><p>后续将根据该平台的地域、部署或 IAM 要求提供专用表单。</p></div>
|
||||
<div class="drawer-actions"><a class="secondary-button" href="{% url 'agent_runtime:provider-list' %}">关闭</a></div>
|
||||
{% endif %}
|
||||
</aside>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
+37
-2
@@ -1,5 +1,40 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>{% block title %}JobRadar{% endblock %}</title><link rel="stylesheet" href="/static/css/app.css"></head>
|
||||
<body><a class="skip" href="#main">跳到主要内容</a><header><strong>JobRadar · 职途雷达</strong>{% if user.is_authenticated %}<nav><a href="{% url 'agent_runtime:run-list' %}">运行记录</a><a href="{% url 'accounts:profile' %}">个人资料</a><form method="post" action="{% url 'accounts:logout' %}">{% csrf_token %}<button>退出</button></form></nav>{% endif %}</header><main id="main">{% for message in messages %}<p class="message">{{ message }}</p>{% endfor %}{% block content %}{% endblock %}</main></body>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>{% block title %}JobRadar{% endblock %}</title>
|
||||
<link rel="stylesheet" href="/static/css/app.css">
|
||||
</head>
|
||||
<body class="{% if user.is_authenticated %}app-shell{% else %}public-shell{% endif %}">
|
||||
<a class="skip" href="#main">跳到主要内容</a>
|
||||
{% if user.is_authenticated %}
|
||||
<aside class="sidebar" aria-label="主导航">
|
||||
<a class="brand" href="{% url 'agent_runtime:run-list' %}">
|
||||
<span class="brand-mark" aria-hidden="true">◎</span>
|
||||
<span><strong>JobRadar</strong><small>职途雷达</small></span>
|
||||
</a>
|
||||
<nav class="side-nav">
|
||||
<p class="nav-group">工作台</p>
|
||||
<a href="{% url 'agent_runtime:run-list' %}"><span aria-hidden="true">◫</span> Agent 运行记录</a>
|
||||
<p class="nav-group">设置</p>
|
||||
<a href="{% url 'agent_runtime:provider-list' %}"><span aria-hidden="true">⚙</span> API 服务商</a>
|
||||
<a href="{% url 'accounts:profile' %}"><span aria-hidden="true">○</span> 个人资料</a>
|
||||
</nav>
|
||||
<div class="sidebar-user">
|
||||
<span class="avatar">{{ user.username|first|upper }}</span>
|
||||
<span><strong>{{ user.username }}</strong><small>个人工作区</small></span>
|
||||
<form method="post" action="{% url 'accounts:logout' %}">
|
||||
{% csrf_token %}<button class="icon-button" title="退出登录">↗</button>
|
||||
</form>
|
||||
</div>
|
||||
</aside>
|
||||
{% else %}
|
||||
<header class="public-header"><strong>JobRadar · 职途雷达</strong></header>
|
||||
{% endif %}
|
||||
<main id="main" class="main-content">
|
||||
{% for message in messages %}<p class="message">{{ message }}</p>{% endfor %}
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user