create en
This commit is contained in:
@@ -47,11 +47,11 @@ function CreateShortUrlForm() {
|
|||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [success, setSuccess] = useState(false);
|
const [success, setSuccess] = useState(false);
|
||||||
|
|
||||||
// 使用 useEffect 在加载时添加用户信息到表单数据中
|
// Use useEffect to add user information to form data on load
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user) {
|
if (user) {
|
||||||
console.log('当前用户:', user.email);
|
console.log('Current user:', user.email);
|
||||||
// 可以在这里添加用户相关数据到表单中
|
// Can add user-related data to the form here
|
||||||
}
|
}
|
||||||
}, [user]);
|
}, [user]);
|
||||||
|
|
||||||
@@ -93,32 +93,32 @@ function CreateShortUrlForm() {
|
|||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 验证必填字段
|
// Validate required fields
|
||||||
if (!formData.originalUrl) {
|
if (!formData.originalUrl) {
|
||||||
throw new Error('原始 URL 是必填项');
|
throw new Error('Original URL is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!formData.title) {
|
if (!formData.title) {
|
||||||
throw new Error('标题是必填项');
|
throw new Error('Title is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!formData.teamId) {
|
if (!formData.teamId) {
|
||||||
throw new Error('团队是必填项');
|
throw new Error('Team is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!formData.projectId) {
|
if (!formData.projectId) {
|
||||||
throw new Error('项目是必填项');
|
throw new Error('Project is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!formData.domain) {
|
if (!formData.domain) {
|
||||||
throw new Error('域名是必填项');
|
throw new Error('Domain is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按照API要求构建请求数据
|
// Construct request data according to API requirements
|
||||||
const requestData = {
|
const requestData = {
|
||||||
type: "shorturl",
|
type: "shorturl",
|
||||||
attributes: {
|
attributes: {
|
||||||
// 可以添加任何额外属性,但attributes不能为空
|
// Can add any additional attributes, but attributes cannot be empty
|
||||||
icon: ""
|
icon: ""
|
||||||
},
|
},
|
||||||
shortUrl: {
|
shortUrl: {
|
||||||
@@ -134,20 +134,20 @@ function CreateShortUrlForm() {
|
|||||||
tagIds: formData.tags && formData.tags.length > 0 ? formData.tags : undefined
|
tagIds: formData.tags && formData.tags.length > 0 ? formData.tags : undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
// 调用 API 创建 shorturl 资源
|
// Call API to create shorturl resource
|
||||||
const response = await limqRequest('resource/shorturl', 'POST', requestData as unknown as Record<string, unknown>);
|
const response = await limqRequest('resource/shorturl', 'POST', requestData as unknown as Record<string, unknown>);
|
||||||
|
|
||||||
console.log('创建成功:', response);
|
console.log('Created successfully:', response);
|
||||||
setSuccess(true);
|
setSuccess(true);
|
||||||
|
|
||||||
// 2秒后跳转到链接列表页面
|
// Redirect to links list page after 2 seconds
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
router.push('/links');
|
router.push('/links');
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('创建短链接失败:', err);
|
console.error('Failed to create short URL:', err);
|
||||||
setError(err instanceof Error ? err.message : '创建短链接失败,请稍后重试');
|
setError(err instanceof Error ? err.message : 'Failed to create short URL, please try again later');
|
||||||
} finally {
|
} finally {
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ function CreateShortUrlForm() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="ml-3">
|
<div className="ml-3">
|
||||||
<p className="text-sm text-green-700">
|
<p className="text-sm text-green-700">
|
||||||
短链接创建成功!正在跳转...
|
Short URL created successfully! Redirecting...
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -196,10 +196,10 @@ function CreateShortUrlForm() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<form onSubmit={handleSubmit} className="p-6 space-y-6">
|
<form onSubmit={handleSubmit} className="p-6 space-y-6">
|
||||||
{/* 标题 */}
|
{/* Title */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="title" className="block text-sm font-medium text-gray-700">
|
<label htmlFor="title" className="block text-sm font-medium text-gray-700">
|
||||||
标题 <span className="text-red-500">*</span>
|
Title <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -207,16 +207,16 @@ function CreateShortUrlForm() {
|
|||||||
name="title"
|
name="title"
|
||||||
value={formData.title}
|
value={formData.title}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
placeholder="例如:产品发布活动"
|
placeholder="e.g., Product Launch Campaign"
|
||||||
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 原始 URL */}
|
{/* Original URL */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="originalUrl" className="block text-sm font-medium text-gray-700">
|
<label htmlFor="originalUrl" className="block text-sm font-medium text-gray-700">
|
||||||
原始 URL <span className="text-red-500">*</span>
|
Original URL <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="url"
|
type="url"
|
||||||
@@ -230,10 +230,10 @@ function CreateShortUrlForm() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 自定义短链接 */}
|
{/* Custom Short Link */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="customSlug" className="block text-sm font-medium text-gray-700">
|
<label htmlFor="customSlug" className="block text-sm font-medium text-gray-700">
|
||||||
自定义短链接 <span className="text-gray-500">(可选)</span>
|
Custom Short Link <span className="text-gray-500">(Optional)</span>
|
||||||
</label>
|
</label>
|
||||||
<div className="flex mt-1 rounded-md shadow-sm">
|
<div className="flex mt-1 rounded-md shadow-sm">
|
||||||
<span className="inline-flex items-center px-3 py-2 text-sm text-gray-500 border border-r-0 border-gray-300 rounded-l-md bg-gray-50">
|
<span className="inline-flex items-center px-3 py-2 text-sm text-gray-500 border border-r-0 border-gray-300 rounded-l-md bg-gray-50">
|
||||||
@@ -250,14 +250,14 @@ function CreateShortUrlForm() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-1 text-xs text-gray-500">
|
<p className="mt-1 text-xs text-gray-500">
|
||||||
留空将生成随机短链接
|
Leave blank to generate a random short link
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 域名 */}
|
{/* Domain */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="domain" className="block text-sm font-medium text-gray-700">
|
<label htmlFor="domain" className="block text-sm font-medium text-gray-700">
|
||||||
域名 <span className="text-red-500">*</span>
|
Domain <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -265,16 +265,16 @@ function CreateShortUrlForm() {
|
|||||||
name="domain"
|
name="domain"
|
||||||
value={formData.domain}
|
value={formData.domain}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
placeholder="例如:googleads.link"
|
placeholder="e.g., googleads.link"
|
||||||
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 团队选择 */}
|
{/* Team Selection */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="teamId" className="block text-sm font-medium text-gray-700">
|
<label htmlFor="teamId" className="block text-sm font-medium text-gray-700">
|
||||||
团队 <span className="text-red-500">*</span>
|
Team <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<div className="mt-1">
|
<div className="mt-1">
|
||||||
<TeamSelector
|
<TeamSelector
|
||||||
@@ -283,7 +283,7 @@ function CreateShortUrlForm() {
|
|||||||
setFormData(prev => ({
|
setFormData(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
teamId: teamId as string,
|
teamId: teamId as string,
|
||||||
// 当团队变更时清除已选项目
|
// Clear selected project when team changes
|
||||||
projectId: ''
|
projectId: ''
|
||||||
}));
|
}));
|
||||||
}}
|
}}
|
||||||
@@ -291,10 +291,10 @@ function CreateShortUrlForm() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 项目选择 */}
|
{/* Project Selection */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="projectId" className="block text-sm font-medium text-gray-700">
|
<label htmlFor="projectId" className="block text-sm font-medium text-gray-700">
|
||||||
项目 <span className="text-red-500">*</span>
|
Project <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<div className="mt-1">
|
<div className="mt-1">
|
||||||
<ProjectSelector
|
<ProjectSelector
|
||||||
@@ -310,10 +310,10 @@ function CreateShortUrlForm() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 描述 */}
|
{/* Description */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="description" className="block text-sm font-medium text-gray-700">
|
<label htmlFor="description" className="block text-sm font-medium text-gray-700">
|
||||||
描述 <span className="text-gray-500">(可选)</span>
|
Description <span className="text-gray-500">(Optional)</span>
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
id="description"
|
id="description"
|
||||||
@@ -321,15 +321,15 @@ function CreateShortUrlForm() {
|
|||||||
value={formData.description}
|
value={formData.description}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
rows={3}
|
rows={3}
|
||||||
placeholder="对此链接的简短描述"
|
placeholder="A brief description of this link"
|
||||||
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 标签 */}
|
{/* Tags */}
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="tagInput" className="block text-sm font-medium text-gray-700">
|
<label htmlFor="tagInput" className="block text-sm font-medium text-gray-700">
|
||||||
标签 <span className="text-gray-500">(可选)</span>
|
Tags <span className="text-gray-500">(Optional)</span>
|
||||||
</label>
|
</label>
|
||||||
<div className="flex mt-1 rounded-md shadow-sm">
|
<div className="flex mt-1 rounded-md shadow-sm">
|
||||||
<input
|
<input
|
||||||
@@ -338,7 +338,7 @@ function CreateShortUrlForm() {
|
|||||||
value={tagInput}
|
value={tagInput}
|
||||||
onChange={(e) => setTagInput(e.target.value)}
|
onChange={(e) => setTagInput(e.target.value)}
|
||||||
onKeyDown={handleTagKeyDown}
|
onKeyDown={handleTagKeyDown}
|
||||||
placeholder="添加标签并按 Enter"
|
placeholder="Add a tag and press Enter"
|
||||||
className="flex-1 block w-full min-w-0 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
className="flex-1 block w-full min-w-0 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
@@ -346,7 +346,7 @@ function CreateShortUrlForm() {
|
|||||||
onClick={addTag}
|
onClick={addTag}
|
||||||
className="inline-flex items-center px-3 py-2 text-sm font-medium text-white border border-transparent rounded-r-md shadow-sm bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
className="inline-flex items-center px-3 py-2 text-sm font-medium text-white border border-transparent rounded-r-md shadow-sm bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||||
>
|
>
|
||||||
添加
|
Add
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -360,7 +360,7 @@ function CreateShortUrlForm() {
|
|||||||
onClick={() => removeTag(tag)}
|
onClick={() => removeTag(tag)}
|
||||||
className="flex-shrink-0 ml-1 text-blue-500 rounded-full hover:text-blue-700 focus:outline-none"
|
className="flex-shrink-0 ml-1 text-blue-500 rounded-full hover:text-blue-700 focus:outline-none"
|
||||||
>
|
>
|
||||||
<span className="sr-only">删除标签 {tag}</span>
|
<span className="sr-only">Remove tag {tag}</span>
|
||||||
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
|
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
|
||||||
</svg>
|
</svg>
|
||||||
@@ -371,14 +371,14 @@ function CreateShortUrlForm() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 提交按钮 */}
|
{/* Submit Button */}
|
||||||
<div className="flex justify-end pt-4 border-t border-gray-200">
|
<div className="flex justify-end pt-4 border-t border-gray-200">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => router.back()}
|
onClick={() => router.back()}
|
||||||
className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 mr-3"
|
className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 mr-3"
|
||||||
>
|
>
|
||||||
取消
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -391,9 +391,9 @@ function CreateShortUrlForm() {
|
|||||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
处理中...
|
Processing...
|
||||||
</>
|
</>
|
||||||
) : '创建短链接'}
|
) : 'Create Short URL'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Reference in New Issue
Block a user