diff --git a/apps/admin-web/src/components/ProxyOrderModal.tsx b/apps/admin-web/src/components/ProxyOrderModal.tsx
index 2aeccde..19d53a6 100644
--- a/apps/admin-web/src/components/ProxyOrderModal.tsx
+++ b/apps/admin-web/src/components/ProxyOrderModal.tsx
@@ -86,6 +86,22 @@ export default function ProxyOrderModal({ open, onClose, onSuccess }: ProxyOrder
.finally(() => setLoadingOptions(false));
}, [open]);
+ const selectedProduct = options?.products.find((p) => p.id === productId);
+ const allowOnline = selectedProduct ? selectedProduct.allowOnlinePurchase !== false : true;
+ const allowOnSite = !!selectedProduct?.allowOnSitePickup;
+ const allowCrossCity = selectedProduct ? selectedProduct.allowCrossCityDelivery !== false : true;
+
+ useEffect(() => {
+ if (!open || !selectedProduct) return;
+ if (!allowOnline && allowOnSite && deliveryMode !== 'ON_SITE_PICKUP') {
+ setDeliveryMode('ON_SITE_PICKUP');
+ return;
+ }
+ if (allowOnline && !allowOnSite && deliveryMode !== 'ADDRESS') {
+ setDeliveryMode('ADDRESS');
+ }
+ }, [open, selectedProduct, allowOnline, allowOnSite, deliveryMode]);
+
useEffect(() => {
if (!open || !productId || quantity < 1 || step !== 'form') {
if (step === 'form') setPreview(null);
@@ -128,7 +144,6 @@ export default function ProxyOrderModal({ open, onClose, onSuccess }: ProxyOrder
setCreated(null);
setCodeUrl(null);
setPayLoading(false);
- setMockConfirming(false);
}
function handleClose() {
@@ -140,12 +155,12 @@ export default function ProxyOrderModal({ open, onClose, onSuccess }: ProxyOrder
if (!/^1\d{10}$/.test(phone.trim())) return '请输入有效手机号';
if (!productId) return '请选择商品';
if (deliveryMode === 'ADDRESS') {
+ if (!allowOnline) return '该商品不支持线上购买';
if (!region?.province || !region?.city || !region?.district) return '请选择省市区';
if (!addressDetail.trim()) return '请填写详细地址';
if (!autoReceive) return '配送到址须勾选同意自动收货';
- } else {
- const product = options?.products.find((p) => p.id === productId);
- if (product && product.allowOnSitePickup === false) return '该商品不支持现场提货';
+ } else if (!allowOnSite) {
+ return '该商品不支持现场提货';
}
if (!preview) return '请等待费用计算完成';
return null;
@@ -329,20 +344,32 @@ export default function ProxyOrderModal({ open, onClose, onSuccess }: ProxyOrder
) : null}
- {
- setDeliveryMode(e.target.value);
- if (e.target.value !== 'ADDRESS') setAutoReceive(false);
- }}
- options={[
- { value: 'ADDRESS', label: '配送到址' },
- { value: 'ON_SITE_PICKUP', label: '现场提货' },
- ]}
- />
+ {allowOnline && allowOnSite ? (
+ {
+ setDeliveryMode(e.target.value);
+ if (e.target.value !== 'ADDRESS') setAutoReceive(false);
+ }}
+ options={[
+ { value: 'ADDRESS', label: '配送到址' },
+ { value: 'ON_SITE_PICKUP', label: '现场提货' },
+ ]}
+ />
+ ) : (
+
+ {!allowOnline && allowOnSite
+ ? '该商品仅支持现场提货'
+ : allowOnline && !allowOnSite
+ ? allowCrossCity
+ ? '该商品仅支持配送到址(含跨城)'
+ : '该商品仅支持配送到址(不可跨城)'
+ : '该商品暂无可选履约方式'}
+
+ )}
- {deliveryMode === 'ADDRESS' ? (
+ {deliveryMode === 'ADDRESS' && allowOnline ? (
<>
) {
const detail = (d.detailContent ?? {}) as ProductDetailContentDto;
+ const row = d as Row;
return {
...d,
coverUrl: (d as { mainImageUrl?: string }).mainImageUrl,
- carouselUrls: ((d as Row).carouselUrls?.length ? (d as Row).carouselUrls : ['']) as string[],
- detailImageUrls: ((d as Row).detailImageUrls?.length ? (d as Row).detailImageUrls : ['']) as string[],
- visibilityWhitelistEnabled: !!(d as Row).visibilityWhitelistEnabled,
- visibilityPhones: ((d as Row).visibilityPhones ?? []) as string[],
+ carouselUrls: (row.carouselUrls?.length ? row.carouselUrls : ['']) as string[],
+ detailImageUrls: (row.detailImageUrls?.length ? row.detailImageUrls : ['']) as string[],
+ allowOnlinePurchase: row.allowOnlinePurchase !== false,
+ allowCrossCityDelivery: row.allowOnlinePurchase === false ? false : row.allowCrossCityDelivery !== false,
+ allowOnSitePickup: !!row.allowOnSitePickup,
+ visibilityWhitelistEnabled: !!row.visibilityWhitelistEnabled,
+ visibilityPhones: (row.visibilityPhones ?? []) as string[],
storyTitle: detail.storyTitle ?? '',
storyText: detail.storyText ?? '',
features: detail.features?.length
@@ -109,7 +117,6 @@ function buildProductPayload(v: ProductFormValues) {
.filter(Boolean);
return {
- skuCode: v.skuCode,
barcode69: v.barcode69,
name: v.name,
subtitle: v.subtitle,
@@ -120,6 +127,9 @@ function buildProductPayload(v: ProductFormValues) {
status: v.status,
sortOrder: v.sortOrder,
allowOnSitePickup: !!v.allowOnSitePickup,
+ allowOnlinePurchase: v.allowOnlinePurchase !== false,
+ allowCrossCityDelivery:
+ v.allowOnlinePurchase === false ? false : v.allowCrossCityDelivery !== false,
visibilityWhitelistEnabled: !!v.visibilityWhitelistEnabled,
visibilityPhones,
coverUrl: v.coverUrl,
@@ -288,8 +298,8 @@ function BaseInfoFields({ mode, form }: { mode: 'create' | 'edit'; form: FormIns
<>
{mode === 'create' && (
<>
-
-
+
+
@@ -320,6 +330,36 @@ function BaseInfoFields({ mode, form }: { mode: 'create' | 'edit'; form: FormIns
+
+ {
+ if (!checked) form.setFieldsValue({ allowCrossCityDelivery: false });
+ }}
+ />
+
+ prev.allowOnlinePurchase !== cur.allowOnlinePurchase}>
+ {() => (
+
+
+
+ )}
+
@@ -383,10 +423,19 @@ export default function ProductsPage() {
v ? 限{row.visibilityPhones?.length ?? 0}人 : 公开,
},
{
- title: '现场取货',
- dataIndex: 'allowOnSitePickup',
- width: 90,
- render: (v: boolean) => (v ? 允许 : 否),
+ title: '履约',
+ key: 'fulfillment',
+ width: 160,
+ render: (_, row) => (
+
+ {row.allowOnlinePurchase !== false ? 线上 : null}
+ {row.allowOnlinePurchase !== false && row.allowCrossCityDelivery !== false ? (
+ 跨城
+ ) : null}
+ {row.allowOnSitePickup ? 现场 : null}
+ {row.allowOnlinePurchase === false && !row.allowOnSitePickup ? 无 : null}
+
+ ),
},
{ title: '排序', dataIndex: 'sortOrder', width: 60 },
{ title: '创建', dataIndex: 'createdAt', width: 160, render: fmtTime },
@@ -431,12 +480,16 @@ export default function ProductsPage() {
- { setPage(p); setPageSize(ps); } }} />
setDrawerOpen(false)}
extra={detail && (
setCreateOpen(false)} onOk={async () => {
const v = await createForm.validateFields();
+ if (!v.allowOnlinePurchase && !v.allowOnSitePickup) {
+ message.error('请至少勾选「允许线上购买」或「允许现场取货」之一');
+ return;
+ }
const payload = buildProductPayload(v);
await request('/admin/products', { method: 'POST', body: JSON.stringify(payload) });
message.success('已创建');
@@ -479,7 +536,8 @@ export default function ProductsPage() {
void reload();
}} width={720}>