diff --git a/web/src/pages/Setting/Operation/SettingsChannelAffinity.jsx b/web/src/pages/Setting/Operation/SettingsChannelAffinity.jsx
index 559d18bc..76ad7aec 100644
--- a/web/src/pages/Setting/Operation/SettingsChannelAffinity.jsx
+++ b/web/src/pages/Setting/Operation/SettingsChannelAffinity.jsx
@@ -192,6 +192,36 @@ const parseOptionalObjectJson = (jsonString, label) => {
}
};
+const buildChannelAffinityRulePayload = ({
+ values,
+ isEdit,
+ editingRuleId,
+ rulesLength,
+ modelRegex,
+ pathRegex,
+ keySources,
+ userAgentInclude,
+ paramOverrideTemplate,
+}) => ({
+ id: isEdit ? editingRuleId : rulesLength,
+ name: (values?.name || '').trim(),
+ model_regex: modelRegex,
+ path_regex: pathRegex,
+ key_sources: keySources,
+ value_regex: (values?.value_regex || '').trim(),
+ ttl_seconds: Number(values?.ttl_seconds || 0),
+ include_using_group: !!values?.include_using_group,
+ include_model_name: !!values?.include_model_name,
+ include_rule_name: !!values?.include_rule_name,
+ skip_retry_on_failure: !!values?.skip_retry_on_failure,
+ ...(userAgentInclude.length > 0
+ ? { user_agent_include: userAgentInclude }
+ : {}),
+ ...(paramOverrideTemplate
+ ? { param_override_template: paramOverrideTemplate }
+ : {}),
+});
+
export default function SettingsChannelAffinity(props) {
const { t } = useTranslation();
const { Text } = Typography;
@@ -456,14 +486,12 @@ export default function SettingsChannelAffinity(props) {
const templates = [
CHANNEL_AFFINITY_RULE_TEMPLATES.codexCli,
CHANNEL_AFFINITY_RULE_TEMPLATES.claudeCli,
- ].map(
- (tpl) => {
- const baseTemplate = cloneChannelAffinityTemplate(tpl);
- const name = makeUniqueName(existingNames, tpl.name);
- existingNames.add(name);
- return { ...baseTemplate, name };
- },
- );
+ ].map((tpl) => {
+ const baseTemplate = cloneChannelAffinityTemplate(tpl);
+ const name = makeUniqueName(existingNames, tpl.name);
+ existingNames.add(name);
+ return { ...baseTemplate, name };
+ });
const next = [...(rules || []), ...templates].map((r, idx) => ({
...(r || {}),
@@ -716,27 +744,17 @@ export default function SettingsChannelAffinity(props) {
return showError(t(paramTemplateValidation.message));
}
- const rulePayload = {
- id: isEdit ? editingRule.id : rules.length,
- name: (values.name || '').trim(),
- model_regex: modelRegex,
- path_regex: normalizeStringList(values.path_regex_text),
- key_sources: keySourcesValidation.value,
- value_regex: (values.value_regex || '').trim(),
- ttl_seconds: Number(values.ttl_seconds || 0),
- include_using_group: !!values.include_using_group,
- include_model_name: !!values.include_model_name,
- include_rule_name: !!values.include_rule_name,
- ...(values.skip_retry_on_failure
- ? { skip_retry_on_failure: true }
- : {}),
- ...(userAgentInclude.length > 0
- ? { user_agent_include: userAgentInclude }
- : {}),
- ...(paramTemplateValidation.value
- ? { param_override_template: paramTemplateValidation.value }
- : {}),
- };
+ const rulePayload = buildChannelAffinityRulePayload({
+ values,
+ isEdit,
+ editingRuleId: editingRule?.id,
+ rulesLength: rules.length,
+ modelRegex,
+ pathRegex: normalizeStringList(values.path_regex_text),
+ keySources: keySourcesValidation.value,
+ userAgentInclude,
+ paramOverrideTemplate: paramTemplateValidation.value,
+ });
if (!rulePayload.name) return showError(t('名称不能为空'));
@@ -1273,9 +1291,7 @@ export default function SettingsChannelAffinity(props) {
label={t('作用域:包含模型名称')}
/>