Compare commits

...

10 Commits

Author SHA1 Message Date
tikkhun 69b5ab72ff refactor(Customer/StatisticList): 替换客户列表接口为统计列表接口并调整排序参数格式 2026-01-30 16:44:32 +08:00
tikkhun a4445362d5 fix(SyncForm): 修正日期格式化中的秒数显示问题 2026-01-30 16:44:32 +08:00
zhuotianyuan 500151c957 fix(订单列表): 将默认 shipmentPlatform 从 uniuni 改为 freightwaves 2026-01-30 15:21:59 +08:00
zhuotianyuan 8190dc92eb fix(订单列表): 修正物流公司默认值为空字符串
将"最佳物流"对应的值从"最优物流"改为空字符串,以保持数据一致性
2026-01-30 14:57:29 +08:00
zhuotianyuan 9429df1db7 fix: 移除调试语句debugger 2026-01-30 14:57:29 +08:00
zhuotianyuan 128677e9ac feat(订单列表): 添加最佳物流选项并优化邮件地址处理
添加"最佳物流"到快递公司选项列表
将origin.email_addresses改为直接使用而不分割,保持与destination.email_addresses处理方式一致
2026-01-30 14:57:29 +08:00
tikkhun 4c23fba5de fix: 移除订单列表页中的调试日志 2026-01-30 03:57:26 +00:00
tikkhun 84b8097949 fix(Product): 禁用批量创建套装按钮当未选择行时
fix(Order): 调整同步订单日期范围格式并添加调试日志

fix(Customer): 优化客户信息显示逻辑和空值处理

refactor(SyncForm): 重构同步表单初始值和日期处理逻辑
2026-01-30 03:57:26 +00:00
zhuotianyuan bf41887b6b style: 格式化订单列表页代码缩进和换行 2026-01-27 11:32:02 +00:00
zhuotianyuan 139fdf0474 feat(订单列表): 添加快递公司选择字段
新增快递公司选择下拉框,并默认设置 UNIUNI 为初始值。同时修正发货信息中 email_addresses 字段的取值逻辑
2026-01-27 11:32:02 +00:00
7 changed files with 411 additions and 333 deletions

View File

@ -16,7 +16,7 @@ interface SyncFormProps {
tableRef: React.MutableRefObject<ActionType | undefined>;
onFinish: (values: any) => Promise<void>;
siteId?: string;
dateRange?: [dayjs.Dayjs, dayjs.Dayjs];
initialValues?: any;
}
/**
@ -28,7 +28,10 @@ const SyncForm: React.FC<SyncFormProps> = ({
tableRef,
onFinish,
siteId,
dateRange,
initialValues = {
// 默认一星期
dateRange: [dayjs().subtract(1, 'week'), dayjs()],
},
}) => {
// 使用 antd 的 App 组件提供的 message API
const [loading, setLoading] = React.useState(false);
@ -57,9 +60,7 @@ const SyncForm: React.FC<SyncFormProps> = ({
// 返回一个抽屉表单
return (
<DrawerForm<API.ordercontrollerSyncorderParams>
initialValues={{
dateRange: [dayjs().subtract(1, 'week'), dayjs()],
}}
initialValues={initialValues}
title="同步订单"
// 表单的触发器,一个带图标的按钮
trigger={
@ -75,9 +76,20 @@ const SyncForm: React.FC<SyncFormProps> = ({
destroyOnHidden: true,
}}
// 表单提交成功后的回调
onFinish={onFinish}
onFinish={async (values) => {
const normalValues = {
...values,
dateRange: values.dateRange
? [
dayjs(values.dateRange[0]).format('YYYY-MM-DDTHH:mm:ss[Z]'),
dayjs(values.dateRange[1]).add(1, 'day').format('YYYY-MM-DDTHH:mm:ss[Z]'),
]
: [],
};
await onFinish(normalValues);
}}
>
<ProForm.Group>
{/* 站点选择框 */}
<ProFormSelect
name="siteId"
@ -99,17 +111,10 @@ const SyncForm: React.FC<SyncFormProps> = ({
name="dateRange"
label="同步日期范围"
placeholder={['开始日期', '结束日期']}
transform={(value) => {
return {
dateRange: value,
};
}}
fieldProps={{
showTime: false,
style: { width: '100%' },
}}
/>
</ProForm.Group>
</DrawerForm>
);
};

View File

