增强供应商配置:添加网站地址字段和智能推测功能

- 添加websiteUrl可选字段到Provider类型
- 实现API地址到网站地址的自动推测逻辑(去除api.前缀)
- 在添加/编辑供应商表单中增加网站地址字段
- 供应商列表智能显示:有网址显示可点击链接,无网址显示API地址
- 提升用户体验:避免点击API端点地址导致的错误页面
This commit is contained in:
farion1231
2025-08-06 10:09:58 +08:00
parent 4540ad613f
commit 71a8fd166f
7 changed files with 126 additions and 21 deletions

View File

@@ -1,5 +1,6 @@
import React, { useState, useEffect } from 'react'
import { Provider } from '../../shared/types'
import { inferWebsiteUrl } from '../../shared/utils'
import './AddProviderModal.css'
interface EditProviderModalProps {
@@ -12,7 +13,8 @@ const EditProviderModal: React.FC<EditProviderModalProps> = ({ provider, onSave,
const [formData, setFormData] = useState({
name: provider.name,
apiUrl: provider.apiUrl,
apiKey: provider.apiKey
apiKey: provider.apiKey,
websiteUrl: provider.websiteUrl || ''
})
const [showPassword, setShowPassword] = useState(false)
@@ -20,7 +22,8 @@ const EditProviderModal: React.FC<EditProviderModalProps> = ({ provider, onSave,
setFormData({
name: provider.name,
apiUrl: provider.apiUrl,
apiKey: provider.apiKey
apiKey: provider.apiKey,
websiteUrl: provider.websiteUrl || ''
})
}, [provider])
@@ -40,10 +43,17 @@ const EditProviderModal: React.FC<EditProviderModalProps> = ({ provider, onSave,
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target
setFormData(prev => ({
...prev,
const newFormData = {
...formData,
[name]: value
}))
}
// 如果修改的是API地址自动推测网站地址
if (name === 'apiUrl') {
newFormData.websiteUrl = inferWebsiteUrl(value)
}
setFormData(newFormData)
}
return (
@@ -80,6 +90,20 @@ const EditProviderModal: React.FC<EditProviderModalProps> = ({ provider, onSave,
/>
</div>
<div className="form-group">
<label htmlFor="websiteUrl"></label>
<input
type="url"
id="websiteUrl"
name="websiteUrl"
value={formData.websiteUrl || ''}
onChange={handleChange}
placeholder="https://example.com可选"
autoComplete="off"
/>
<small className="field-hint">访API地址</small>
</div>
<div className="form-group">
<label htmlFor="apiKey">API Key *</label>
<div className="password-input-wrapper">