Skip to content

Commit 92a4e88

Browse files
authored
Merge pull request #1844 from JoeyLearnsToCode/feat-channel-block-edit
feat: Add navigation buttons for channel edit form sections
2 parents 9e68286 + e904359 commit 92a4e88

File tree

1 file changed

+132
-20
lines changed

1 file changed

+132
-20
lines changed

web/src/components/table/channels/modals/EditChannelModal.jsx

Lines changed: 132 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ import {
6868
IconCode,
6969
IconGlobe,
7070
IconBolt,
71+
IconChevronUp,
72+
IconChevronDown,
7173
} from '@douyinfe/semi-icons';
7274

7375
const { Text, Title } = Typography;
@@ -206,6 +208,27 @@ const EditChannelModal = (props) => {
206208
keyData: '',
207209
});
208210

211+
// 专门的2FA验证状态(用于TwoFactorAuthModal)
212+
const [show2FAVerifyModal, setShow2FAVerifyModal] = useState(false);
213+
const [verifyCode, setVerifyCode] = useState('');
214+
const [verifyLoading, setVerifyLoading] = useState(false);
215+
216+
// 表单块导航相关状态
217+
const formSectionRefs = useRef({
218+
basicInfo: null,
219+
apiConfig: null,
220+
modelConfig: null,
221+
advancedSettings: null,
222+
channelExtraSettings: null,
223+
});
224+
const [currentSectionIndex, setCurrentSectionIndex] = useState(0);
225+
const formSections = ['basicInfo', 'apiConfig', 'modelConfig', 'advancedSettings', 'channelExtraSettings'];
226+
const formContainerRef = useRef(null);
227+
228+
// 2FA状态更新辅助函数
229+
const updateTwoFAState = (updates) => {
230+
setTwoFAState((prev) => ({ ...prev, ...updates }));
231+
};
209232
// 使用通用安全验证 Hook
210233
const {
211234
isModalVisible,
@@ -245,6 +268,44 @@ const EditChannelModal = (props) => {
245268
});
246269
};
247270

