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:
@@ -2,13 +2,22 @@ import { useEffect, useState } from 'react';
|
||||
import { Alert, Button, Form, Input, InputNumber, Modal, Space, Typography, message } from 'antd';
|
||||
import { DownOutlined, UpOutlined } from '@ant-design/icons';
|
||||
import type { StorePackageItemDto } from '@dukang/shared-types';
|
||||
import { STORE_PACKAGE_MAX_COUNT } from '@dukang/shared-types';
|
||||
import { STORE_PACKAGE_IMAGE_MAX_COUNT, STORE_PACKAGE_MAX_COUNT, normalizeStorePackageImageUrls } from '@dukang/shared-types';
|
||||
import { request } from '../lib/api';
|
||||
import OssUpload from './OssUpload';
|
||||
import PackageImagesUpload from './PackageImagesUpload';
|
||||
type PackageRow = StorePackageItemDto;
|
||||
|
||||
function emptyRow(index = 0): PackageRow {
|
||||
return { name: '', price: '0', dishes: '', usableTime: '', otherNotes: '', imageUrl: '', sortOrder: index };
|
||||
return {
|
||||
name: '',
|
||||
price: '0',
|
||||
dishes: '',
|
||||
usableTime: '',
|
||||
otherNotes: '',
|
||||
imageUrl: '',
|
||||
imageUrls: [],
|
||||
sortOrder: index,
|
||||
};
|
||||
}
|
||||
|
||||
export default function AdminStorePackagesSection({ storeId }: { storeId: string }) {
|
||||
@@ -23,7 +32,16 @@ export default function AdminStorePackagesSection({ storeId }: { storeId: string
|
||||
.then((data) => {
|
||||
setItems(
|
||||
data.live?.length
|
||||
? data.live.map((p, i) => ({ ...p, price: String(p.price), sortOrder: i }))
|
||||
? data.live.map((p, i) => {
|
||||
const imageUrls = normalizeStorePackageImageUrls(p);
|
||||
return {
|
||||
...p,
|
||||
price: String(p.price),
|
||||
imageUrl: imageUrls[0] ?? '',
|
||||
imageUrls,
|
||||
sortOrder: i,
|
||||
};
|
||||
})
|
||||
: [emptyRow()],
|
||||
);
|
||||
})
|
||||
@@ -74,16 +92,20 @@ export default function AdminStorePackagesSection({ storeId }: { storeId: string
|
||||
|
||||
async function save() {
|
||||
const filled = items
|
||||
.map((item, index) => ({
|
||||
name: item.name.trim(),
|
||||
price: item.price.trim(),
|
||||
dishes: item.dishes.trim(),
|
||||
usableTime: item.usableTime?.trim() || null,
|
||||
otherNotes: item.otherNotes?.trim() || null,
|
||||
imageUrl: item.imageUrl?.trim() || null,
|
||||
sortOrder: index,
|
||||
}))
|
||||
.filter((item) => item.name || item.dishes || item.price);
|
||||
.map((item, index) => {
|
||||
const imageUrls = normalizeStorePackageImageUrls(item);
|
||||
return {
|
||||
name: item.name.trim(),
|
||||
price: item.price.trim(),
|
||||
dishes: item.dishes.trim(),
|
||||
usableTime: item.usableTime?.trim() || null,
|
||||
otherNotes: item.otherNotes?.trim() || null,
|
||||
imageUrl: imageUrls[0] ?? null,
|
||||
imageUrls: imageUrls.length ? imageUrls : null,
|
||||
sortOrder: index,
|
||||
};
|
||||
})
|
||||
.filter((item) => item.name || item.dishes || item.price || (item.imageUrls?.length ?? 0) > 0);
|
||||
|
||||
for (let i = 0; i < filled.length; i++) {
|
||||
const item = filled[i];
|
||||
@@ -100,6 +122,10 @@ export default function AdminStorePackagesSection({ storeId }: { storeId: string
|
||||
message.warning(`第 ${i + 1} 条套餐价格须为非负数字`);
|
||||
return;
|
||||
}
|
||||
if ((item.imageUrls?.length ?? 0) > STORE_PACKAGE_IMAGE_MAX_COUNT) {
|
||||
message.warning(`第 ${i + 1} 条套餐图片最多 ${STORE_PACKAGE_IMAGE_MAX_COUNT} 张`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setSaving(true);
|
||||
@@ -215,11 +241,14 @@ export default function AdminStorePackagesSection({ storeId }: { storeId: string
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="套餐图片" style={{ marginBottom: 12 }}>
|
||||
<OssUpload
|
||||
bizType="STORE_PACKAGE"
|
||||
mediaType="IMAGE"
|
||||
value={item.imageUrl || undefined}
|
||||
onChange={(url) => updateAt(index, { imageUrl: url })}
|
||||
<PackageImagesUpload
|
||||
value={normalizeStorePackageImageUrls(item)}
|
||||
onChange={(imageUrls) =>
|
||||
updateAt(index, {
|
||||
imageUrls,
|
||||
imageUrl: imageUrls[0] ?? '',
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user