feat: 开发采集、采集箱和商品编辑功能
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { Checkbox, Empty, Image, Space, Tag, Typography } from 'antd';
|
||||
import { ProductAsset, ProductDetail } from '@/services/product';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
const GROUP_NAME: Record<string, string> = {
|
||||
main: '主图',
|
||||
sku: 'SKU 图',
|
||||
detail: '详情图',
|
||||
video: '视频',
|
||||
param: '参数图',
|
||||
generated: '生成图',
|
||||
};
|
||||
|
||||
const STATUS_TAG: Record<string, { color: string; text: string }> = {
|
||||
pending: { color: 'default', text: '待下载' },
|
||||
downloading: { color: 'processing', text: '下载中' },
|
||||
uploaded: { color: 'green', text: '已就绪' },
|
||||
failed: { color: 'red', text: '失败' },
|
||||
};
|
||||
|
||||
interface Props {
|
||||
assets: ProductAsset[];
|
||||
product: ProductDetail;
|
||||
onSave: (p: Partial<ProductDetail>) => void;
|
||||
onRefresh: () => void;
|
||||
}
|
||||
|
||||
export default function ImagePanel({ assets, product, onSave }: Props) {
|
||||
const selected = (product.images ?? []) as string[];
|
||||
|
||||
const toggle = (url: string) => {
|
||||
const next = selected.includes(url) ? selected.filter((u) => u !== url) : [...selected, url];
|
||||
onSave({ images: next });
|
||||
};
|
||||
|
||||
const groups = [...new Set(assets.map((a) => a.group_key))];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Text type="secondary">勾选图片加入发布主图(images 数组,顺序即 Ozon 展示顺序)。</Text>
|
||||
{groups.length === 0 && <Empty description="暂无素材" />}
|
||||
{groups.map((g) => (
|
||||
<div key={g} style={{ marginTop: 16 }}>
|
||||
<Text strong>{GROUP_NAME[g] ?? g}</Text>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, marginTop: 8 }}>
|
||||
{assets
|
||||
.filter((a) => a.group_key === g)
|
||||
.map((a) => {
|
||||
const url = a.stored_url || a.source_url;
|
||||
const tag = STATUS_TAG[a.status] ?? STATUS_TAG.pending;
|
||||
const usable = a.status === 'uploaded';
|
||||
return (
|
||||
<div key={a.id} style={{ width: 140 }}>
|
||||
<Image
|
||||
src={url}
|
||||
width={140}
|
||||
height={140}
|
||||
style={{ objectFit: 'cover', borderRadius: 6 }}
|
||||
fallback="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><rect width='140' height='140' fill='%23eee'/><text x='20' y='70' font-size='12' fill='%23999'>无预览</text></svg>"
|
||||
/>
|
||||
<Space direction="vertical" size={2} style={{ marginTop: 6, width: '100%' }}>
|
||||
<Tag color={tag.color}>{tag.text}</Tag>
|
||||
{a.variant_name && <Text ellipsis style={{ fontSize: 12 }}>{a.variant_name}</Text>}
|
||||
{usable && a.stored_url && (
|
||||
<Checkbox
|
||||
checked={selected.includes(a.stored_url)}
|
||||
onChange={() => toggle(a.stored_url!)}
|
||||
>
|
||||
加入主图
|
||||
</Checkbox>
|
||||
)}
|
||||
</Space>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user