fix(frontend): clarify OpenAI Fast/Flex policy rules

This commit is contained in:
InCerryGit
2026-08-16 23:49:21 +08:00
parent baeac1f3de
commit 22fc0cdbf5
5 changed files with 167 additions and 23 deletions
+65 -7
View File
@@ -1128,6 +1128,47 @@
</button>
</div>
<div
class="mb-4 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-gray-500 dark:text-gray-400"
:data-testid="`openai-fast-policy-summary-${ruleIndex}`"
>
<span class="font-medium text-gray-700 dark:text-gray-300">
{{
t(
hasOpenAIFastPolicyTargetModels(rule)
? "admin.settings.openaiFastPolicy.summaryTargetModels"
: "admin.settings.openaiFastPolicy.summaryAllModels",
)
}}
</span>
<span aria-hidden="true">→</span>
<span
class="inline-flex items-center rounded bg-primary-50 px-2 py-0.5 font-medium text-primary-700 dark:bg-primary-900/30 dark:text-primary-300"
>
{{ openaiFastPolicyActionSummary(rule.action) }}
</span>
<template v-if="hasOpenAIFastPolicyTargetModels(rule)">
<span aria-hidden="true">·</span>
<span class="font-medium text-gray-700 dark:text-gray-300">
{{
t(
"admin.settings.openaiFastPolicy.summaryOtherModels",
)
}}
</span>
<span aria-hidden="true">→</span>
<span
class="inline-flex items-center rounded bg-gray-100 px-2 py-0.5 font-medium text-gray-700 dark:bg-dark-600 dark:text-gray-300"
>
{{
openaiFastPolicyActionSummary(
rule.fallback_action || "pass",
)
}}
</span>
</template>
</div>
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
<!-- Service Tier -->
<div>
@@ -1227,14 +1268,23 @@
</p>
</div>
<!-- Model Whitelist -->
<div class="mt-3">
<!-- Target Models -->
<div
class="mt-3"
role="group"
:aria-labelledby="`openai-fast-policy-models-label-${ruleIndex}`"
:aria-describedby="`openai-fast-policy-models-hint-${ruleIndex}`"
>
<label
:id="`openai-fast-policy-models-label-${ruleIndex}`"
class="mb-1 block text-xs font-medium text-gray-600 dark:text-gray-400"
>
{{ t("admin.settings.openaiFastPolicy.modelWhitelist") }}
</label>
<p class="mb-2 text-xs text-gray-400 dark:text-gray-500">
<p
:id="`openai-fast-policy-models-hint-${ruleIndex}`"
class="mb-2 text-xs text-gray-400 dark:text-gray-500"
>
{{
t("admin.settings.openaiFastPolicy.modelWhitelistHint")
}}
@@ -1298,11 +1348,9 @@
</button>
</div>
<!-- Fallback Action (only when model_whitelist is non-empty) -->
<!-- Other Models Action (only when target models are non-empty) -->
<div
v-if="
rule.model_whitelist && rule.model_whitelist.length > 0
"
v-if="hasOpenAIFastPolicyTargetModels(rule)"
class="mt-3"
>
<label
@@ -11975,6 +12023,16 @@ const openaiFastPolicyActionOptions = computed(() => [
{ value: "block", label: t("admin.settings.openaiFastPolicy.actionBlock") },
]);
function openaiFastPolicyActionSummary(
action: OpenAIFastPolicyRule["action"],
) {
return t(`admin.settings.openaiFastPolicy.summaryAction.${action}`);
}
function hasOpenAIFastPolicyTargetModels(rule: OpenAIFastPolicyRule) {
return Boolean(rule.model_whitelist?.some((pattern) => pattern.trim() !== ""));
}
const openaiFastPolicyScopeOptions = computed(() => [
{ value: "all", label: t("admin.settings.openaiFastPolicy.scopeAll") },
{ value: "oauth", label: t("admin.settings.openaiFastPolicy.scopeOAuth") },
@@ -229,6 +229,11 @@ vi.mock("vue-i18n", async () => {
"admin.settings.upstreamBillingProbe.intervalHint": "范围 5–1440 分钟。",
"admin.settings.upstreamBillingProbe.saved": "上游倍率自动探测设置已保存",
"admin.settings.upstreamBillingProbe.saveFailed": "保存上游倍率自动探测设置失败",
"admin.settings.openaiFastPolicy.summaryTargetModels": "目标模型",
"admin.settings.openaiFastPolicy.summaryAllModels": "全部模型",
"admin.settings.openaiFastPolicy.summaryOtherModels": "其他模型",
"admin.settings.openaiFastPolicy.summaryAction.filter": "过滤",
"admin.settings.openaiFastPolicy.summaryAction.pass": "透传",
"admin.settings.security.passkeyDeploymentHint":
"请由服务器运维在部署配置中将 webauthn.enabled 设为 true,填写 webauthn.rp_id(仅域名)与 webauthn.rp_origins(完整 HTTPS 来源),然后重启服务。",
"admin.settings.site.uploadImage": "上传图片",
@@ -1261,6 +1266,43 @@ describe("admin SettingsView payment visible method controls", () => {
expect(wrapper.text()).not.toContain("OpenAI 高级调度器");
});
it("summarizes target and other-model actions, then switches to all models", async () => {
getSettings.mockResolvedValueOnce({
...baseSettingsResponse,
openai_fast_policy_settings: {
rules: [
{
service_tier: "all",
action: "filter",
scope: "all",
model_whitelist: ["gpt-5.6-sol"],
fallback_action: "pass",
},
],
},
});
const wrapper = mountView();
await flushPromises();
await openGatewayTab(wrapper);
const summary = wrapper.get('[data-testid="openai-fast-policy-summary-0"]');
expect(summary.text()).toContain("目标模型");
expect(summary.text()).toContain("过滤");
expect(summary.text()).toContain("其他模型");
expect(summary.text()).toContain("透传");
await wrapper
.get(
'[role="group"][aria-labelledby="openai-fast-policy-models-label-0"] input[type="text"]',
)
.setValue("");
expect(summary.text()).toContain("全部模型");
expect(summary.text()).toContain("过滤");
expect(summary.text()).not.toContain("其他模型");
expect(summary.text()).not.toContain("透传");
});
it("loads and saves upstream billing probe settings from the gateway tab", async () => {
getUpstreamBillingProbeSettings.mockResolvedValueOnce({
enabled: false,