271+
// 重置2FA验证状态
272+
const reset2FAVerifyState = () => {
273+
setShow2FAVerifyModal(false);
274+
setVerifyCode('');
275+
setVerifyLoading(false);
276+
};
277+
278+
// 表单导航功能
279+
const scrollToSection = (sectionKey) => {
280+
const sectionElement = formSectionRefs.current[sectionKey];
281+
if (sectionElement) {
282+
sectionElement.scrollIntoView({
283+
behavior: 'smooth',
284+
block: 'start',
285+
inline: 'nearest'
286+
});
287+
}
288+
};
289+
290+
const navigateToSection = (direction) => {
291+
const availableSections = formSections.filter(section => {
292+
if (section === 'apiConfig') {
293+
return showApiConfigCard;
294+
}
295+
return true;
296+
});
297+
298+
let newIndex;
299+
if (direction === 'up') {
300+
newIndex = currentSectionIndex > 0 ? currentSectionIndex - 1 : availableSections.length - 1;
301+
} else {
302+
newIndex = currentSectionIndex < availableSections.length - 1 ? currentSectionIndex + 1 : 0;
303+
}
304+
305+
setCurrentSectionIndex(newIndex);
306+
scrollToSection(availableSections[newIndex]);
307+
};
308+
248309
// 渠道额外设置状态
249310
const [channelSettings, setChannelSettings] = useState({
250311
force_format: false,
@@ -729,6 +790,8 @@ const EditChannelModal = (props) => {
729790
fetchModelGroups();
730791
// 重置手动输入模式状态
731792
setUseManualInput(false);
793+
// 重置导航状态
794+
setCurrentSectionIndex(0);
732795
} else {
733796
// 统一的模态框关闭重置逻辑
734797
resetModalState();
@@ -1270,7 +1333,41 @@ const EditChannelModal = (props) => {
12701333
visible={props.visible}
12711334
width={isMobile ? '100%' : 600}
12721335
footer={
1273-
<div className='flex justify-end bg-white'>
1336+
<div className='flex justify-between items-center bg-white'>
1337+
<div className='flex gap-2'>
1338+
<Button
1339+
size='small'
1340+
type='tertiary'
1341+
icon={<IconChevronUp />}
1342+
onClick={() => navigateToSection('up')}
1343+
style={{
1344+
borderRadius: '50%',
1345+
width: '32px',
1346+
height: '32px',
1347+
padding: 0,
1348+
display: 'flex',
1349+
alignItems: 'center',
1350+
justifyContent: 'center'
1351+
}}
1352+
title={t('上一个表单块')}
1353+
/>
1354+
<Button
1355+
size='small'
1356+
type='tertiary'
1357+
icon={<IconChevronDown />}
1358+
onClick={() => navigateToSection('down')}
1359+
style={{
1360+
borderRadius: '50%',
1361+
width: '32px',
1362+
height: '32px',
1363+
padding: 0,
1364+
display: 'flex',
1365+
alignItems: 'center',
1366+
justifyContent: 'center'
1367+
}}
1368+
title={t('下一个表单块')}
1369+
/>
1370+
</div>
12741371
<Space>
12751372
<Button
12761373
theme='solid'
@@ -1301,10 +1398,14 @@ const EditChannelModal = (props) => {
13011398
>
13021399
{() => (
13031400
<Spin spinning={loading}>
1304-
<div className='p-2'>
1305-
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
1306-
{/* Header: Basic Info */}
1307-
<div className='flex items-center mb-2'>
1401+
<div
1402+
className='p-2'
1403+
ref={formContainerRef}
1404+
>
1405+
<div ref={el => formSectionRefs.current.basicInfo = el}>
1406+
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
1407+
{/* Header: Basic Info */}
1408+
<div className='flex items-center mb-2'>
13081409
<Avatar
13091410
size='small'
13101411
color='blue'
@@ -1778,13 +1879,15 @@ const EditChannelModal = (props) => {
17781879
}
17791880
/>
17801881
)}
1781-
</Card>
1882+
</Card>
1883+
</div>
17821884

17831885
{/* API Configuration Card */}
17841886
{showApiConfigCard && (
1785-
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
1786-
{/* Header: API Config */}
1787-
<div className='flex items-center mb-2'>
1887+
<div ref={el => formSectionRefs.current.apiConfig = el}>
1888+
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
1889+
{/* Header: API Config */}
1890+
<div className='flex items-center mb-2'>
17881891
<Avatar
17891892
size='small'
17901893
color='green'
@@ -1995,13 +2098,15 @@ const EditChannelModal = (props) => {
19952098
/>
19962099
</div>
19972100
)}
1998-
</Card>
2101+
</Card>
2102+
</div>
19992103
)}
20002104

20012105
{/* Model Configuration Card */}
2002-
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
2003-
{/* Header: Model Config */}
2004-
<div className='flex items-center mb-2'>
2106+
<div ref={el => formSectionRefs.current.modelConfig = el}>
2107+
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
2108+
{/* Header: Model Config */}
2109+
<div className='flex items-center mb-2'>
20052110
<Avatar
20062111
size='small'
20072112
color='purple'
@@ -2196,12 +2301,14 @@ const EditChannelModal = (props) => {
21962301
formApi={formApiRef.current}
21972302
extraText={t('键为请求中的模型名称,值为要替换的模型名称')}
21982303
/>
2199-
</Card>
2304+
</Card>
2305+
</div>
22002306

22012307
{/* Advanced Settings Card */}
2202-
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
2203-
{/* Header: Advanced Settings */}
2204-
<div className='flex items-center mb-2'>
2308+
<div ref={el => formSectionRefs.current.advancedSettings = el}>
2309+
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
2310+
{/* Header: Advanced Settings */}
2311+
<div className='flex items-center mb-2'>
22052312
<Avatar
22062313
size='small'
22072314
color='orange'
@@ -2414,6 +2521,8 @@ const EditChannelModal = (props) => {
24142521
'键为原状态码,值为要复写的状态码,仅影响本地判断',
24152522
)}
24162523
/>
2524+
</Card>
2525+
</div>
24172526

24182527
{/* 字段透传控制 - OpenAI 渠道 */}
24192528
{inputs.type === 1 && (
@@ -2487,9 +2596,10 @@ const EditChannelModal = (props) => {
24872596
</Card>
24882597

24892598
{/* Channel Extra Settings Card */}
2490-
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
2491-
{/* Header: Channel Extra Settings */}
2492-
<div className='flex items-center mb-2'>
2599+
<div ref={el => formSectionRefs.current.channelExtraSettings = el}>
2600+
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
2601+
{/* Header: Channel Extra Settings */}
2602+
<div className='flex items-center mb-2'>
24932603
<Avatar
24942604
size='small'
24952605
color='violet'
@@ -2587,6 +2697,8 @@ const EditChannelModal = (props) => {
25872697
'如果用户请求中包含系统提示词,则使用此设置拼接到用户的系统提示词前面',
25882698
)}
25892699
/>
2700+
</Card>
2701+
</div>
25902702

25912703
</Card>
25922704
</div>

0 commit comments

Comments
 (0)