Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
f0886c8a
authored
Feb 22, 2026
by
Seefs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix
parent
6b58648d
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
559 additions
and
120 deletions
+559
-120
web/src/components/table/channels/modals/ParamOverrideEditorModal.jsx
+559
-120
No files found.
web/src/components/table/channels/modals/ParamOverrideEditorModal.jsx
View file @
f0886c8a
...
@@ -20,10 +20,10 @@ For commercial licensing, please contact support@quantumnous.com
...
@@ -20,10 +20,10 @@ For commercial licensing, please contact support@quantumnous.com
import
React
,
{
useCallback
,
useEffect
,
useMemo
,
useState
}
from
'react'
;
import
React
,
{
useCallback
,
useEffect
,
useMemo
,
useState
}
from
'react'
;
import
{
useTranslation
}
from
'react-i18next'
;
import
{
useTranslation
}
from
'react-i18next'
;
import
{
import
{
Banner
,
Button
,
Button
,
Card
,
Card
,
Col
,
Col
,
Collapse
,
Input
,
Input
,
Modal
,
Modal
,
Row
,
Row
,
...
@@ -31,6 +31,7 @@ import {
...
@@ -31,6 +31,7 @@ import {
Space
,
Space
,
Switch
,
Switch
,
Tag
,
Tag
,
TextArea
,
Typography
,
Typography
,
}
from
'@douyinfe/semi-ui'
;
}
from
'@douyinfe/semi-ui'
;
import
{
IconDelete
,
IconPlus
}
from
'@douyinfe/semi-icons'
;
import
{
IconDelete
,
IconPlus
}
from
'@douyinfe/semi-icons'
;
...
@@ -204,6 +205,11 @@ const OPERATION_TEMPLATE = {
...
@@ -204,6 +205,11 @@ const OPERATION_TEMPLATE = {
],
],
};
};
const
TEMPLATE_LIBRARY_OPTIONS
=
[
{
label
:
'Template · Operations'
,
value
:
'operations'
},
{
label
:
'Template · Legacy Object'
,
value
:
'legacy'
},
];
let
localIdSeed
=
0
;
let
localIdSeed
=
0
;
const
nextLocalId
=
()
=>
`param_override_
${
Date
.
now
()}
_
${
localIdSeed
++
}
`
;
const
nextLocalId
=
()
=>
`param_override_
${
Date
.
now
()}
_
${
localIdSeed
++
}
`
;
...
@@ -274,6 +280,28 @@ const normalizeOperation = (operation = {}) => ({
...
@@ -274,6 +280,28 @@ const normalizeOperation = (operation = {}) => ({
const
createDefaultOperation
=
()
=>
normalizeOperation
({
mode
:
'set'
});
const
createDefaultOperation
=
()
=>
normalizeOperation
({
mode
:
'set'
});
const
getOperationSummary
=
(
operation
=
{},
index
=
0
)
=>
{
const
mode
=
operation
.
mode
||
'set'
;
if
(
mode
===
'sync_fields'
)
{
const
from
=
String
(
operation
.
from
||
''
).
trim
();
const
to
=
String
(
operation
.
to
||
''
).
trim
();
return
`
${
index
+
1
}
.
${
mode
}
·
${
from
||
to
||
'-'
}
`
;
}
const
path
=
String
(
operation
.
path
||
''
).
trim
();
const
from
=
String
(
operation
.
from
||
''
).
trim
();
const
to
=
String
(
operation
.
to
||
''
).
trim
();
return
`
${
index
+
1
}
.
${
mode
}
·
${
path
||
from
||
to
||
'-'
}
`
;
};
const
getOperationModeTagColor
=
(
mode
=
'set'
)
=>
{
if
(
mode
.
includes
(
'header'
))
return
'cyan'
;
if
(
mode
.
includes
(
'replace'
)
||
mode
.
includes
(
'trim'
))
return
'violet'
;
if
(
mode
.
includes
(
'copy'
)
||
mode
.
includes
(
'move'
))
return
'blue'
;
if
(
mode
.
includes
(
'error'
)
||
mode
.
includes
(
'prune'
))
return
'red'
;
if
(
mode
.
includes
(
'sync'
))
return
'green'
;
return
'grey'
;
};
const
parseInitialState
=
(
rawValue
)
=>
{
const
parseInitialState
=
(
rawValue
)
=>
{
const
text
=
typeof
rawValue
===
'string'
?
rawValue
:
''
;
const
text
=
typeof
rawValue
===
'string'
?
rawValue
:
''
;
const
trimmed
=
text
.
trim
();
const
trimmed
=
text
.
trim
();
...
@@ -439,6 +467,10 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -439,6 +467,10 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
const
[
operations
,
setOperations
]
=
useState
([
createDefaultOperation
()]);
const
[
operations
,
setOperations
]
=
useState
([
createDefaultOperation
()]);
const
[
jsonText
,
setJsonText
]
=
useState
(
''
);
const
[
jsonText
,
setJsonText
]
=
useState
(
''
);
const
[
jsonError
,
setJsonError
]
=
useState
(
''
);
const
[
jsonError
,
setJsonError
]
=
useState
(
''
);
const
[
operationSearch
,
setOperationSearch
]
=
useState
(
''
);
const
[
selectedOperationId
,
setSelectedOperationId
]
=
useState
(
''
);
const
[
expandedConditionMap
,
setExpandedConditionMap
]
=
useState
({});
const
[
templateLibraryKey
,
setTemplateLibraryKey
]
=
useState
(
'operations'
);
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
!
visible
)
return
;
if
(
!
visible
)
return
;
...
@@ -449,13 +481,73 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -449,13 +481,73 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
setOperations
(
nextState
.
operations
);
setOperations
(
nextState
.
operations
);
setJsonText
(
nextState
.
jsonText
);
setJsonText
(
nextState
.
jsonText
);
setJsonError
(
nextState
.
jsonError
);
setJsonError
(
nextState
.
jsonError
);
setOperationSearch
(
''
);
setSelectedOperationId
(
nextState
.
operations
[
0
]?.
id
||
''
);
setExpandedConditionMap
({});
setTemplateLibraryKey
(
nextState
.
visualMode
===
'legacy'
?
'legacy'
:
'operations'
,
);
},
[
visible
,
value
]);
},
[
visible
,
value
]);
useEffect
(()
=>
{
if
(
operations
.
length
===
0
)
{
setSelectedOperationId
(
''
);
return
;
}
if
(
!
operations
.
some
((
item
)
=>
item
.
id
===
selectedOperationId
))
{
setSelectedOperationId
(
operations
[
0
].
id
);
}
},
[
operations
,
selectedOperationId
]);
useEffect
(()
=>
{
setTemplateLibraryKey
(
visualMode
===
'legacy'
?
'legacy'
:
'operations'
);
},
[
visualMode
]);
const
operationCount
=
useMemo
(
const
operationCount
=
useMemo
(
()
=>
operations
.
filter
((
item
)
=>
!
isOperationBlank
(
item
)).
length
,
()
=>
operations
.
filter
((
item
)
=>
!
isOperationBlank
(
item
)).
length
,
[
operations
],
[
operations
],
);
);
const
filteredOperations
=
useMemo
(()
=>
{
const
keyword
=
operationSearch
.
trim
().
toLowerCase
();
if
(
!
keyword
)
return
operations
;
return
operations
.
filter
((
operation
)
=>
{
const
searchableText
=
[
operation
.
mode
,
operation
.
path
,
operation
.
from
,
operation
.
to
,
operation
.
value_text
,
]
.
filter
(
Boolean
)
.
join
(
' '
)
.
toLowerCase
();
return
searchableText
.
includes
(
keyword
);
});
},
[
operationSearch
,
operations
]);
const
selectedOperation
=
useMemo
(
()
=>
operations
.
find
((
operation
)
=>
operation
.
id
===
selectedOperationId
),
[
operations
,
selectedOperationId
],
);
const
selectedOperationIndex
=
useMemo
(
()
=>
operations
.
findIndex
((
operation
)
=>
operation
.
id
===
selectedOperationId
),
[
operations
,
selectedOperationId
],
);
const
topOperationModes
=
useMemo
(()
=>
{
const
counts
=
operations
.
reduce
((
acc
,
operation
)
=>
{
const
mode
=
operation
.
mode
||
'set'
;
acc
[
mode
]
=
(
acc
[
mode
]
||
0
)
+
1
;
return
acc
;
},
{});
return
Object
.
entries
(
counts
)
.
sort
((
a
,
b
)
=>
b
[
1
]
-
a
[
1
])
.
slice
(
0
,
4
);
},
[
operations
]);
const
buildVisualJson
=
useCallback
(()
=>
{
const
buildVisualJson
=
useCallback
(()
=>
{
if
(
visualMode
===
'legacy'
)
{
if
(
visualMode
===
'legacy'
)
{
const
trimmed
=
legacyValue
.
trim
();
const
trimmed
=
legacyValue
.
trim
();
...
@@ -545,8 +637,10 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -545,8 +637,10 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
if
(
editMode
===
'visual'
)
return
;
if
(
editMode
===
'visual'
)
return
;
const
trimmed
=
jsonText
.
trim
();
const
trimmed
=
jsonText
.
trim
();
if
(
!
trimmed
)
{
if
(
!
trimmed
)
{
const
fallback
=
createDefaultOperation
();
setVisualMode
(
'operations'
);
setVisualMode
(
'operations'
);
setOperations
([
createDefaultOperation
()]);
setOperations
([
fallback
]);
setSelectedOperationId
(
fallback
.
id
);
setLegacyValue
(
''
);
setLegacyValue
(
''
);
setJsonError
(
''
);
setJsonError
(
''
);
setEditMode
(
'visual'
);
setEditMode
(
'visual'
);
...
@@ -563,21 +657,24 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -563,21 +657,24 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
!
Array
.
isArray
(
parsed
)
&&
!
Array
.
isArray
(
parsed
)
&&
Array
.
isArray
(
parsed
.
operations
)
Array
.
isArray
(
parsed
.
operations
)
)
{
)
{
setVisualMode
(
'operations'
);
const
nextOperations
=
setOperations
(
parsed
.
operations
.
length
>
0
parsed
.
operations
.
length
>
0
?
parsed
.
operations
.
map
(
normalizeOperation
)
?
parsed
.
operations
.
map
(
normalizeOperation
)
:
[
createDefaultOperation
()],
:
[
createDefaultOperation
()];
);
setVisualMode
(
'operations'
);
setOperations
(
nextOperations
);
setSelectedOperationId
(
nextOperations
[
0
]?.
id
||
''
);
setLegacyValue
(
''
);
setLegacyValue
(
''
);
setJsonError
(
''
);
setJsonError
(
''
);
setEditMode
(
'visual'
);
setEditMode
(
'visual'
);
return
;
return
;
}
}
if
(
parsed
&&
typeof
parsed
===
'object'
&&
!
Array
.
isArray
(
parsed
))
{
if
(
parsed
&&
typeof
parsed
===
'object'
&&
!
Array
.
isArray
(
parsed
))
{
const
fallback
=
createDefaultOperation
();
setVisualMode
(
'legacy'
);
setVisualMode
(
'legacy'
);
setLegacyValue
(
JSON
.
stringify
(
parsed
,
null
,
2
));
setLegacyValue
(
JSON
.
stringify
(
parsed
,
null
,
2
));
setOperations
([
createDefaultOperation
()]);
setOperations
([
fallback
]);
setSelectedOperationId
(
fallback
.
id
);
setJsonError
(
''
);
setJsonError
(
''
);
setEditMode
(
'visual'
);
setEditMode
(
'visual'
);
return
;
return
;
...
@@ -587,27 +684,54 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -587,27 +684,54 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
const
setOldTemplate
=
()
=>
{
const
setOldTemplate
=
()
=>
{
const
text
=
JSON
.
stringify
(
LEGACY_TEMPLATE
,
null
,
2
);
const
text
=
JSON
.
stringify
(
LEGACY_TEMPLATE
,
null
,
2
);
const
fallback
=
createDefaultOperation
();
setVisualMode
(
'legacy'
);
setVisualMode
(
'legacy'
);
setLegacyValue
(
text
);
setLegacyValue
(
text
);
setOperations
([
fallback
]);
setSelectedOperationId
(
fallback
.
id
);
setExpandedConditionMap
({});
setJsonText
(
text
);
setJsonText
(
text
);
setJsonError
(
''
);
setJsonError
(
''
);
setEditMode
(
'visual'
);
setEditMode
(
'visual'
);
setTemplateLibraryKey
(
'legacy'
);
};
};
const
setNewTemplate
=
()
=>
{
const
setNewTemplate
=
()
=>
{
const
nextOperations
=
OPERATION_TEMPLATE
.
operations
.
map
(
normalizeOperation
);
setVisualMode
(
'operations'
);
setVisualMode
(
'operations'
);
setOperations
(
OPERATION_TEMPLATE
.
operations
.
map
(
normalizeOperation
));
setOperations
(
nextOperations
);
setSelectedOperationId
(
nextOperations
[
0
]?.
id
||
''
);
setExpandedConditionMap
({});
setJsonText
(
JSON
.
stringify
(
OPERATION_TEMPLATE
,
null
,
2
));
setJsonText
(
JSON
.
stringify
(
OPERATION_TEMPLATE
,
null
,
2
));
setJsonError
(
''
);
setJsonError
(
''
);
setEditMode
(
'visual'
);
setEditMode
(
'visual'
);
setTemplateLibraryKey
(
'operations'
);
};
};
const
clearValue
=
()
=>
{
const
clearValue
=
()
=>
{
const
fallback
=
createDefaultOperation
();
setVisualMode
(
'operations'
);
setVisualMode
(
'operations'
);
setLegacyValue
(
''
);
setLegacyValue
(
''
);
setOperations
([
createDefaultOperation
()]);
setOperations
([
fallback
]);
setSelectedOperationId
(
fallback
.
id
);
setExpandedConditionMap
({});
setJsonText
(
''
);
setJsonText
(
''
);
setJsonError
(
''
);
setJsonError
(
''
);
setTemplateLibraryKey
(
'operations'
);
};
const
applyTemplateFromLibrary
=
()
=>
{
if
(
templateLibraryKey
===
'legacy'
)
{
setOldTemplate
();
return
;
}
setNewTemplate
();
};
const
resetEditorState
=
()
=>
{
clearValue
();
setEditMode
(
'visual'
);
};
};
const
updateOperation
=
(
operationId
,
patch
)
=>
{
const
updateOperation
=
(
operationId
,
patch
)
=>
{
...
@@ -619,10 +743,13 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -619,10 +743,13 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
};
};
const
addOperation
=
()
=>
{
const
addOperation
=
()
=>
{
setOperations
((
prev
)
=>
[...
prev
,
createDefaultOperation
()]);
const
created
=
createDefaultOperation
();
setOperations
((
prev
)
=>
[...
prev
,
created
]);
setSelectedOperationId
(
created
.
id
);
};
};
const
duplicateOperation
=
(
operationId
)
=>
{
const
duplicateOperation
=
(
operationId
)
=>
{
let
insertedId
=
''
;
setOperations
((
prev
)
=>
{
setOperations
((
prev
)
=>
{
const
index
=
prev
.
findIndex
((
item
)
=>
item
.
id
===
operationId
);
const
index
=
prev
.
findIndex
((
item
)
=>
item
.
id
===
operationId
);
if
(
index
<
0
)
return
prev
;
if
(
index
<
0
)
return
prev
;
...
@@ -643,10 +770,14 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -643,10 +770,14 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
pass_missing_key
:
condition
.
pass_missing_key
,
pass_missing_key
:
condition
.
pass_missing_key
,
})),
})),
});
});
insertedId
=
cloned
.
id
;
const
next
=
[...
prev
];
const
next
=
[...
prev
];
next
.
splice
(
index
+
1
,
0
,
cloned
);
next
.
splice
(
index
+
1
,
0
,
cloned
);
return
next
;
return
next
;
});
});
if
(
insertedId
)
{
setSelectedOperationId
(
insertedId
);
}
};
};
const
removeOperation
=
(
operationId
)
=>
{
const
removeOperation
=
(
operationId
)
=>
{
...
@@ -654,19 +785,32 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -654,19 +785,32 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
if
(
prev
.
length
<=
1
)
return
[
createDefaultOperation
()];
if
(
prev
.
length
<=
1
)
return
[
createDefaultOperation
()];
return
prev
.
filter
((
item
)
=>
item
.
id
!==
operationId
);
return
prev
.
filter
((
item
)
=>
item
.
id
!==
operationId
);
});
});
setExpandedConditionMap
((
prev
)
=>
{
if
(
!
Object
.
prototype
.
hasOwnProperty
.
call
(
prev
,
operationId
))
{
return
prev
;
}
const
next
=
{
...
prev
};
delete
next
[
operationId
];
return
next
;
});
};
};
const
addCondition
=
(
operationId
)
=>
{
const
addCondition
=
(
operationId
)
=>
{
const
createdCondition
=
createDefaultCondition
();
setOperations
((
prev
)
=>
setOperations
((
prev
)
=>
prev
.
map
((
operation
)
=>
prev
.
map
((
operation
)
=>
operation
.
id
===
operationId
operation
.
id
===
operationId
?
{
?
{
...
operation
,
...
operation
,
conditions
:
[...(
operation
.
conditions
||
[]),
create
DefaultCondition
()
],
conditions
:
[...(
operation
.
conditions
||
[]),
create
dCondition
],
}
}
:
operation
,
:
operation
,
),
),
);
);
setExpandedConditionMap
((
prev
)
=>
({
...
prev
,
[
operationId
]:
[...(
prev
[
operationId
]
||
[]),
createdCondition
.
id
],
}));
};
};
const
updateCondition
=
(
operationId
,
conditionId
,
patch
)
=>
{
const
updateCondition
=
(
operationId
,
conditionId
,
patch
)
=>
{
...
@@ -697,8 +841,50 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -697,8 +841,50 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
};
};
}),
}),
);
);
setExpandedConditionMap
((
prev
)
=>
({
...
prev
,
[
operationId
]:
(
prev
[
operationId
]
||
[]).
filter
(
(
id
)
=>
id
!==
conditionId
,
),
}));
};
};
const
selectedConditionKeys
=
useMemo
(
()
=>
expandedConditionMap
[
selectedOperationId
]
||
[],
[
expandedConditionMap
,
selectedOperationId
],
);
const
handleConditionCollapseChange
=
useCallback
(
(
operationId
,
activeKeys
)
=>
{
const
keys
=
(
Array
.
isArray
(
activeKeys
)
?
activeKeys
:
[
activeKeys
]
).
filter
(
Boolean
);
setExpandedConditionMap
((
prev
)
=>
({
...
prev
,
[
operationId
]:
keys
,
}));
},
[],
);
const
expandAllSelectedConditions
=
useCallback
(()
=>
{
if
(
!
selectedOperationId
||
!
selectedOperation
)
return
;
setExpandedConditionMap
((
prev
)
=>
({
...
prev
,
[
selectedOperationId
]:
(
selectedOperation
.
conditions
||
[]).
map
(
(
condition
)
=>
condition
.
id
,
),
}));
},
[
selectedOperation
,
selectedOperationId
]);
const
collapseAllSelectedConditions
=
useCallback
(()
=>
{
if
(
!
selectedOperationId
)
return
;
setExpandedConditionMap
((
prev
)
=>
({
...
prev
,
[
selectedOperationId
]:
[],
}));
},
[
selectedOperationId
]);
const
handleJsonChange
=
(
nextValue
)
=>
{
const
handleJsonChange
=
(
nextValue
)
=>
{
setJsonText
(
nextValue
);
setJsonText
(
nextValue
);
const
trimmed
=
String
(
nextValue
||
''
).
trim
();
const
trimmed
=
String
(
nextValue
||
''
).
trim
();
...
@@ -761,21 +947,13 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -761,21 +947,13 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
<
Modal
<
Modal
title=
{
t
(
'参数覆盖'
)
}
title=
{
t
(
'参数覆盖'
)
}
visible=
{
visible
}
visible=
{
visible
}
width=
{
98
0
}
width=
{
112
0
}
onCancel=
{
onCancel
}
onCancel=
{
onCancel
}
onOk=
{
handleSave
}
onOk=
{
handleSave
}
okText=
{
t
(
'保存'
)
}
okText=
{
t
(
'保存'
)
}
cancelText=
{
t
(
'取消'
)
}
cancelText=
{
t
(
'取消'
)
}
>
>
<
Space
vertical
align=
'start'
spacing=
{
12
}
style=
{
{
width
:
'100%'
}
}
>
<
Space
vertical
align=
'start'
spacing=
{
12
}
style=
{
{
width
:
'100%'
}
}
>
<
Banner
fullMode=
{
false
}
type=
'info'
description=
{
t
(
'支持旧格式直接覆盖,也支持新格式 operations 条件编辑;可在可视化和 JSON 之间双向切换。'
,
)
}
/>
<
Space
wrap
>
<
Space
wrap
>
<
Button
<
Button
type=
{
editMode
===
'visual'
?
'primary'
:
'tertiary'
}
type=
{
editMode
===
'visual'
?
'primary'
:
'tertiary'
}
...
@@ -789,32 +967,24 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -789,32 +967,24 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
>
>
{
t
(
'JSON 模式'
)
}
{
t
(
'JSON 模式'
)
}
</
Button
>
</
Button
>
<
Button
onClick=
{
setOldTemplate
}
>
{
t
(
'旧格式模板'
)
}
</
Button
>
<
Select
<
Button
onClick=
{
setNewTemplate
}
>
{
t
(
'新格式模板'
)
}
</
Button
>
value=
{
templateLibraryKey
}
<
Button
onClick=
{
clearValue
}
>
{
t
(
'不更改'
)
}
</
Button
>
optionList=
{
TEMPLATE_LIBRARY_OPTIONS
}
onChange=
{
(
nextValue
)
=>
setTemplateLibraryKey
(
nextValue
||
'operations'
)
}
style=
{
{
width
:
240
}
}
/>
<
Button
onClick=
{
applyTemplateFromLibrary
}
>
{
t
(
'应用模板'
)
}
</
Button
>
<
Button
onClick=
{
resetEditorState
}
>
{
t
(
'重置'
)
}
</
Button
>
</
Space
>
</
Space
>
{
editMode
===
'visual'
?
(
{
editMode
===
'visual'
?
(
<
div
style=
{
{
width
:
'100%'
}
}
>
<
div
style=
{
{
width
:
'100%'
}
}
>
<
Space
wrap
style=
{
{
marginBottom
:
12
}
}
>
<
Button
type=
{
visualMode
===
'operations'
?
'primary'
:
'tertiary'
}
onClick=
{
()
=>
setVisualMode
(
'operations'
)
}
>
{
t
(
'新格式模板'
)
}
</
Button
>
<
Button
type=
{
visualMode
===
'legacy'
?
'primary'
:
'tertiary'
}
onClick=
{
()
=>
setVisualMode
(
'legacy'
)
}
>
{
t
(
'旧格式模板'
)
}
</
Button
>
</
Space
>
{
visualMode
===
'legacy'
?
(
{
visualMode
===
'legacy'
?
(
<
div
>
<
div
>
<
Text
className=
'mb-2 block'
>
{
t
(
'旧格式(直接覆盖):'
)
}
</
Text
>
<
Text
className=
'mb-2 block'
>
{
t
(
'旧格式(直接覆盖):'
)
}
</
Text
>
<
Input
.
TextArea
<
TextArea
value=
{
legacyValue
}
value=
{
legacyValue
}
autosize=
{
{
minRows
:
10
,
maxRows
:
20
}
}
autosize=
{
{
minRows
:
10
,
maxRows
:
20
}
}
placeholder=
{
JSON
.
stringify
(
LEGACY_TEMPLATE
,
null
,
2
)
}
placeholder=
{
JSON
.
stringify
(
LEGACY_TEMPLATE
,
null
,
2
)
}
...
@@ -830,48 +1000,190 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -830,48 +1000,190 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
<
div
className=
'flex items-center justify-between mb-3'
>
<
div
className=
'flex items-center justify-between mb-3'
>
<
Space
>
<
Space
>
<
Text
>
{
t
(
'新格式(支持条件判断与json自定义):'
)
}
</
Text
>
<
Text
>
{
t
(
'新格式(支持条件判断与json自定义):'
)
}
</
Text
>
<
Tag
color=
'cyan'
>
<
Tag
color=
'cyan'
>
{
`${t('规则')}: ${operationCount}`
}
</
Tag
>
{
`${t('规则')}: ${operationCount}`
}
</
Tag
>
</
Space
>
</
Space
>
<
Button
icon=
{
<
IconPlus
/>
}
onClick=
{
addOperation
}
>
<
Button
icon=
{
<
IconPlus
/>
}
onClick=
{
addOperation
}
>
{
t
(
'新增规则'
)
}
{
t
(
'新增规则'
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
<
Space
vertical
spacing=
{
8
}
style=
{
{
width
:
'100%'
}
}
>
<
Row
gutter=
{
12
}
>
{
operations
.
map
((
operation
,
index
)
=>
{
<
Col
xs=
{
24
}
md=
{
8
}
>
const
mode
=
operation
.
mode
||
'set'
;
<
Card
className=
'!rounded-2xl !border-0 h-full'
bodyStyle=
{
{
padding
:
12
,
background
:
'var(--semi-color-fill-0)'
,
display
:
'flex'
,
flexDirection
:
'column'
,
gap
:
10
,
minHeight
:
520
,
}
}
>
<
div
className=
'flex items-center justify-between'
>
<
Text
strong
>
{
t
(
'规则导航'
)
}
</
Text
>
<
Tag
color=
'grey'
>
{
`${operationCount}/${operations.length}`
}
</
Tag
>
</
div
>
{
topOperationModes
.
length
>
0
?
(
<
Space
wrap
spacing=
{
6
}
>
{
topOperationModes
.
map
(([
mode
,
count
])
=>
(
<
Tag
key=
{
`mode_stat_${mode}`
}
size=
'small'
color=
{
getOperationModeTagColor
(
mode
)
}
>
{
`${mode} · ${count}`
}
</
Tag
>
))
}
</
Space
>
)
:
null
}
<
Input
value=
{
operationSearch
}
placeholder=
{
t
(
'搜索规则(mode/path/from/to)'
)
}
onChange=
{
(
nextValue
)
=>
setOperationSearch
(
nextValue
||
''
)
}
showClear
/>
<
div
className=
'overflow-auto'
style=
{
{
flex
:
1
,
minHeight
:
320
,
paddingRight
:
2
}
}
>
{
filteredOperations
.
length
===
0
?
(
<
Text
type=
'tertiary'
size=
'small'
>
{
t
(
'没有匹配的规则'
)
}
</
Text
>
)
:
(
<
div
style=
{
{
display
:
'flex'
,
flexDirection
:
'column'
,
gap
:
8
,
width
:
'100%'
,
}
}
>
{
filteredOperations
.
map
((
operation
)
=>
{
const
index
=
operations
.
findIndex
(
(
item
)
=>
item
.
id
===
operation
.
id
,
);
const
isActive
=
operation
.
id
===
selectedOperationId
;
return
(
<
div
key=
{
operation
.
id
}
role=
'button'
tabIndex=
{
0
}
onClick=
{
()
=>
setSelectedOperationId
(
operation
.
id
)
}
onKeyDown=
{
(
event
)
=>
{
if
(
event
.
key
===
'Enter'
||
event
.
key
===
' '
)
{
event
.
preventDefault
();
setSelectedOperationId
(
operation
.
id
);
}
}
}
className=
'w-full rounded-xl px-3 py-3 cursor-pointer transition-colors'
style=
{
{
background
:
isActive
?
'var(--semi-color-primary-light-default)'
:
'var(--semi-color-bg-2)'
,
border
:
isActive
?
'1px solid var(--semi-color-primary)'
:
'1px solid var(--semi-color-border)'
,
}
}
>
<
div
className=
'flex items-start justify-between gap-2'
>
<
div
>
<
Text
strong
>
{
`#${index + 1}`
}
</
Text
>
<
Text
type=
'tertiary'
size=
'small'
className=
'block mt-1'
>
{
getOperationSummary
(
operation
,
index
)
}
</
Text
>
</
div
>
<
Tag
size=
'small'
color=
'grey'
>
{
(
operation
.
conditions
||
[]).
length
}
</
Tag
>
</
div
>
<
Space
spacing=
{
6
}
style=
{
{
marginTop
:
8
}
}
>
<
Tag
size=
'small'
color=
{
getOperationModeTagColor
(
operation
.
mode
||
'set'
,
)
}
>
{
operation
.
mode
||
'set'
}
</
Tag
>
<
Text
type=
'tertiary'
size=
'small'
>
{
t
(
'条件'
)
}
</
Text
>
</
Space
>
</
div
>
);
})
}
</
div
>
)
}
</
div
>
</
Card
>
</
Col
>
<
Col
xs=
{
24
}
md=
{
16
}
>
{
selectedOperation
?
(
(()
=>
{
const
mode
=
selectedOperation
.
mode
||
'set'
;
const
meta
=
MODE_META
[
mode
]
||
MODE_META
.
set
;
const
meta
=
MODE_META
[
mode
]
||
MODE_META
.
set
;
const
conditions
=
o
peration
.
conditions
||
[];
const
conditions
=
selectedO
peration
.
conditions
||
[];
const
syncFromTarget
=
const
syncFromTarget
=
mode
===
'sync_fields'
mode
===
'sync_fields'
?
parseSyncTargetSpec
(
o
peration
.
from
)
?
parseSyncTargetSpec
(
selectedO
peration
.
from
)
:
null
;
:
null
;
const
syncToTarget
=
const
syncToTarget
=
mode
===
'sync_fields'
mode
===
'sync_fields'
?
parseSyncTargetSpec
(
o
peration
.
to
)
?
parseSyncTargetSpec
(
selectedO
peration
.
to
)
:
null
;
:
null
;
return
(
return
(
<
Card
key=
{
operation
.
id
}
className=
'!rounded-xl border'
>
<
Card
<
div
className=
'flex items-center justify-between mb-2'
>
className=
'!rounded-2xl !border-0'
bodyStyle=
{
{
padding
:
14
,
background
:
'var(--semi-color-fill-0)'
,
}
}
>
<
div
className=
'flex items-center justify-between mb-3'
>
<
Space
>
<
Space
>
<
Tag
>
{
`#${index + 1}`
}
</
Tag
>
<
Tag
color=
'blue'
>
{
`#${selectedOperationIndex + 1}`
}
</
Tag
>
<
Text
>
{
mode
}
</
Text
>
<
Text
strong
>
{
getOperationSummary
(
selectedOperation
,
selectedOperationIndex
,
)
}
</
Text
>
</
Space
>
</
Space
>
<
Space
>
<
Space
>
<
Button
<
Button
size=
'small'
size=
'small'
type=
'tertiary'
type=
'tertiary'
onClick=
{
()
=>
duplicateOperation
(
operation
.
id
)
}
onClick=
{
()
=>
duplicateOperation
(
selectedOperation
.
id
)
}
>
>
{
t
(
'复制'
)
}
{
t
(
'复制'
)
}
</
Button
>
</
Button
>
<
Button
<
Button
theme=
'borderless
'
size=
'small
'
type=
'danger'
type=
'danger'
theme=
'borderless'
icon=
{
<
IconDelete
/>
}
icon=
{
<
IconDelete
/>
}
onClick=
{
()
=>
removeOperation
(
operation
.
id
)
}
onClick=
{
()
=>
removeOperation
(
selectedOperation
.
id
)
}
/>
/>
</
Space
>
</
Space
>
</
div
>
</
div
>
...
@@ -885,7 +1197,9 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -885,7 +1197,9 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
value=
{
mode
}
value=
{
mode
}
optionList=
{
OPERATION_MODE_OPTIONS
}
optionList=
{
OPERATION_MODE_OPTIONS
}
onChange=
{
(
nextMode
)
=>
onChange=
{
(
nextMode
)
=>
updateOperation
(
operation
.
id
,
{
mode
:
nextMode
})
updateOperation
(
selectedOperation
.
id
,
{
mode
:
nextMode
,
})
}
}
style=
{
{
width
:
'100%'
}
}
style=
{
{
width
:
'100%'
}
}
/>
/>
...
@@ -893,10 +1207,12 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -893,10 +1207,12 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
{
meta
.
path
||
meta
.
pathOptional
?
(
{
meta
.
path
||
meta
.
pathOptional
?
(
<
Col
xs=
{
24
}
md=
{
16
}
>
<
Col
xs=
{
24
}
md=
{
16
}
>
<
Text
type=
'tertiary'
size=
'small'
>
<
Text
type=
'tertiary'
size=
'small'
>
{
meta
.
pathOptional
?
'path (optional)'
:
'path'
}
{
meta
.
pathOptional
?
'path (optional)'
:
'path'
}
</
Text
>
</
Text
>
<
Input
<
Input
value=
{
o
peration
.
path
}
value=
{
selectedO
peration
.
path
}
placeholder=
{
placeholder=
{
mode
.
includes
(
'header'
)
mode
.
includes
(
'header'
)
?
'X-Debug-Mode'
?
'X-Debug-Mode'
...
@@ -905,32 +1221,42 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -905,32 +1221,42 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
:
'temperature'
:
'temperature'
}
}
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateOperation
(
o
peration
.
id
,
{
updateOperation
(
selectedO
peration
.
id
,
{
path
:
nextValue
,
path
:
nextValue
,
})
})
}
}
/>
/>
<
Space
wrap
style=
{
{
marginTop
:
6
}
}
>
<
Space
wrap
style=
{
{
marginTop
:
6
}
}
>
{
OPERATION_PATH_SUGGESTIONS
.
map
((
pathItem
)
=>
(
{
OPERATION_PATH_SUGGESTIONS
.
map
(
(
pathItem
)
=>
(
<
Tag
<
Tag
key=
{
`${o
peration.id}_${pathItem}`
}
key=
{
`${selectedO
peration.id}_${pathItem}`
}
size=
'small'
size=
'small'
color=
'grey'
color=
'grey'
className=
'cursor-pointer'
className=
'cursor-pointer'
onClick=
{
()
=>
onClick=
{
()
=>
updateOperation
(
operation
.
id
,
{
updateOperation
(
selectedOperation
.
id
,
{
path
:
pathItem
,
path
:
pathItem
,
})
},
)
}
}
>
>
{
pathItem
}
{
pathItem
}
</
Tag
>
</
Tag
>
))
}
),
)
}
</
Space
>
</
Space
>
</
Col
>
</
Col
>
)
:
null
}
)
:
null
}
</
Row
>
</
Row
>
<
Text
type=
'tertiary'
size=
'small'
className=
'mt-1 block'
>
<
Text
type=
'tertiary'
size=
'small'
className=
'mt-1 block'
>
{
MODE_DESCRIPTIONS
[
mode
]
||
''
}
{
MODE_DESCRIPTIONS
[
mode
]
||
''
}
</
Text
>
</
Text
>
...
@@ -939,12 +1265,12 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -939,12 +1265,12 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
<
Text
type=
'tertiary'
size=
'small'
>
<
Text
type=
'tertiary'
size=
'small'
>
value (JSON or plain text)
value (JSON or plain text)
</
Text
>
</
Text
>
<
Input
.
TextArea
<
TextArea
value=
{
o
peration
.
value_text
}
value=
{
selectedO
peration
.
value_text
}
autosize=
{
{
minRows
:
1
,
maxRows
:
4
}
}
autosize=
{
{
minRows
:
1
,
maxRows
:
4
}
}
placeholder=
'0.7'
placeholder=
'0.7'
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateOperation
(
o
peration
.
id
,
{
updateOperation
(
selectedO
peration
.
id
,
{
value_text
:
nextValue
,
value_text
:
nextValue
,
})
})
}
}
...
@@ -955,16 +1281,22 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -955,16 +1281,22 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
{
meta
.
keepOrigin
?
(
{
meta
.
keepOrigin
?
(
<
div
className=
'mt-2'
>
<
div
className=
'mt-2'
>
<
Switch
<
Switch
checked=
{
operation
.
keep_origin
}
checked=
{
Boolean
(
selectedOperation
.
keep_origin
,
)
}
checkedText=
{
t
(
'开'
)
}
checkedText=
{
t
(
'开'
)
}
uncheckedText=
{
t
(
'关'
)
}
uncheckedText=
{
t
(
'关'
)
}
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateOperation
(
o
peration
.
id
,
{
updateOperation
(
selectedO
peration
.
id
,
{
keep_origin
:
nextValue
,
keep_origin
:
nextValue
,
})
})
}
}
/>
/>
<
Text
type=
'tertiary'
size=
'small'
className=
'ml-2'
>
<
Text
type=
'tertiary'
size=
'small'
className=
'ml-2'
>
keep_origin
keep_origin
</
Text
>
</
Text
>
</
div
>
</
div
>
...
@@ -986,24 +1318,30 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -986,24 +1318,30 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
optionList=
{
SYNC_TARGET_TYPE_OPTIONS
}
optionList=
{
SYNC_TARGET_TYPE_OPTIONS
}
style=
{
{
width
:
120
}
}
style=
{
{
width
:
120
}
}
onChange=
{
(
nextType
)
=>
onChange=
{
(
nextType
)
=>
updateOperation
(
operation
.
id
,
{
updateOperation
(
selectedOperation
.
id
,
{
from
:
buildSyncTargetSpec
(
from
:
buildSyncTargetSpec
(
nextType
,
nextType
,
syncFromTarget
?.
key
||
''
,
syncFromTarget
?.
key
||
''
,
),
),
})
},
)
}
}
/>
/>
<
Input
<
Input
value=
{
syncFromTarget
?.
key
||
''
}
value=
{
syncFromTarget
?.
key
||
''
}
placeholder=
'session_id'
placeholder=
'session_id'
onChange=
{
(
nextKey
)
=>
onChange=
{
(
nextKey
)
=>
updateOperation
(
operation
.
id
,
{
updateOperation
(
selectedOperation
.
id
,
{
from
:
buildSyncTargetSpec
(
from
:
buildSyncTargetSpec
(
syncFromTarget
?.
type
||
'json'
,
syncFromTarget
?.
type
||
'json'
,
nextKey
,
nextKey
,
),
),
})
},
)
}
}
/>
/>
</
div
>
</
div
>
...
@@ -1018,24 +1356,30 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1018,24 +1356,30 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
optionList=
{
SYNC_TARGET_TYPE_OPTIONS
}
optionList=
{
SYNC_TARGET_TYPE_OPTIONS
}
style=
{
{
width
:
120
}
}
style=
{
{
width
:
120
}
}
onChange=
{
(
nextType
)
=>
onChange=
{
(
nextType
)
=>
updateOperation
(
operation
.
id
,
{
updateOperation
(
selectedOperation
.
id
,
{
to
:
buildSyncTargetSpec
(
to
:
buildSyncTargetSpec
(
nextType
,
nextType
,
syncToTarget
?.
key
||
''
,
syncToTarget
?.
key
||
''
,
),
),
})
},
)
}
}
/>
/>
<
Input
<
Input
value=
{
syncToTarget
?.
key
||
''
}
value=
{
syncToTarget
?.
key
||
''
}
placeholder=
'prompt_cache_key'
placeholder=
'prompt_cache_key'
onChange=
{
(
nextKey
)
=>
onChange=
{
(
nextKey
)
=>
updateOperation
(
operation
.
id
,
{
updateOperation
(
selectedOperation
.
id
,
{
to
:
buildSyncTargetSpec
(
to
:
buildSyncTargetSpec
(
syncToTarget
?.
type
||
'json'
,
syncToTarget
?.
type
||
'json'
,
nextKey
,
nextKey
,
),
),
})
},
)
}
}
/>
/>
</
div
>
</
div
>
...
@@ -1047,26 +1391,30 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1047,26 +1391,30 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
color=
'cyan'
color=
'cyan'
className=
'cursor-pointer'
className=
'cursor-pointer'
onClick=
{
()
=>
onClick=
{
()
=>
updateOperation
(
o
peration
.
id
,
{
updateOperation
(
selectedO
peration
.
id
,
{
from
:
'header:session_id'
,
from
:
'header:session_id'
,
to
:
'json:prompt_cache_key'
,
to
:
'json:prompt_cache_key'
,
})
})
}
}
>
>
{
'header:session_id -> json:prompt_cache_key'
}
{
'header:session_id -> json:prompt_cache_key'
}
</
Tag
>
</
Tag
>
<
Tag
<
Tag
size=
'small'
size=
'small'
color=
'cyan'
color=
'cyan'
className=
'cursor-pointer'
className=
'cursor-pointer'
onClick=
{
()
=>
onClick=
{
()
=>
updateOperation
(
o
peration
.
id
,
{
updateOperation
(
selectedO
peration
.
id
,
{
from
:
'json:prompt_cache_key'
,
from
:
'json:prompt_cache_key'
,
to
:
'header:session_id'
,
to
:
'header:session_id'
,
})
})
}
}
>
>
{
'json:prompt_cache_key -> header:session_id'
}
{
'json:prompt_cache_key -> header:session_id'
}
</
Tag
>
</
Tag
>
</
Space
>
</
Space
>
</
div
>
</
div
>
...
@@ -1078,14 +1426,14 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1078,14 +1426,14 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
from
from
</
Text
>
</
Text
>
<
Input
<
Input
value=
{
o
peration
.
from
}
value=
{
selectedO
peration
.
from
}
placeholder=
{
placeholder=
{
mode
.
includes
(
'header'
)
mode
.
includes
(
'header'
)
?
'Authorization'
?
'Authorization'
:
'model'
:
'model'
}
}
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateOperation
(
o
peration
.
id
,
{
updateOperation
(
selectedO
peration
.
id
,
{
from
:
nextValue
,
from
:
nextValue
,
})
})
}
}
...
@@ -1098,14 +1446,16 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1098,14 +1446,16 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
to
to
</
Text
>
</
Text
>
<
Input
<
Input
value=
{
o
peration
.
to
}
value=
{
selectedO
peration
.
to
}
placeholder=
{
placeholder=
{
mode
.
includes
(
'header'
)
mode
.
includes
(
'header'
)
?
'X-Upstream-Auth'
?
'X-Upstream-Auth'
:
'original_model'
:
'original_model'
}
}
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateOperation
(
operation
.
id
,
{
to
:
nextValue
})
updateOperation
(
selectedOperation
.
id
,
{
to
:
nextValue
,
})
}
}
/>
/>
</
Col
>
</
Col
>
...
@@ -1113,31 +1463,54 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1113,31 +1463,54 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
</
Row
>
</
Row
>
)
:
null
}
)
:
null
}
<
div
className=
'mt-3 border rounded-lg p-2'
>
<
div
className=
'mt-3 rounded-xl p-2'
style=
{
{
background
:
'rgba(127, 127, 127, 0.08)'
,
}
}
>
<
div
className=
'flex items-center justify-between mb-2'
>
<
div
className=
'flex items-center justify-between mb-2'
>
<
Space
>
<
Space
>
<
Text
>
{
t
(
'条件'
)
}
</
Text
>
<
Text
>
{
t
(
'条件'
)
}
</
Text
>
<
Select
<
Select
value=
{
o
peration
.
logic
||
'OR'
}
value=
{
selectedO
peration
.
logic
||
'OR'
}
optionList=
{
[
optionList=
{
[
{
label
:
'OR'
,
value
:
'OR'
},
{
label
:
'OR'
,
value
:
'OR'
},
{
label
:
'AND'
,
value
:
'AND'
},
{
label
:
'AND'
,
value
:
'AND'
},
]
}
]
}
style=
{
{
width
:
96
}
}
style=
{
{
width
:
96
}
}
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateOperation
(
o
peration
.
id
,
{
updateOperation
(
selectedO
peration
.
id
,
{
logic
:
nextValue
,
logic
:
nextValue
,
})
})
}
}
/>
/>
</
Space
>
</
Space
>
<
Space
spacing=
{
6
}
>
<
Button
size=
'small'
type=
'tertiary'
onClick=
{
expandAllSelectedConditions
}
>
{
t
(
'全部展开'
)
}
</
Button
>
<
Button
size=
'small'
type=
'tertiary'
onClick=
{
collapseAllSelectedConditions
}
>
{
t
(
'全部收起'
)
}
</
Button
>
<
Button
<
Button
icon=
{
<
IconPlus
/>
}
icon=
{
<
IconPlus
/>
}
size=
'small'
size=
'small'
onClick=
{
()
=>
addCondition
(
operation
.
id
)
}
onClick=
{
()
=>
addCondition
(
selectedOperation
.
id
)
}
>
>
{
t
(
'新增条件'
)
}
{
t
(
'新增条件'
)
}
</
Button
>
</
Button
>
</
Space
>
</
div
>
</
div
>
{
conditions
.
length
===
0
?
(
{
conditions
.
length
===
0
?
(
...
@@ -1145,28 +1518,54 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1145,28 +1518,54 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
{
t
(
'没有条件时,默认总是执行该操作。'
)
}
{
t
(
'没有条件时,默认总是执行该操作。'
)
}
</
Text
>
</
Text
>
)
:
(
)
:
(
<
Space
vertical
spacing=
{
8
}
style=
{
{
width
:
'100%'
}
}
>
<
Collapse
{
conditions
.
map
((
condition
,
conditionIndex
)
=>
(
keepDOM
<
Card
activeKey=
{
selectedConditionKeys
}
onChange=
{
(
activeKeys
)
=>
handleConditionCollapseChange
(
selectedOperation
.
id
,
activeKeys
,
)
}
>
{
conditions
.
map
(
(
condition
,
conditionIndex
)
=>
(
<
Collapse
.
Panel
key=
{
condition
.
id
}
key=
{
condition
.
id
}
bodyStyle=
{
{
padding
:
10
}
}
itemKey=
{
condition
.
id
}
className=
'!rounded-lg'
header=
{
<
Space
spacing=
{
8
}
>
<
Tag
size=
'small'
>
{
`C${conditionIndex + 1}`
}
</
Tag
>
<
Text
type=
'tertiary'
size=
'small'
>
{
condition
.
path
||
t
(
'未设置 path'
)
}
</
Text
>
</
Space
>
}
>
>
<
div
className=
'flex items-center justify-between mb-2'
>
<
div
>
<
Tag
size=
'small'
>
{
`C${conditionIndex + 1}`
}
</
Tag
>
<
div
className=
'flex justify-end mb-2'
>
<
Button
<
Button
theme=
'borderless'
theme=
'borderless'
type=
'danger'
type=
'danger'
icon=
{
<
IconDelete
/>
}
icon=
{
<
IconDelete
/>
}
size=
'small'
size=
'small'
onClick=
{
()
=>
onClick=
{
()
=>
removeCondition
(
operation
.
id
,
condition
.
id
)
removeCondition
(
selectedOperation
.
id
,
condition
.
id
,
)
}
}
/>
/>
</
div
>
</
div
>
<
Row
gutter=
{
12
}
>
<
Row
gutter=
{
12
}
>
<
Col
xs=
{
24
}
md=
{
10
}
>
<
Col
xs=
{
24
}
md=
{
10
}
>
<
Text
type=
'tertiary'
size=
'small'
>
<
Text
type=
'tertiary'
size=
'small'
>
path
path
</
Text
>
</
Text
>
<
Input
<
Input
...
@@ -1174,13 +1573,16 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1174,13 +1573,16 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
placeholder=
'model'
placeholder=
'model'
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateCondition
(
updateCondition
(
o
peration
.
id
,
selectedO
peration
.
id
,
condition
.
id
,
condition
.
id
,
{
path
:
nextValue
},
{
path
:
nextValue
},
)
)
}
}
/>
/>
<
Space
wrap
style=
{
{
marginTop
:
6
}
}
>
<
Space
wrap
style=
{
{
marginTop
:
6
}
}
>
{
CONDITION_PATH_SUGGESTIONS
.
map
(
{
CONDITION_PATH_SUGGESTIONS
.
map
(
(
pathItem
)
=>
(
(
pathItem
)
=>
(
<
Tag
<
Tag
...
@@ -1190,7 +1592,7 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1190,7 +1592,7 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
className=
'cursor-pointer'
className=
'cursor-pointer'
onClick=
{
()
=>
onClick=
{
()
=>
updateCondition
(
updateCondition
(
o
peration
.
id
,
selectedO
peration
.
id
,
condition
.
id
,
condition
.
id
,
{
path
:
pathItem
},
{
path
:
pathItem
},
)
)
...
@@ -1203,15 +1605,20 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1203,15 +1605,20 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
</
Space
>
</
Space
>
</
Col
>
</
Col
>
<
Col
xs=
{
24
}
md=
{
8
}
>
<
Col
xs=
{
24
}
md=
{
8
}
>
<
Text
type=
'tertiary'
size=
'small'
>
<
Text
type=
'tertiary'
size=
'small'
>
mode
mode
</
Text
>
</
Text
>
<
Select
<
Select
value=
{
condition
.
mode
}
value=
{
condition
.
mode
}
optionList=
{
CONDITION_MODE_OPTIONS
}
optionList=
{
CONDITION_MODE_OPTIONS
}
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateCondition
(
updateCondition
(
o
peration
.
id
,
selectedO
peration
.
id
,
condition
.
id
,
condition
.
id
,
{
mode
:
nextValue
},
{
mode
:
nextValue
},
)
)
...
@@ -1220,7 +1627,10 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1220,7 +1627,10 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
/>
/>
</
Col
>
</
Col
>
<
Col
xs=
{
24
}
md=
{
6
}
>
<
Col
xs=
{
24
}
md=
{
6
}
>
<
Text
type=
'tertiary'
size=
'small'
>
<
Text
type=
'tertiary'
size=
'small'
>
value
value
</
Text
>
</
Text
>
<
Input
<
Input
...
@@ -1228,7 +1638,7 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1228,7 +1638,7 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
placeholder=
'gpt'
placeholder=
'gpt'
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateCondition
(
updateCondition
(
o
peration
.
id
,
selectedO
peration
.
id
,
condition
.
id
,
condition
.
id
,
{
value_text
:
nextValue
},
{
value_text
:
nextValue
},
)
)
...
@@ -1238,12 +1648,14 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1238,12 +1648,14 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
</
Row
>
</
Row
>
<
Space
style=
{
{
marginTop
:
8
}
}
>
<
Space
style=
{
{
marginTop
:
8
}
}
>
<
Switch
<
Switch
checked=
{
condition
.
invert
}
checked=
{
Boolean
(
condition
.
invert
,
)
}
checkedText=
{
t
(
'开'
)
}
checkedText=
{
t
(
'开'
)
}
uncheckedText=
{
t
(
'关'
)
}
uncheckedText=
{
t
(
'关'
)
}
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateCondition
(
updateCondition
(
o
peration
.
id
,
selectedO
peration
.
id
,
condition
.
id
,
condition
.
id
,
{
invert
:
nextValue
},
{
invert
:
nextValue
},
)
)
...
@@ -1253,14 +1665,18 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1253,14 +1665,18 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
invert
invert
</
Text
>
</
Text
>
<
Switch
<
Switch
checked=
{
condition
.
pass_missing_key
}
checked=
{
Boolean
(
condition
.
pass_missing_key
,
)
}
checkedText=
{
t
(
'开'
)
}
checkedText=
{
t
(
'开'
)
}
uncheckedText=
{
t
(
'关'
)
}
uncheckedText=
{
t
(
'关'
)
}
onChange=
{
(
nextValue
)
=>
onChange=
{
(
nextValue
)
=>
updateCondition
(
updateCondition
(
o
peration
.
id
,
selectedO
peration
.
id
,
condition
.
id
,
condition
.
id
,
{
pass_missing_key
:
nextValue
},
{
pass_missing_key
:
nextValue
,
},
)
)
}
}
/>
/>
...
@@ -1268,16 +1684,37 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1268,16 +1684,37 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
pass_missing_key
pass_missing_key
</
Text
>
</
Text
>
</
Space
>
</
Space
>
</
Card
>
</
div
>
))
}
</
Collapse
.
Panel
>
</
Space
>
),
)
}
</
Collapse
>
)
}
)
}
</
div
>
</
div
>
</
Card
>
</
Card
>
);
);
})
}
})()
</
Space
>
)
:
(
<
Card
className=
'!rounded-xl border mt-3'
>
<
Card
className=
'!rounded-2xl !border-0'
bodyStyle=
{
{
padding
:
14
,
background
:
'var(--semi-color-fill-0)'
,
}
}
>
<
Text
type=
'tertiary'
>
{
t
(
'请选择一条规则进行编辑。'
)
}
</
Text
>
</
Card
>
)
}
<
Card
className=
'!rounded-2xl !border-0 mt-3'
bodyStyle=
{
{
padding
:
12
,
background
:
'var(--semi-color-fill-0)'
,
}
}
>
<
div
className=
'flex items-center justify-between mb-2'
>
<
div
className=
'flex items-center justify-between mb-2'
>
<
Text
>
{
t
(
'实时 JSON 预览'
)
}
</
Text
>
<
Text
>
{
t
(
'实时 JSON 预览'
)
}
</
Text
>
<
Tag
color=
'grey'
>
{
t
(
'预览'
)
}
</
Tag
>
<
Tag
color=
'grey'
>
{
t
(
'预览'
)
}
</
Tag
>
...
@@ -1286,6 +1723,8 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1286,6 +1723,8 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
{
visualPreview
||
'
{}
'
}
{
visualPreview
||
'
{}
'
}
</
pre
>
</
pre
>
</
Card
>
</
Card
>
</
Col
>
</
Row
>
</
div
>
</
div
>
)
}
)
}
</
div
>
</
div
>
...
@@ -1295,7 +1734,7 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
...
@@ -1295,7 +1734,7 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
<
Button
onClick=
{
formatJson
}
>
{
t
(
'格式化'
)
}
</
Button
>
<
Button
onClick=
{
formatJson
}
>
{
t
(
'格式化'
)
}
</
Button
>
<
Tag
color=
'grey'
>
{
t
(
'普通编辑'
)
}
</
Tag
>
<
Tag
color=
'grey'
>
{
t
(
'普通编辑'
)
}
</
Tag
>
</
Space
>
</
Space
>
<
Input
.
TextArea
<
TextArea
value=
{
jsonText
}
value=
{
jsonText
}
autosize=
{
{
minRows
:
18
,
maxRows
:
28
}
}
autosize=
{
{
minRows
:
18
,
maxRows
:
28
}
}
onChange=
{
(
nextValue
)
=>
handleJsonChange
(
nextValue
??
''
)
}
onChange=
{
(
nextValue
)
=>
handleJsonChange
(
nextValue
??
''
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment