gbmake-payload/src/components/sync/TaobaoSyncButtons.tsx

136 lines
4.2 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 React, { useState, useEffect } from 'react'
import { useDocumentInfo } from '@payloadcms/ui'
/**
* 产品编辑页 — 淘宝信息同步按钮
*
* 放置在淘宝链接 Tab 顶部UI 字段),显示两个操作按钮:
* 🔄 更新淘宝信息 → 仅填充空字段 (force=false)
* ⚡ 强制更新淘宝信息 → 覆盖所有字段 (force=true)
*
* 依赖 APIPOST /api/admin/taobao/sync-product
*/
export const TaobaoSyncButtons: React.FC = () => {
const { id, collectionSlug } = useDocumentInfo()
const [loadingNormal, setLoadingNormal] = useState(false)
const [loadingForce, setLoadingForce] = useState(false)
const [message, setMessage] = useState<string | null>(null)
if (!id) return null // 新建文档时不显示
const isValidCollection =
collectionSlug === 'products' || collectionSlug === 'preorder-products'
if (!isValidCollection) return null
const run = async (force: boolean) => {
const setLoading = force ? setLoadingForce : setLoadingNormal
setLoading(true)
setMessage(null)
try {
const res = await fetch('/api/admin/taobao/sync-product', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ productId: id, collection: collectionSlug, force }),
})
const data = await res.json()
if (!data.success) throw new Error(data.error || '请求失败')
setMessage(`${data.message || '完成'}`)
// 刷新页面以显示更新后的字段值
setTimeout(() => window.location.reload(), 1200)
} catch (err: any) {
setMessage(`${err?.message ?? '未知错误'}`)
} finally {
setLoading(false)
}
}
const busy = loadingNormal || loadingForce
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '0.5rem',
padding: '0.75rem 1rem',
marginBottom: '1rem',
background: 'var(--theme-elevation-50)',
borderRadius: '6px',
border: '1px solid var(--theme-elevation-150)',
}}
>
<div style={{ fontSize: '0.8rem', fontWeight: 600, color: 'var(--theme-elevation-600)' }}>
</div>
<div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
{/* 更新(非强制) */}
<button
type="button"
disabled={busy}
onClick={() => run(false)}
style={{
padding: '0.4rem 0.9rem',
background: busy ? '#9ca3af' : '#3b82f6',
color: '#fff',
border: 'none',
borderRadius: '4px',
cursor: busy ? 'not-allowed' : 'pointer',
fontSize: '0.8rem',
fontWeight: 500,
whiteSpace: 'nowrap',
}}
>
{loadingNormal ? '解析中…' : '🔄 更新淘宝信息'}
</button>
{/* 强制全量更新 */}
<button
type="button"
disabled={busy}
onClick={() => run(true)}
style={{
padding: '0.4rem 0.9rem',
background: busy ? '#9ca3af' : '#f97316',
color: '#fff',
border: 'none',
borderRadius: '4px',
cursor: busy ? 'not-allowed' : 'pointer',
fontSize: '0.8rem',
fontWeight: 500,
whiteSpace: 'nowrap',
}}
>
{loadingForce ? '解析中…' : '⚡ 强制更新淘宝信息'}
</button>
</div>
{/* 说明文字 */}
<div style={{ fontSize: '0.73rem', color: 'var(--theme-elevation-450)', lineHeight: 1.5 }}>
<strong>🔄 </strong>&emsp;
<strong> </strong>
</div>
{message && (
<div
style={{
padding: '0.4rem 0.75rem',
borderRadius: '4px',
background: message.startsWith('✅') ? 'var(--theme-success-50)' : 'var(--theme-error-50)',
color: message.startsWith('✅') ? 'var(--theme-success-750)' : 'var(--theme-error-750)',
fontSize: '0.8rem',
}}
>
{message}
</div>
)}
</div>
)
}