@ -2,7 +2,7 @@ import { HistoryOrder } from '@/pages/Statistics/Order';
import {
customercontrollerAddtag,
customercontrollerDeltag,
customercontrollerGetcustomerlist,
customercontrollerGetcustomerstatisticlist,
customercontrollerGettags,
customercontrollerSetrate,
} from '@/servers/api/customer';
@ -27,9 +27,9 @@ const ListPage: React.FC = () => {
dataIndex: 'username',
hideInSearch: true,
render: (_, record) => {
if (record.billing.first_name || record.billing.last_name)
return record.billing.first_name + ' ' + record.billing.last_name;
return record.shipping.first_name + ' ' + record.shipping.last_name;
if (record.billing?.first_name || record.billing?.last_name)
return record.billing?.first_name + ' ' + record.billing?.last_name;
return record.shipping?.first_name + ' ' + record.shipping?.last_name;
},
},
{
@ -132,7 +132,7 @@ const ListPage: React.FC = () => {
title: '联系电话',
dataIndex: 'phone',
hideInSearch: true,
render: (_, record) => record?.billing.phone || record?.shipping.phone,
render: (_, record) => record.phone ?? record?.billing?.phone ?? record?.shipping?.phone ?? '-',
},
{
title: '账单地址',
@ -200,9 +200,9 @@ const ListPage: React.FC = () => {
rowKey="id"
request={async (params, sorter) => {
const key = Object.keys(sorter)[0];
const { data, success } = await customercontrollerGetcustomerlist({
const { data, success } = await customercontrollerGetcustomerstatisticlist({
...params,
...(key ? { sorterKey: key, sorterValue: sorter[key] } : {}),
...(key ? { orderBy: `${key}:${sorter[key]}` } : {}),
});
return {

View File

@ -84,8 +84,8 @@ import dayjs from 'dayjs';
import * as XLSX from 'xlsx';
const ListPage: React.FC = () => {
const [file, setFile] = useState<File | null>(null);
const [csvData, setCsvData] = useState<any[]>([]);
const [processedData, setProcessedData] = useState<any[]>([]);
const [csvData, setCsvData] = useState<any[]>([]);
const [processedData, setProcessedData] = useState<any[]>([]);
const actionRef = useRef<ActionType>();
const [activeKey, setActiveKey] = useState<string>('all');
const [count, setCount] = useState<any[]>([]);
@ -476,62 +476,62 @@ const ListPage: React.FC = () => {
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
/**
* @description
*/
const handleFileUpload = (uploadedFile: File) => {
// 检查文件类型
if (!uploadedFile.name.match(/\.(xlsx)$/)) {
message.error('请上传 xlsx 格式的文件!');
return false;
/**
* @description
*/
const handleFileUpload = (uploadedFile: File) => {
// 检查文件类型
if (!uploadedFile.name.match(/\.(xlsx)$/)) {
message.error('请上传 xlsx 格式的文件!');
return false;
}
setFile(uploadedFile);
const reader = new FileReader();
// 对于Excel文件继续使用readAsArrayBuffer
reader.onload = (e) => {
try {
const data = e.target?.result;
// 如果是ArrayBuffer使用type: 'array'来处理
const workbook = XLSX.read(data, { type: 'array' });
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
if (jsonData.length < 2) {
message.error('文件为空或缺少表头!');
setCsvData([]);
return;
}
// 将数组转换为对象数组
const headers = jsonData[0] as string[];
const rows = jsonData.slice(1).map((rowArray: any) => {
const rowData: { [key: string]: any } = {};
headers.forEach((header, index) => {
rowData[header] = rowArray[index];
});
return rowData;
});
message.success(`成功解析 ${rows.length} 条数据.`);
setCsvData(rows);
setProcessedData([]); // 清空旧的处理结果
} catch (error) {
message.error('Excel文件解析失败,请检查文件格式!');
console.error('Excel Parse Error:', error);
setCsvData([]);
}
setFile(uploadedFile);
const reader = new FileReader();
// 对于Excel文件继续使用readAsArrayBuffer
reader.onload = (e) => {
try {
const data = e.target?.result;
// 如果是ArrayBuffer使用type: 'array'来处理
const workbook = XLSX.read(data, { type: 'array' });
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
if (jsonData.length < 2) {
message.error('文件为空或缺少表头!');
setCsvData([]);
return;
}
// 将数组转换为对象数组
const headers = jsonData[0] as string[];
const rows = jsonData.slice(1).map((rowArray: any) => {
const rowData: { [key: string]: any } = {};
headers.forEach((header, index) => {
rowData[header] = rowArray[index];
});
return rowData;
});
message.success(`成功解析 ${rows.length} 条数据.`);
setCsvData(rows);
setProcessedData([]); // 清空旧的处理结果
} catch (error) {
message.error('Excel文件解析失败,请检查文件格式!');
console.error('Excel Parse Error:', error);
setCsvData([]);
}
};
reader.readAsArrayBuffer(uploadedFile);
reader.onerror = (error) => {
message.error('文件读取失败!');
console.error('File Read Error:', error);
};
return false; // 阻止antd Upload组件的默认上传行为
};
reader.readAsArrayBuffer(uploadedFile);
reader.onerror = (error) => {
message.error('文件读取失败!');
console.error('File Read Error:', error);
};
return false; // 阻止antd Upload组件的默认上传行为
};
return (
<PageContainer ghost>
@ -560,41 +560,41 @@ const ListPage: React.FC = () => {
}}
toolBarRender={() => [
// <CreateOrder tableRef={actionRef} />,
<Upload
// beforeUpload={handleFileUpload}
name="file"
<Upload
// beforeUpload={handleFileUpload}
name="file"
accept=".xlsx"
showUploadList={false}
maxCount={1}
customRequest={async (options) => {
const { file, onSuccess, onError } = options;
console.log(file);
const formData = new FormData();
const { file, onSuccess, onError } = options;
console.log(file);
const formData = new FormData();
formData.append('file', file);
try {
try {
const res = await request('/order/import', {
method: 'POST',
data: formData,
requestType: 'form',
});
if (res?.success && res.data) {
// 使用xlsx将JSON数据转换为Excel
if (res?.success && res.data) {
// 使用xlsx将JSON数据转换为Excel
const XLSX = require('xlsx');
const worksheet = XLSX.utils.json_to_sheet(res.data);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, 'Orders');
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
// 否则按原逻辑处理二进制数据
const blob = new Blob([excelBuffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'orders.xlsx';
a.click();
URL.revokeObjectURL(url);
// 否则按原逻辑处理二进制数据
const blob = new Blob([excelBuffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'orders.xlsx';
a.click();
URL.revokeObjectURL(url);
} else {
message.error(res.message || '导出失败');
@ -606,9 +606,9 @@ const ListPage: React.FC = () => {
onError?.(error);
}
}}
>
<Button icon={<UploadOutlined />}></Button>
</Upload>,
>
<Button icon={<UploadOutlined />}></Button>
</Upload>,
<SyncForm
onFinish={async (values: any) => {
try {
@ -617,8 +617,8 @@ const ListPage: React.FC = () => {
message: errMsg,
data,
} = await ordercontrollerSyncorders(values, {
after: values.dateRange?.[0] + 'T00:00:00Z',
before: values.dateRange?.[1] + 'T23:59:59Z',
after: values.dateRange?.[0],
before: values.dateRange?.[1],
});
if (!success) {
throw new Error(errMsg);
@ -756,36 +756,36 @@ const Detail: React.FC<{
)
? []
: [
<Divider type="vertical" />,
<Button
type="primary"
onClick={async () => {
try {
if (!record.siteId || !record.externalOrderId) {
message.error('站点ID或外部订单ID不存在');
return;
}
const {
success,
message: errMsg,
data,
} = await ordercontrollerSyncorderbyid({
siteId: record.siteId,
orderId: record.externalOrderId,
});
if (!success) {
throw new Error(errMsg);
}
showSyncResult(data as SyncResultData, '订单');
tableRef.current?.reload();
} catch (error: any) {
message.error(error?.message || '同步失败');
<Divider type="vertical" />,
<Button
type="primary"
onClick={async () => {
try {
if (!record.siteId || !record.externalOrderId) {
message.error('站点ID或外部订单ID不存在');
return;
}
}}
>
</Button>,
]),
const {
success,
message: errMsg,
data,
} = await ordercontrollerSyncorderbyid({
siteId: record.siteId,
orderId: record.externalOrderId,
});
if (!success) {
throw new Error(errMsg);
}
showSyncResult(data as SyncResultData, '订单');
tableRef.current?.reload();
} catch (error: any) {
message.error(error?.message || '同步失败');
}
}}
>
</Button>,
]),
// ...(['processing', 'pending_reshipment'].includes(record.orderStatus)
// ? [
// <Divider type="vertical" />,
@ -804,152 +804,152 @@ const Detail: React.FC<{
'pending_refund',
].includes(record.orderStatus)
? [
<Divider type="vertical" />,
<Popconfirm
title="转至售后"
description="确认转至售后?"
onConfirm={async () => {
try {
if (!record.id) {
message.error('订单ID不存在');
return;
}
const { success, message: errMsg } =
await ordercontrollerChangestatus(
{
id: record.id,
},
{
status: 'after_sale_pending',
},
);
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
} catch (error: any) {
message.error(error.message);
<Divider type="vertical" />,
<Popconfirm
title="转至售后"
description="确认转至售后?"
onConfirm={async () => {
try {
if (!record.id) {
message.error('订单ID不存在');
return;
}
}}
>
<Button type="primary" ghost>
</Button>
</Popconfirm>,
]
const { success, message: errMsg } =
await ordercontrollerChangestatus(
{
id: record.id,
},
{
status: 'after_sale_pending',
},
);
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
} catch (error: any) {
message.error(error.message);
}
}}
>
<Button type="primary" ghost>
</Button>
</Popconfirm>,
]
: []),
...(record.orderStatus === 'after_sale_pending'
? [
<Divider type="vertical" />,
<Popconfirm
title="转至取消"
description="确认转至取消?"
onConfirm={async () => {
try {
if (!record.id) {
message.error('订单ID不存在');
return;
}
const { success, message: errMsg } =
await ordercontrollerCancelorder({
<Divider type="vertical" />,
<Popconfirm
title="转至取消"
description="确认转至取消?"
onConfirm={async () => {
try {
if (!record.id) {
message.error('订单ID不存在');
return;
}
const { success, message: errMsg } =
await ordercontrollerCancelorder({
id: record.id,
});
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
} catch (error: any) {
message.error(error.message);
}
}}
>
<Button type="primary" ghost>
</Button>
</Popconfirm>,
<Divider type="vertical" />,
<Popconfirm
title="转至退款"
description="确认转至退款?"
onConfirm={async () => {
try {
if (!record.id) {
message.error('订单ID不存在');
return;
}
const { success, message: errMsg } =
await ordercontrollerRefundorder({
id: record.id,
});
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
} catch (error: any) {
message.error(error.message);
}
}}
>
<Button type="primary" ghost>
退
</Button>
</Popconfirm>,
<Divider type="vertical" />,
<Popconfirm
title="转至完成"
description="确认转至完成?"
onConfirm={async () => {
try {
if (!record.id) {
message.error('订单ID不存在');
return;
}
const { success, message: errMsg } =
await ordercontrollerCompletedorder({
id: record.id,
});
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
} catch (error: any) {
message.error(error.message);
}
}}
>
<Button type="primary" ghost>
</Button>
</Popconfirm>,
<Divider type="vertical" />,
<Popconfirm
title="转至待补发"
description="确认转至待补发?"
onConfirm={async () => {
try {
const { success, message: errMsg } =
await ordercontrollerChangestatus(
{
id: record.id,
});
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
} catch (error: any) {
message.error(error.message);
},
{
status: 'pending_reshipment',
},
);
if (!success) {
throw new Error(errMsg);
}
}}
>
<Button type="primary" ghost>
</Button>
</Popconfirm>,
<Divider type="vertical" />,
<Popconfirm
title="转至退款"
description="确认转至退款?"
onConfirm={async () => {
try {
if (!record.id) {
message.error('订单ID不存在');
return;
}
const { success, message: errMsg } =
await ordercontrollerRefundorder({
id: record.id,
});
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
} catch (error: any) {
message.error(error.message);
}
}}
>
<Button type="primary" ghost>
退
</Button>
</Popconfirm>,
<Divider type="vertical" />,
<Popconfirm
title="转至完成"
description="确认转至完成?"
onConfirm={async () => {
try {
if (!record.id) {
message.error('订单ID不存在');
return;
}
const { success, message: errMsg } =
await ordercontrollerCompletedorder({
id: record.id,
});
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
} catch (error: any) {
message.error(error.message);
}
}}
>
<Button type="primary" ghost>
</Button>
</Popconfirm>,
<Divider type="vertical" />,
<Popconfirm
title="转至待补发"
description="确认转至待补发?"
onConfirm={async () => {
try {
const { success, message: errMsg } =
await ordercontrollerChangestatus(
{
id: record.id,
},
{
status: 'pending_reshipment',
},
);
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
} catch (error: any) {
message.error(error.message);
}
}}
>
<Button type="primary" ghost>
</Button>
</Popconfirm>,
]
tableRef.current?.reload();
} catch (error: any) {
message.error(error.message);
}
}}
>
<Button type="primary" ghost>
</Button>
</Popconfirm>,
]
: []),
]}
>
@ -1212,31 +1212,31 @@ const Detail: React.FC<{
}
actions={
v.state === 'waiting-for-scheduling' ||
v.state === 'waiting-for-transit'
v.state === 'waiting-for-transit'
? [
<Popconfirm
title="取消运单"
description="确认取消运单?"
onConfirm={async () => {
try {
const { success, message: errMsg } =
await logisticscontrollerDelshipment({
id: v.id,
});
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
initRequest();
} catch (error: any) {
message.error(error.message);
<Popconfirm
title="取消运单"
description="确认取消运单?"
onConfirm={async () => {
try {
const { success, message: errMsg } =
await logisticscontrollerDelshipment({
id: v.id,
});
if (!success) {
throw new Error(errMsg);
}
}}
>
<DeleteFilled />
</Popconfirm>,
]
tableRef.current?.reload();
initRequest();
} catch (error: any) {
message.error(error.message);
}
}}
>
<DeleteFilled />
</Popconfirm>,
]
: []
}
>
@ -1381,10 +1381,17 @@ const Shipping: React.FC<{
const [rates, setRates] = useState<API.RateDTO[]>([]);
const [ratesLoading, setRatesLoading] = useState(false);
const { message } = App.useApp();
const [shipmentPlatforms, setShipmentPlatforms] = useState([
const [shipmentPlatforms, setShipmentPlatforms] = useState([
{ label: 'uniuni', value: 'uniuni' },
{ label: 'tms.freightwaves', value: 'freightwaves' },
]);
const [courierCompany, setCourierCompany] = useState([
{ label: '最佳物流', value: '' },
{ label: 'UNIUNI', value: 'UNIUNI' },
{ label: 'PuroYYZ', value: 'PuroYYZ' },
{ label: 'CPYYZ', value: 'CPYYZ' },
{ label: 'UPSYYZ7000NEW', value: 'UPSYYZ7000NEW' },
]);
return (
<ModalForm
formRef={formRef}
@ -1413,7 +1420,7 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
await ordercontrollerGetorderdetail({
orderId: id,
});
console.log('success data',success,data)
console.log('success data', success, data)
if (!success || !data) return {};
data.sales = data.sales?.reduce(
(acc: API.OrderSale[], cur: API.OrderSale) => {
@ -1436,8 +1443,9 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
if (reShipping) data.sales = [{}];
let shipmentInfo = localStorage.getItem('shipmentInfo');
if (shipmentInfo) shipmentInfo = JSON.parse(shipmentInfo);
const a = {
shipmentPlatform: 'uniuni',
const a = {
shipmentPlatform: 'freightwaves',
courierCompany: '',
...data,
// payment_method_id: shipmentInfo?.payment_method_id,
stockPointId: shipmentInfo?.stockPointId,
@ -1464,7 +1472,7 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
},
origin: {
name: data?.name,
email_addresses: data?.email,
email_addresses: shipmentInfo?.email_addresses,
contact_name: data?.name,
phone_number: shipmentInfo?.phone_number,
address: {
@ -1508,7 +1516,7 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
...data
}) => {
details.origin.email_addresses =
details.origin.email_addresses.split(',');
details.origin.email_addresses;
details.destination.email_addresses =
details.destination.email_addresses.split(',');
details.destination.phone_number.number =
@ -1541,6 +1549,7 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
postal_code: details.origin.address.postal_code,
address_line_1: details.origin.address.address_line_1,
phone_number: details.origin.phone_number,
email_addresses: details.origin.email_addresses,
}),
);
@ -1561,17 +1570,25 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
}
}}
>
<Row gutter={16}>
<Row gutter={16}>
<Col span={8}>
<ProFormSelect
name="shipmentPlatform"
label="发货平台"
options={shipmentPlatforms}
placeholder="请选择发货平台"
rules={[{ required: true, message: '请选择一个选项' }]}
/>
</Col>
</Row>
<ProFormSelect
name="shipmentPlatform"
label="发货平台"
options={shipmentPlatforms}
placeholder="请选择发货平台"
rules={[{ required: true, message: '请选择一个选项' }]}
/>
</Col>
<Col span={8}>
<ProFormSelect
name="courierCompany"
label="快递公司"
options={courierCompany}
placeholder="请选择快递公司"
/>
</Col>
</Row>
<ProFormText label="订单号" readonly name='externalOrderId' />
<ProFormText label="客户备注" readonly name="customer_note" />
<ProFormList
@ -1641,16 +1658,16 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
<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
@ -1718,7 +1735,7 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
// address_id: row.id,
details: {
origin: {
email_addresses:email,
email_addresses: email,
address,
phone_number: {
phone: phone_number,
@ -1731,7 +1748,7 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
/>
}
>
{/* <ProFormText
{/* <ProFormText
label="address_id"
name={'address_id'}
rules={[{ required: true, message: '请输入ID' }]}
@ -2084,7 +2101,7 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
name="description"
placeholder="请输入描述"
width="lg"
// rules={[{ required: true, message: '请输入描述' }]}
// rules={[{ required: true, message: '请输入描述' }]}
/>
</ProForm.Group>
</ProFormList>
@ -2149,7 +2166,7 @@ const [shipmentPlatforms, setShipmentPlatforms] = useState([
const originEmail = details.origin.email_addresses;
const destinationEmail = details.destination.email_addresses;
details.origin.email_addresses =
details.origin.email_addresses.split(',');
details.origin.email_addresses;
details.destination.email_addresses =
details.destination.email_addresses.split(',');
details.destination.phone_number.number =
@ -2484,7 +2501,7 @@ const CreateOrder: React.FC<{
<ProFormText
label="公司名称"
name={['billing', 'company']}
rules={[{ message: '请输入公司名称' }]}
rules={[{ message: '请输入公司名称' }]}
/>
<ProFormItem
name={['billing', 'country']}
@ -2571,7 +2588,7 @@ const AddressPicker: React.FC<{
}));
},
},
{
{
title: 'id',
dataIndex: ['id'],
hideInSearch: true,
@ -2604,7 +2621,7 @@ const AddressPicker: React.FC<{
},
{
title: '邮箱',
dataIndex: [ 'email'],
dataIndex: ['email'],
hideInSearch: true,
},
];

View File

@ -467,7 +467,9 @@ const List: React.FC = () => {
</Button>,
// 批量创建 bundle 产品按钮
<Button onClick={() => setBatchCreateBundleModalVisible(true)}>
<Button
disabled={selectedRows.length <= 0}
onClick={() => setBatchCreateBundleModalVisible(true)}>
</Button>,
// 批量同步按钮

View File

@ -12,6 +12,7 @@ import * as order from './order';
import * as product from './product';
import * as site from './site';
import * as siteApi from './siteApi';
import * as siteProduct from './siteProduct';
import * as statistics from './statistics';
import * as stock from './stock';
import * as subscription from './subscription';
@ -28,6 +29,7 @@ export default {
order,
product,
siteApi,
siteProduct,
site,
statistics,
stock,

View File

@ -0,0 +1,33 @@
// @ts-ignore
/* eslint-disable */
import { request } from 'umi';
/** 此处后端没有提供注释 GET /site-product/list */
export async function siteproductcontrollerGetsiteproductlist(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.siteproductcontrollerGetsiteproductlistParams,
options?: { [key: string]: any },
) {
return request<any>('/site-product/list', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /site-product/sync */
export async function siteproductcontrollerSyncsiteproducts(
body: number,
options?: { [key: string]: any },
) {
return request<any>('/site-product/sync', {
method: 'POST',
headers: {
'Content-Type': 'text/plain',
},
data: body,
...(options || {}),
});
}

View File

@ -1103,8 +1103,8 @@ declare namespace API {
categoryId?: number;
/** 库存组成 */
components?: ProductStockComponent[];
/** 站点 SKU 列表 */
siteSkus?: string[];
/** 站点 SKU关联 */
siteSkus?: SiteSku[];
/** 来源 */
source?: number;
/** 创建时间 */
@ -1630,10 +1630,12 @@ declare namespace API {
stockPointId?: number;
orderIds?: number[];
shipmentPlatform?: string;
courierCompany?: string;
};
type ShipmentFeeBookDTO = {
shipmentPlatform?: string;
courierCompany?: string;
stockPointId?: number;
sender?: string;
startPhone?: Record<string, any>;
@ -2221,6 +2223,23 @@ declare namespace API {
id: string;
};
type siteproductcontrollerGetsiteproductlistParams = {
sku?: string;
name?: string;
siteId?: number;
pageSize?: number;
current?: number;
};
type SiteSku = {
/** sku */
sku?: string;
/** 商品ID */
productId?: number;
/** 是否旧版数据 */
isOld?: boolean;
};
type SitesResponse = {
/** 状态码 */
code?: number;