gbmake-payload/src/components/fields/TaobaoFetchButton.tsx

86 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { useField, useFormFields } from '@payloadcms/ui'
import React, { useState } from 'react'
/**
* 淘宝自动解析按钮
* 放置在 taobaoLinks 数组项内,读取当前 url 字段,
* 调用 /api/taobao/parse 获取标题 / 封面 / 价格,
* 然后自动填入同一数组项的对应字段。
*
* 使用方式TaobaoLinksField.ts 的 UI 字段):
* { type: 'ui', name: 'fetchButton', admin: { components: { Field: '/components/fields/TaobaoFetchButton#TaobaoFetchButton' } } }
*/
export const TaobaoFetchButton: React.FC<{ path?: string }> = ({ path = '' }) => {
const [loading, setLoading] = useState(false)
const [message, setMessage] = useState<string | null>(null)
// path 例如 "taobaoLinks.0.fetchButton",取前缀 "taobaoLinks.0."
const prefix = path.replace(/[^.]+$/, '')
const { value: url } = useField<string>({ path: `${prefix}url` })
const { setValue: setTitle } = useField<string>({ path: `${prefix}title` })
const { setValue: setThumbnail } = useField<string>({ path: `${prefix}thumbnail` })
const { setValue: setPrice } = useField<number>({ path: `${prefix}price` })
const handleFetch = async () => {
if (!url) {
setMessage('请先填写淘宝链接')
return
}
setLoading(true)
setMessage(null)
try {
const res = await fetch('/api/taobao/parse', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url }),
})
const data = await res.json()
if (!data.success) throw new Error(data.error || '解析失败')
if (data.title) setTitle(data.title)
if (data.thumbnail) setThumbnail(data.thumbnail)
if (data.price != null) setPrice(data.price)
const filled = [data.title && '标题', data.thumbnail && '封面', data.price != null && '价格']
.filter(Boolean)
.join('、')
setMessage(filled ? `✅ 已填入:${filled}` : '⚠️ 未能解析到内容')
} catch (err: any) {
setMessage(`${err?.message ?? '请求失败'}`)
} finally {
setLoading(false)
}
}
return (
<div style={{ marginTop: '0.5rem', display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
<button
type="button"
onClick={handleFetch}
disabled={loading || !url}
style={{
padding: '0.4rem 0.9rem',
background: loading ? '#9ca3af' : '#f97316',
color: '#fff',
border: 'none',
borderRadius: '4px',
cursor: loading || !url ? 'not-allowed' : 'pointer',
fontSize: '0.8rem',
fontWeight: 500,
whiteSpace: 'nowrap',
}}
>
{loading ? '解析中…' : '🔍 自动解析'}
</button>
{message && (
<span style={{ fontSize: '0.78rem', color: message.startsWith('✅') ? '#16a34a' : '#dc2626' }}>
{message}
</span>
)}
</div>
)
}