修复URL推测功能:支持不完整URL输入并保持验证
- 修复inferWebsiteUrl函数,支持无协议URL的推测 - 在API地址失焦时自动补全https://协议 - 同时更新API地址和网站地址字段 - 保持URL输入验证,确保API地址有效性 - 提升用户体验:用户可输入api.example.com等简化格式
This commit is contained in:
@@ -43,6 +43,24 @@ const AddProviderModal: React.FC<AddProviderModalProps> = ({ onAdd, onClose }) =
|
|||||||
setFormData(newFormData)
|
setFormData(newFormData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleApiUrlBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
||||||
|
const apiUrl = e.target.value.trim()
|
||||||
|
if (apiUrl) {
|
||||||
|
let normalizedApiUrl = apiUrl
|
||||||
|
|
||||||
|
// 如果没有协议,添加 https://
|
||||||
|
if (!normalizedApiUrl.match(/^https?:\/\//)) {
|
||||||
|
normalizedApiUrl = 'https://' + normalizedApiUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
apiUrl: normalizedApiUrl,
|
||||||
|
websiteUrl: inferWebsiteUrl(normalizedApiUrl)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 预设的供应商配置
|
// 预设的供应商配置
|
||||||
const presets = [
|
const presets = [
|
||||||
{
|
{
|
||||||
@@ -109,6 +127,7 @@ const AddProviderModal: React.FC<AddProviderModalProps> = ({ onAdd, onClose }) =
|
|||||||
name="apiUrl"
|
name="apiUrl"
|
||||||
value={formData.apiUrl}
|
value={formData.apiUrl}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
onBlur={handleApiUrlBlur}
|
||||||
placeholder="https://api.anthropic.com"
|
placeholder="https://api.anthropic.com"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
@@ -117,7 +136,7 @@ const AddProviderModal: React.FC<AddProviderModalProps> = ({ onAdd, onClose }) =
|
|||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="websiteUrl">网站地址</label>
|
<label htmlFor="websiteUrl">网站地址</label>
|
||||||
<input
|
<input
|
||||||
type="url"
|
type="text"
|
||||||
id="websiteUrl"
|
id="websiteUrl"
|
||||||
name="websiteUrl"
|
name="websiteUrl"
|
||||||
value={formData.websiteUrl}
|
value={formData.websiteUrl}
|
||||||
|
|||||||
@@ -56,6 +56,24 @@ const EditProviderModal: React.FC<EditProviderModalProps> = ({ provider, onSave,
|
|||||||
setFormData(newFormData)
|
setFormData(newFormData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleApiUrlBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
||||||
|
const apiUrl = e.target.value.trim()
|
||||||
|
if (apiUrl) {
|
||||||
|
let normalizedApiUrl = apiUrl
|
||||||
|
|
||||||
|
// 如果没有协议,添加 https://
|
||||||
|
if (!normalizedApiUrl.match(/^https?:\/\//)) {
|
||||||
|
normalizedApiUrl = 'https://' + normalizedApiUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
apiUrl: normalizedApiUrl,
|
||||||
|
websiteUrl: inferWebsiteUrl(normalizedApiUrl)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="modal-overlay" onClick={onClose}>
|
<div className="modal-overlay" onClick={onClose}>
|
||||||
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
||||||
@@ -84,6 +102,7 @@ const EditProviderModal: React.FC<EditProviderModalProps> = ({ provider, onSave,
|
|||||||
name="apiUrl"
|
name="apiUrl"
|
||||||
value={formData.apiUrl || ''}
|
value={formData.apiUrl || ''}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
onBlur={handleApiUrlBlur}
|
||||||
placeholder="https://api.anthropic.com"
|
placeholder="https://api.anthropic.com"
|
||||||
required
|
required
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
@@ -93,7 +112,7 @@ const EditProviderModal: React.FC<EditProviderModalProps> = ({ provider, onSave,
|
|||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="websiteUrl">网站地址</label>
|
<label htmlFor="websiteUrl">网站地址</label>
|
||||||
<input
|
<input
|
||||||
type="url"
|
type="text"
|
||||||
id="websiteUrl"
|
id="websiteUrl"
|
||||||
name="websiteUrl"
|
name="websiteUrl"
|
||||||
value={formData.websiteUrl || ''}
|
value={formData.websiteUrl || ''}
|
||||||
|
|||||||
@@ -8,8 +8,15 @@ export function inferWebsiteUrl(apiUrl: string): string {
|
|||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let urlString = apiUrl.trim()
|
||||||
|
|
||||||
|
// 如果没有协议,默认添加 https://
|
||||||
|
if (!urlString.match(/^https?:\/\//)) {
|
||||||
|
urlString = 'https://' + urlString
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = new URL(apiUrl.trim())
|
const url = new URL(urlString)
|
||||||
|
|
||||||
// 如果是localhost或IP地址,去掉路径部分
|
// 如果是localhost或IP地址,去掉路径部分
|
||||||
if (url.hostname === 'localhost' || /^\d+\.\d+\.\d+\.\d+$/.test(url.hostname)) {
|
if (url.hostname === 'localhost' || /^\d+\.\d+\.\d+\.\d+$/.test(url.hostname)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user