feat(v3.4.15): HQ store media edit and package images up to 20
Allow HQ to replace/delete store photos; support multi-image packages with a 20-image cap. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { Button, Image, Space, Typography } from 'antd';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { STORE_PACKAGE_IMAGE_MAX_COUNT } from '@dukang/shared-types';
|
||||
import OssUpload from './OssUpload';
|
||||
|
||||
type Props = {
|
||||
value?: string[];
|
||||
onChange?: (urls: string[]) => void;
|
||||
};
|
||||
|
||||
/** 套餐多图上传:最多 STORE_PACKAGE_IMAGE_MAX_COUNT 张,支持替换与删除 */
|
||||
export default function PackageImagesUpload({ value, onChange }: Props) {
|
||||
const urls = (value ?? []).map((u) => String(u || '').trim()).filter(Boolean);
|
||||
|
||||
function updateAt(index: number, url: string) {
|
||||
const next = [...urls];
|
||||
const trimmed = url.trim();
|
||||
if (!trimmed) {
|
||||
next.splice(index, 1);
|
||||
} else {
|
||||
next[index] = trimmed;
|
||||
}
|
||||
onChange?.(next);
|
||||
}
|
||||
|
||||
function removeAt(index: number) {
|
||||
onChange?.(urls.filter((_, i) => i !== index));
|
||||
}
|
||||
|
||||
function addSlot() {
|
||||
if (urls.length >= STORE_PACKAGE_IMAGE_MAX_COUNT) return;
|
||||
onChange?.([...urls, '']);
|
||||
}
|
||||
|
||||
const slots = urls.length ? urls : [''];
|
||||
|
||||
return (
|
||||
<Space direction="vertical" style={{ width: '100%' }} size="middle">
|
||||
<Typography.Text type="secondary">
|
||||
最多 {STORE_PACKAGE_IMAGE_MAX_COUNT} 张,可替换或删除
|
||||
</Typography.Text>
|
||||
{slots.map((url, index) => (
|
||||
<div key={`${index}-${url || 'empty'}`} style={{ display: 'flex', gap: 8, alignItems: 'flex-start' }}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<OssUpload
|
||||
bizType="STORE_PACKAGE"
|
||||
mediaType="IMAGE"
|
||||
value={url || undefined}
|
||||
onChange={(next) => updateAt(index, next)}
|
||||
/>
|
||||
</div>
|
||||
{(urls.length > 0 || url) && (
|
||||
<Button type="link" danger onClick={() => removeAt(index)} style={{ marginTop: 8 }}>
|
||||
删除
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{urls.length < STORE_PACKAGE_IMAGE_MAX_COUNT ? (
|
||||
<Button type="dashed" icon={<PlusOutlined />} onClick={addSlot} block>
|
||||
添加图片({urls.filter(Boolean).length}/{STORE_PACKAGE_IMAGE_MAX_COUNT})
|
||||
</Button>
|
||||
) : null}
|
||||
{urls.length > 1 ? (
|
||||
<Image.PreviewGroup>
|
||||
<Space wrap size={8}>
|
||||
{urls.map((u) => (
|
||||
<Image key={u} src={u} width={64} height={64} style={{ objectFit: 'cover', borderRadius: 4 }} />
|
||||
))}
|
||||
</Space>
|
||||
</Image.PreviewGroup>
|
||||
) : null}
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user