fix: 少量关于产品和订单的修改 #47

Merged
zksu merged 6 commits from zksu/WEB:main into main 2026-01-22 07:14:44 +00:00
11 changed files with 157 additions and 567 deletions
Showing only changes of commit d78b587035 - Show all commits

View File

@ -4,8 +4,8 @@ import {
ActionType,
DrawerForm,
ProForm,
ProFormSelect,
ProFormDateRangePicker,
ProFormSelect,
} from '@ant-design/pro-components';
import { Button } from 'antd';
import dayjs from 'dayjs';
@ -24,7 +24,12 @@ interface SyncFormProps {
* @param {SyncFormProps} props
* @returns {React.ReactElement}
*/
const SyncForm: React.FC<SyncFormProps> = ({ tableRef, onFinish, siteId, dateRange }) => {
const SyncForm: React.FC<SyncFormProps> = ({
tableRef,
onFinish,
siteId,
dateRange,
}) => {
// 使用 antd 的 App 组件提供的 message API
const [loading, setLoading] = React.useState(false);
@ -52,11 +57,10 @@ const SyncForm: React.FC<SyncFormProps> = ({ tableRef, onFinish, siteId, dateRan
// 返回一个抽屉表单
return (
<DrawerForm<API.ordercontrollerSyncorderParams>
initialValues={{
dateRange: [dayjs().subtract(1, 'week'), dayjs()],
}}
title="同步订单"
initialValues={{
dateRange: [dayjs().subtract(1, 'week'), dayjs()],
}}
title="同步订单"
// 表单的触发器,一个带图标的按钮
trigger={
<Button key="syncSite" type="primary">
@ -74,7 +78,6 @@ const SyncForm: React.FC<SyncFormProps> = ({ tableRef, onFinish, siteId, dateRan
onFinish={onFinish}
>
<ProForm.Group>
{/* 站点选择框 */}
<ProFormSelect
name="siteId"
@ -93,20 +96,19 @@ const SyncForm: React.FC<SyncFormProps> = ({ tableRef, onFinish, siteId, dateRan
/>
<ProFormDateRangePicker
name="dateRange"
label="同步日期范围"
placeholder={['开始日期', '结束日期']}
transform={(value) => {
return {
dateRange: value,
};
}}
fieldProps={{
showTime: false,
style: { width: '100%' },
}}
/>
name="dateRange"
label="同步日期范围"
placeholder={['开始日期', '结束日期']}
transform={(value) => {
return {
dateRange: value,
};
}}
fieldProps={{
showTime: false,
style: { width: '100%' },
}}
/>
</ProForm.Group>
</DrawerForm>
);

View File

@ -502,7 +502,10 @@ const ListPage: React.FC = () => {
success,
message: errMsg,
data,
} = await ordercontrollerSyncorders(values,{after:values.dateRange?.[0]+'T00:00:00Z',before:values.dateRange?.[1]+'T23:59:59Z'});
} = await ordercontrollerSyncorders(values, {
after: values.dateRange?.[0] + 'T00:00:00Z',
before: values.dateRange?.[1] + 'T23:59:59Z',
});
if (!success) {
throw new Error(errMsg);
}
@ -1507,16 +1510,16 @@ const Shipping: React.FC<{
<ProFormList
label="发货产品"
name="sales"
// rules={[
// {
// required: true,
// message: '至少需要一个商品',
// validator: (_, value) =>
// value && value.length > 0
//</Col> ? Promise.resolve()
// : Promise.reject('至少需要一个商品'),
// },
// ]}
// rules={[
// {
// required: true,
// message: '至少需要一个商品',
// validator: (_, value) =>
// value && value.length > 0
//</Col> ? Promise.resolve()
// : Promise.reject('至少需要一个商品'),
// },
// ]}
>
<ProForm.Group>
<ProFormSelect

View File

@ -1,486 +0,0 @@
import { PageContainer } from '@ant-design/pro-components';
import { request } from '@umijs/max';
import {
Card,
Col,
Image,
Layout,
Row,
Select,
Space,
Typography,
message,
} from 'antd';
import React, { useEffect, useState } from 'react';
const { Sider, Content } = Layout;
const { Title, Text } = Typography;
const { Option } = Select;
// Define interfaces
interface Brand {
id: number;
name: string;
shortName?: string;
image?: string;
}
interface Attribute {
id: number;
name: string;
title: string;
}
interface AttributeValue {
id: number;
name: string;
title: string;
titleCN?: string;
value?: string;
image?: string;
}
interface Product {
id: number;
sku: string;
name: string;
image?: string;
brandId: number;
brandName: string;
attributes: { [key: string]: any };
}
const BrandSpace: React.FC = () => {
// State management
const [brands, setBrands] = useState<Brand[]>([]);
const [selectedBrand, setSelectedBrand] = useState<number | null>(null);
const [attributes, setAttributes] = useState<Attribute[]>([]);
const [selectedAttribute, setSelectedAttribute] = useState<string | null>(
null,
);
const [attributeValues, setAttributeValues] = useState<AttributeValue[]>([]);
const [selectedAttributeValue, setSelectedAttributeValue] = useState<
number | null
>(null);
const [products, setProducts] = useState<Product[]>([]);
const [loading, setLoading] = useState(false);
const [attributeValuesLoading, setAttributeValuesLoading] = useState(false);
// Fetch brands list
const fetchBrands = async () => {
try {
const response = await request('/dict/items', {
params: { dictId: 'brand' }, // Assuming brand is a dict
});
const brandList = Array.isArray(response)
? response
: response?.data || [];
setBrands(brandList);
// Set default brand to "yoone" if exists
const defaultBrand = brandList.find((brand) => brand.name === 'yoone');
if (defaultBrand) {
setSelectedBrand(defaultBrand.id);
}
} catch (error) {
console.error('Failed to fetch brands:', error);
message.error('获取品牌列表失败');
}
};
// Fetch attributes list
const fetchAttributes = async () => {
try {
// Get all dicts that are attributes (excluding non-attribute dicts)
const response = await request('/dict/list');
const dictList = Array.isArray(response)
? response
: response?.data || [];
// Filter out non-attribute dicts (assuming attributes are specific dicts)
const attributeDicts = dictList.filter((dict: any) =>
['strength', 'flavor', 'humidity', 'size', 'version'].includes(
dict.name,
),
);
setAttributes(attributeDicts);
// Set default attribute to strength if exists
const defaultAttribute = attributeDicts.find(
(attr) => attr.name === 'strength',
);
if (defaultAttribute) {
setSelectedAttribute(defaultAttribute.name);
}
} catch (error) {
console.error('Failed to fetch attributes:', error);
message.error('获取属性列表失败');
}
};
// Fetch attribute values based on selected attribute
const fetchAttributeValues = async (attributeName: string) => {
setAttributeValuesLoading(true);
try {
const response = await request('/dict/items', {
params: { dictId: attributeName },
});
const values = Array.isArray(response) ? response : response?.data || [];
setAttributeValues(values);
} catch (error) {
console.error('Failed to fetch attribute values:', error);
message.error('获取属性值列表失败');
// Clear attribute values on error
setAttributeValues([]);
} finally {
setAttributeValuesLoading(false);
}
};
// Fetch products based on filters
const fetchProducts = async () => {
if (!selectedBrand) return;
setLoading(true);
try {
const params: any = {
brandId: selectedBrand,
};
// Add attribute filter if selected
if (selectedAttribute) {
// If attribute value is selected, filter by both attribute and value
if (selectedAttributeValue) {
params[selectedAttribute] = selectedAttributeValue;
} else {
// If only attribute is selected, filter by attribute presence
params[selectedAttribute] = 'hasValue';
}
}
const response = await request('/product/list', {
params,
});
const productList = response?.data?.items || [];
setProducts(productList);
} catch (error) {
console.error('Failed to fetch products:', error);
message.error('获取产品列表失败');
// Clear products on error
setProducts([]);
} finally {
setLoading(false);
}
};
// Initial data fetch
useEffect(() => {
fetchBrands();
fetchAttributes();
}, []);
// Fetch attribute values when attribute changes
useEffect(() => {
if (selectedAttribute) {
fetchAttributeValues(selectedAttribute);
setSelectedAttributeValue(null); // Reset selected value when attribute changes
}
}, [selectedAttribute]);
// Fetch products when filters change
useEffect(() => {
fetchProducts();
}, [selectedBrand, selectedAttribute, selectedAttributeValue]);
// Handle brand selection change
const handleBrandChange = (value: number) => {
setSelectedBrand(value);
};
// Handle attribute selection change
const handleAttributeChange = (value: string) => {
setSelectedAttribute(value);
};
// Handle attribute value selection change
const handleAttributeValueChange = (value: number) => {
setSelectedAttributeValue(value);
};
return (
<PageContainer title="品牌空间">
<Layout style={{ minHeight: 'calc(100vh - 64px)', background: '#fff' }}>
{/* Top Brand Selection */}
<div style={{ padding: '16px', borderBottom: '1px solid #f0f0f0' }}>
<Space direction="vertical" style={{ width: '100%' }}>
<Title level={4} style={{ margin: 0 }}>
</Title>
<Select
placeholder="请选择品牌"
style={{ width: 300 }}
value={selectedBrand}
onChange={handleBrandChange}
allowClear
>
{brands.map((brand) => (
<Option key={brand.id} value={brand.id}>
{brand.name}
</Option>
))}
</Select>
</Space>
</div>
<Layout>
{/* Left Attribute Selection */}
<Sider
width={240}
style={{ background: '#fafafa', borderRight: '1px solid #f0f0f0' }}
>
<div style={{ padding: '16px' }}>
<Space direction="vertical" style={{ width: '100%' }}>
<Title level={5} style={{ margin: 0 }}>
</Title>
<Select
placeholder="请选择属性类型"
style={{ width: '100%' }}
value={selectedAttribute}
onChange={handleAttributeChange}
allowClear
>
{attributes.map((attr) => (
<Option key={attr.id} value={attr.name}>
{attr.title}
</Option>
))}
</Select>
{selectedAttribute && (
<>
<Title level={5} style={{ margin: '16px 0 8px 0' }}>
</Title>
<Select
placeholder={`请选择${
attributes.find((a) => a.name === selectedAttribute)
?.title
}`}
style={{ width: '100%' }}
value={selectedAttributeValue}
onChange={handleAttributeValueChange}
allowClear
loading={attributeValuesLoading}
>
{attributeValues.map((value) => (
<Option key={value.id} value={value.id}>
<Space>
{value.image && (
<Image
src={value.image}
style={{
width: 24,
height: 24,
objectFit: 'cover',
borderRadius: 4,
}}
/>
)}
<span>
{value.titleCN || value.title || value.name}
</span>
</Space>
</Option>
))}
</Select>
</>
)}
{/* Filter Summary */}
{selectedBrand && (
<div
style={{
marginTop: 24,
padding: 12,
background: '#fff',
borderRadius: 8,
}}
>
<Text strong>:</Text>
<div style={{ marginTop: 8 }}>
<Text type="secondary">: </Text>
<Text>
{brands.find((b) => b.id === selectedBrand)?.name}
</Text>
</div>
{selectedAttribute && (
<div style={{ marginTop: 4 }}>
<Text type="secondary">
{
attributes.find((a) => a.name === selectedAttribute)
?.title
}
:
</Text>
<Text>
{selectedAttributeValue
? attributeValues.find(
(v) => v.id === selectedAttributeValue,
)?.titleCN ||
attributeValues.find(
(v) => v.id === selectedAttributeValue,
)?.title
: '所有值'}
</Text>
</div>
)}
</div>
)}
</Space>
</div>
</Sider>
{/* Main Content - Product List */}
<Content style={{ padding: '16px', overflowX: 'auto' }}>
<div style={{ marginBottom: 16 }}>
<Title level={4} style={{ margin: 0 }}>
<Text type="secondary" style={{ fontSize: 16, marginLeft: 8 }}>
({products.length} )
</Text>
</Title>
</div>
{loading ? (
<div style={{ textAlign: 'center', padding: '64px' }}>
<Text>...</Text>
</div>
) : attributeValues.length > 0 ? (
<div style={{ minWidth: 'max-content' }}>
<Row gutter={[16, 16]}>
{attributeValues.map((attributeValue) => {
// Filter products for this attribute value
if(!Array.isArray(products)){
console.log('products',products)
return null
}
const attributeValueProducts = selectedAttribute
? (products || []).filter((product) =>
product.attributes &&
product.attributes[selectedAttribute] === attributeValue.id
)
: [];
return (
<Col key={attributeValue.id} style={{ minWidth: 300 }}>
<Card
title={
<Space>
{attributeValue.image && (
<Image
src={attributeValue.image}
style={{
width: 24,
height: 24,
objectFit: 'cover',
borderRadius: 4,
}}
/>
)}
<span>
{attributeValue.titleCN || attributeValue.title || attributeValue.name}
</span>
</Space>
}
style={{ width: 300 }}
>
{attributeValueProducts.length > 0 ? (
<div style={{ maxHeight: 600, overflowY: 'auto' }}>
{attributeValueProducts.map((product) => (
<Card
key={product.id}
size="small"
hoverable
style={{ marginBottom: 8 }}
>
<div
style={{
height: 100,
overflow: 'hidden',
marginBottom: 8,
}}
>
<Image
src={
product.image ||
'https://via.placeholder.com/100x100?text=No+Image'
}
alt={product.name}
style={{
width: '100%',
height: '100%',
objectFit: 'cover',
}}
/>
</div>
<div>
<Text
type="secondary"
style={{ fontSize: 12, marginBottom: 4 }}
>
{product.sku}
</Text>
<div style={{ marginTop: 4 }}>
<Text ellipsis style={{ width: '100%', display: 'block' }}>
{product.name}
</Text>
</div>
<div style={{ marginTop: 8 }}>
<Text
strong
style={{ fontSize: 14, color: '#ff4d4f' }}
>
¥{product.price || '--'}
</Text>
</div>
</div>
</Card>
))}
</div>
) : (
<div style={{ textAlign: 'center', padding: '32px' }}>
<Text type="secondary"></Text>
</div>
)}
</Card>
</Col>
);
})}
</Row>
</div>
) : (
<div
style={{
textAlign: 'center',
padding: '64px',
background: '#fafafa',
borderRadius: 8,
}}
>
<Text type="secondary"></Text>
</div>
)}
</Content>
</Layout>
</Layout>
</PageContainer>
);
};
export default BrandSpace;

View File

@ -415,11 +415,11 @@ const CsvTool: React.FC = () => {
}
// 如果type为single且启用了生成bundle SKU则添加quantity
if (
quantity
) {
if (quantity) {
// 使用quantity的shortName如果没有则使用quantity但匹配 4 个零
const quantityShortName = attributeMappings.quantities[quantity] || Number(quantity).toString().padStart(4, '0');
const quantityShortName =
attributeMappings.quantities[quantity] ||
Number(quantity).toString().padStart(4, '0');
skuComponents.push(quantityShortName);
}
// 合并所有组件,使用短横线分隔
@ -463,9 +463,7 @@ const CsvTool: React.FC = () => {
if (size) nameComponents.push(size);
// 如果有数量且类型为bundle或者生成bundle的single产品则添加数量
if (
type==='bundle' && quantity
) {
if (type === 'bundle' && quantity) {
nameComponents.push(String(quantity));
}
@ -569,7 +567,7 @@ const CsvTool: React.FC = () => {
// Determine which data to use for processing and download
let finalData = dataWithSku;
console.log('generateBundleSkuForSingle',generateBundleSkuForSingle)
console.log('generateBundleSkuForSingle', generateBundleSkuForSingle);
// If generateBundleSkuForSingle is enabled, generate bundle products for single products
if (generateBundleSkuForSingle) {
// Filter out single records
@ -578,7 +576,9 @@ const CsvTool: React.FC = () => {
);
// Get quantity values from the config (same source as other attributes like brand)
const quantityValues = config.quantities.map(quantity=>quantity.name)
const quantityValues = config.quantities.map(
(quantity) => quantity.name,
);
// Generate bundle products for each single record and quantity
const generatedBundleRecords = singleRecords.flatMap((singleRecord) => {
@ -772,7 +772,11 @@ const CsvTool: React.FC = () => {
valuePropName="checked"
initialValue={true}
>
<Checkbox onChange={(e)=> setGenerateBundleSkuForSingle(e.target.checked)}>
<Checkbox
onChange={(e) =>
setGenerateBundleSkuForSingle(e.target.checked)
}
>
single类型生成bundle SKU
</Checkbox>
</ProForm.Item>

View File

@ -235,10 +235,10 @@ const List: React.FC = () => {
),
},
{
title: "图片",
title: '图片',
dataIndex: 'image',
width: 100,
valueType:'image'
valueType: 'image',
},
{
title: '名称',
@ -255,7 +255,6 @@ const List: React.FC = () => {
},
},
{
title: '价格',
dataIndex: 'price',

View File

@ -202,7 +202,11 @@ const SiteList: React.FC = () => {
</a>
),
},
{ title: 'webhook地址', dataIndex: 'webhookUrl', width: 280, hideInSearch: true },
{
title: 'webhook地址',
dataIndex: 'webhookUrl',
hideInSearch: true,
},
{
title: 'SKU 前缀',

View File

@ -169,7 +169,6 @@ const EditSiteForm: React.FC<EditSiteFormProps> = ({
label="区域"
mode="multiple"
placeholder="请选择区域"
showSearch
filterOption={(input, option) =>
(option?.label ?? '').toLowerCase().includes(input.toLowerCase())

View File

@ -2,7 +2,6 @@ import { ORDER_STATUS_ENUM } from '@/constants';
import { AddTag } from '@/pages/Customer/List';
import { customercontrollerDeltag } from '@/servers/api/customer';
import { sitecontrollerAll } from '@/servers/api/site';
import * as countries from 'i18n-iso-countries';
import {
statisticscontrollerGetorderbydate,
statisticscontrollerGetorderbyemail,
@ -22,6 +21,7 @@ import { Button, Space, Tag } from 'antd';
import dayjs from 'dayjs';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import ReactECharts from 'echarts-for-react';
import * as countries from 'i18n-iso-countries';
import { useEffect, useMemo, useRef, useState } from 'react';
dayjs.extend(weekOfYear);
@ -40,15 +40,15 @@ const highlightText = (text: string, keyword: string) => {
};
// 获取所有国家/地区的选项
const getCountryOptions = () => {
// 获取所有国家的 ISO 代码
const countryCodes = countries.getAlpha2Codes();
// 将国家代码转换为选项数组
return Object.keys(countryCodes).map((code) => ({
label: countries.getName(code, 'zh') || code, // 使用中文名称, 如果没有则使用代码
value: code,
}));
};
const getCountryOptions = () => {
// 获取所有国家的 ISO 代码
const countryCodes = countries.getAlpha2Codes();
// 将国家代码转换为选项数组
return Object.keys(countryCodes).map((code) => ({
label: countries.getName(code, 'zh') || code, // 使用中文名称, 如果没有则使用代码
value: code,
}));
};
const ListPage: React.FC = () => {
const [xAxis, setXAxis] = useState([]);
@ -635,18 +635,17 @@ const ListPage: React.FC = () => {
}}
/>
<ProFormSelect
name="country"
label="区域"
mode="multiple"
placeholder="请选择区域"
showSearch
filterOption={(input, option) =>
(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
}
options={getCountryOptions()}
/>
<ProFormSelect
name="country"
label="区域"
mode="multiple"
placeholder="请选择区域"
showSearch
filterOption={(input, option) =>
(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
}
options={getCountryOptions()}
/>
{/* <ProFormSelect
label="类型"
name="purchaseType"

View File

@ -8,16 +8,16 @@ import {
ActionType,
PageContainer,
ProColumns,
ProTable,
ProForm,
ProFormSelect,
ProTable,
} from '@ant-design/pro-components';
import { Space, Tag } from 'antd';
import dayjs from 'dayjs';
import ReactECharts from 'echarts-for-react';
import { HistoryOrder } from '../Order';
import * as countries from 'i18n-iso-countries';
import zhCN from 'i18n-iso-countries/langs/zh';
import { HistoryOrder } from '../Order';
countries.registerLocale(zhCN);
const ListPage: React.FC = () => {
const [data, setData] = useState({});
@ -25,12 +25,14 @@ const ListPage: React.FC = () => {
country: ['CA'],
};
function handleSubmit(values: typeof initialValues) {
statisticscontrollerGetordersource({params: values}).then(({ data, success }) => {
if (success) setData(data);
});
statisticscontrollerGetordersource({ params: values }).then(
({ data, success }) => {
if (success) setData(data);
},
);
}
useEffect(() => {
handleSubmit(initialValues)
handleSubmit(initialValues);
}, []);
const option = useMemo(() => {
@ -287,7 +289,6 @@ const ListPage: React.FC = () => {
);
},
},
];
return (
@ -297,7 +298,6 @@ const ListPage: React.FC = () => {
layout="inline"
onFinish={handleSubmit}
>
<ProFormSelect
name="country"
label="区域"
@ -343,8 +343,6 @@ const ListPage: React.FC = () => {
);
};
// 获取所有国家/地区的选项
const getCountryOptions = () => {
// 获取所有国家的 ISO 代码

View File

@ -623,6 +623,21 @@ export async function productcontrollerGetproductlist(
});
}
/** 此处后端没有提供注释 GET /product/list/grouped */
export async function productcontrollerGetproductlistgrouped(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.productcontrollerGetproductlistgroupedParams,
options?: { [key: string]: any },
) {
return request<Record<string, any>>('/product/list/grouped', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /product/search */
export async function productcontrollerSearchproducts(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)

View File

@ -963,6 +963,7 @@ declare namespace API {
orderId?: number;
siteId?: number;
externalOrderItemId?: string;
parentProductId?: number;
productId?: number;
name?: string;
/** sku */
@ -993,6 +994,7 @@ declare namespace API {
orderId?: number;
siteId?: number;
externalOrderItemId?: string;
parentProductId?: number;
productId?: number;
name?: string;
/** sku */
@ -1227,6 +1229,25 @@ declare namespace API {
id: number;
};
type productcontrollerGetproductlistgroupedParams = {
/** 页码 */
page?: number;
/** 每页数量 */
per_page?: number;
/** 查询时间范围开始 */
after?: string;
/** 查询时间范围结束 */
before?: string;
/** 搜索关键词 */
search?: string;
/** 过滤条件对象 */
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
};
type productcontrollerGetproductlistParams = {
/** 页码 */
page?: number;
@ -1242,6 +1263,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
};
type productcontrollerGetproductsiteskusParams = {
@ -1784,6 +1807,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -1802,6 +1827,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -1820,6 +1847,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -1838,6 +1867,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -1856,6 +1887,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -1874,6 +1907,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -1892,6 +1927,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
customerId: number;
siteId: number;
};
@ -1916,6 +1953,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -1938,6 +1977,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -1971,6 +2012,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -1994,6 +2037,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -2012,6 +2057,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -2030,6 +2077,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -2053,6 +2102,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
siteId: number;
};
@ -3004,6 +3055,8 @@ declare namespace API {
where?: any;
/** 排序对象,例如 { "sku": "desc" } */
orderBy?: any;
/** 分组字段,例如 "categoryId" */
groupBy?: string;
};
type UnifiedShippingLineDTO = {