feat(api): 添加区域管理相关接口和类型定义
feat(Dict): 优化字典项表单使用Form实例并添加下载模板功能 feat(Product): 新增产品编辑功能并优化创建表单
This commit is contained in:
parent
15c8588357
commit
456bbac8c6
|
|
@ -36,11 +36,7 @@ const DictPage: React.FC = () => {
|
||||||
// 控制字典项模态框的显示
|
// 控制字典项模态框的显示
|
||||||
const [isDictItemModalVisible, setIsDictItemModalVisible] = useState(false);
|
const [isDictItemModalVisible, setIsDictItemModalVisible] = useState(false);
|
||||||
const [editingDictItem, setEditingDictItem] = useState<any>(null);
|
const [editingDictItem, setEditingDictItem] = useState<any>(null);
|
||||||
const [dictItemForm, setDictItemForm] = useState({
|
const [dictItemForm] = Form.useForm();
|
||||||
name: '',
|
|
||||||
title: '',
|
|
||||||
value: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取字典列表
|
// 获取字典列表
|
||||||
const fetchDicts = async (title?: string) => {
|
const fetchDicts = async (title?: string) => {
|
||||||
|
|
@ -126,36 +122,32 @@ const DictPage: React.FC = () => {
|
||||||
// 打开添加字典项模态框
|
// 打开添加字典项模态框
|
||||||
const handleAddDictItem = () => {
|
const handleAddDictItem = () => {
|
||||||
setEditingDictItem(null);
|
setEditingDictItem(null);
|
||||||
setDictItemForm({ name: '', title: '', value: '' });
|
dictItemForm.resetFields();
|
||||||
setIsDictItemModalVisible(true);
|
setIsDictItemModalVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑字典项模态框
|
// 打开编辑字典项模态框
|
||||||
const handleEditDictItem = (item: any) => {
|
const handleEditDictItem = (item: any) => {
|
||||||
setEditingDictItem(item);
|
setEditingDictItem(item);
|
||||||
setDictItemForm(item);
|
dictItemForm.setFieldsValue(item);
|
||||||
setIsDictItemModalVisible(true);
|
setIsDictItemModalVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理字典项表单提交(添加/编辑)
|
// 处理字典项表单提交(添加/编辑)
|
||||||
const handleDictItemFormSubmit = async () => {
|
const handleDictItemFormSubmit = async (values: any) => {
|
||||||
if (!dictItemForm.name || !dictItemForm.title) {
|
|
||||||
message.warning('请输入名称和标题');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
if (editingDictItem) {
|
if (editingDictItem) {
|
||||||
// 编辑
|
// 编辑
|
||||||
await request(`/dict/item/${editingDictItem.id}`, {
|
await request(`/dict/item/${editingDictItem.id}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
data: dictItemForm,
|
data: values,
|
||||||
});
|
});
|
||||||
message.success('更新成功');
|
message.success('更新成功');
|
||||||
} else {
|
} else {
|
||||||
// 添加
|
// 添加
|
||||||
await request('/dict/item', {
|
await request('/dict/item', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: { ...dictItemForm, dictId: selectedDict.id },
|
data: { ...values, dictId: selectedDict.id },
|
||||||
});
|
});
|
||||||
message.success('添加成功');
|
message.success('添加成功');
|
||||||
}
|
}
|
||||||
|
|
@ -193,6 +185,50 @@ const DictPage: React.FC = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 下载字典模板(走认证请求)
|
||||||
|
*/
|
||||||
|
const handleDownloadDictTemplate = async () => {
|
||||||
|
try {
|
||||||
|
// 使用带有认证拦截的 request 发起下载请求(后端鉴权通过)
|
||||||
|
const blob = await request('/dict/template', { responseType: 'blob' });
|
||||||
|
// 创建临时链接并触发下载
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'dict-template.xlsx';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
} catch (error) {
|
||||||
|
// 错误处理:认证失败或网络错误
|
||||||
|
message.error('下载模板失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 下载字典项模板(走认证请求)
|
||||||
|
*/
|
||||||
|
const handleDownloadDictItemTemplate = async () => {
|
||||||
|
try {
|
||||||
|
// 使用带有认证拦截的 request 发起下载请求(后端鉴权通过)
|
||||||
|
const blob = await request('/dict/item/template', { responseType: 'blob' });
|
||||||
|
// 创建临时链接并触发下载
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'dict-item-template.xlsx';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
} catch (error) {
|
||||||
|
// 错误处理:认证失败或网络错误
|
||||||
|
message.error('下载模板失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 左侧字典列表的列定义
|
// 左侧字典列表的列定义
|
||||||
const dictColumns = [
|
const dictColumns = [
|
||||||
{
|
{
|
||||||
|
|
@ -211,6 +247,7 @@ const DictPage: React.FC = () => {
|
||||||
render: (_: any, record: any) => (
|
render: (_: any, record: any) => (
|
||||||
<Space>
|
<Space>
|
||||||
<Button
|
<Button
|
||||||
|
size='small'
|
||||||
type="link"
|
type="link"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
@ -220,6 +257,7 @@ const DictPage: React.FC = () => {
|
||||||
编辑
|
编辑
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
size='small'
|
||||||
type="link"
|
type="link"
|
||||||
danger
|
danger
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
|
@ -246,6 +284,11 @@ const DictPage: React.FC = () => {
|
||||||
dataIndex: 'title',
|
dataIndex: 'title',
|
||||||
key: 'title',
|
key: 'title',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '中文标题',
|
||||||
|
dataIndex: 'titleCN',
|
||||||
|
key: 'titleCN',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
|
|
@ -308,7 +351,7 @@ const DictPage: React.FC = () => {
|
||||||
>
|
>
|
||||||
<Button icon={<UploadOutlined />}>导入字典</Button>
|
<Button icon={<UploadOutlined />}>导入字典</Button>
|
||||||
</Upload>
|
</Upload>
|
||||||
<Button onClick={() => window.open('/dict/template')}>
|
<Button onClick={handleDownloadDictTemplate}>
|
||||||
下载模板
|
下载模板
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
|
|
@ -336,14 +379,14 @@ const DictPage: React.FC = () => {
|
||||||
</Sider>
|
</Sider>
|
||||||
<Content style={{ padding: '16px' }}>
|
<Content style={{ padding: '16px' }}>
|
||||||
<Space direction="vertical" style={{ width: '100%' }}>
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
<Button
|
<div style={{ width: '100%', display: 'flex', flexDirection: 'row', gap: '2px' }}>
|
||||||
type="primary"
|
<Button
|
||||||
onClick={handleAddDictItem}
|
type="primary"
|
||||||
disabled={!selectedDict}
|
onClick={handleAddDictItem}
|
||||||
>
|
disabled={!selectedDict}
|
||||||
添加字典项
|
>
|
||||||
</Button>
|
添加字典项
|
||||||
<Space>
|
</Button>
|
||||||
<Upload
|
<Upload
|
||||||
name="file"
|
name="file"
|
||||||
action={`/dict/item/import`}
|
action={`/dict/item/import`}
|
||||||
|
|
@ -364,12 +407,12 @@ const DictPage: React.FC = () => {
|
||||||
</Button>
|
</Button>
|
||||||
</Upload>
|
</Upload>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => window.open('/dict/item/template')}
|
onClick={handleDownloadDictItemTemplate}
|
||||||
disabled={!selectedDict}
|
disabled={!selectedDict}
|
||||||
>
|
>
|
||||||
下载模板
|
下载模板
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</div>
|
||||||
<Table
|
<Table
|
||||||
dataSource={dictItems}
|
dataSource={dictItems}
|
||||||
columns={dictItemColumns}
|
columns={dictItemColumns}
|
||||||
|
|
@ -382,37 +425,35 @@ const DictPage: React.FC = () => {
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
title={editingDictItem ? '编辑字典项' : '添加字典项'}
|
title={editingDictItem ? '编辑字典项' : '添加字典项'}
|
||||||
visible={isDictItemModalVisible}
|
open={isDictItemModalVisible}
|
||||||
onOk={handleDictItemFormSubmit}
|
onOk={() => dictItemForm.submit()}
|
||||||
onCancel={() => setIsDictItemModalVisible(false)}
|
onCancel={() => setIsDictItemModalVisible(false)}
|
||||||
|
destroyOnClose
|
||||||
>
|
>
|
||||||
<Form layout="vertical">
|
<Form
|
||||||
<Form.Item label="名称">
|
form={dictItemForm}
|
||||||
<Input
|
layout="vertical"
|
||||||
placeholder="名称 (e.g., zyn)"
|
onFinish={handleDictItemFormSubmit}
|
||||||
value={dictItemForm.name}
|
>
|
||||||
onChange={(e) =>
|
<Form.Item
|
||||||
setDictItemForm({ ...dictItemForm, name: e.target.value })
|
label="名称"
|
||||||
}
|
name="name"
|
||||||
/>
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
>
|
||||||
|
<Input placeholder="名称 (e.g., zyn)" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="标题">
|
<Form.Item
|
||||||
<Input
|
label="标题"
|
||||||
placeholder="标题 (e.g., ZYN)"
|
name="title"
|
||||||
value={dictItemForm.title}
|
rules={[{ required: true, message: '请输入标题' }]}
|
||||||
onChange={(e) =>
|
>
|
||||||
setDictItemForm({ ...dictItemForm, title: e.target.value })
|
<Input placeholder="标题 (e.g., ZYN)" />
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="值 (可选)">
|
<Form.Item label="中文标题" name="titleCN">
|
||||||
<Input
|
<Input placeholder="中文标题 (e.g., 品牌)" />
|
||||||
placeholder="值 (可选)"
|
</Form.Item>
|
||||||
value={dictItemForm.value}
|
<Form.Item label="值 (可选)" name="value">
|
||||||
onChange={(e) =>
|
<Input placeholder="值 (可选)" />
|
||||||
setDictItemForm({ ...dictItemForm, value: e.target.value })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import {
|
||||||
productcontrollerGetproductlist,
|
productcontrollerGetproductlist,
|
||||||
productcontrollerGetstrengthall,
|
productcontrollerGetstrengthall,
|
||||||
productcontrollerUpdateproductnamecn,
|
productcontrollerUpdateproductnamecn,
|
||||||
|
productcontrollerUpdateproduct,
|
||||||
} from '@/servers/api/product';
|
} from '@/servers/api/product';
|
||||||
import { templatecontrollerRendertemplate } from '@/servers/api/template';
|
import { templatecontrollerRendertemplate } from '@/servers/api/template';
|
||||||
import { PlusOutlined } from '@ant-design/icons';
|
import { PlusOutlined } from '@ant-design/icons';
|
||||||
|
|
@ -23,6 +24,7 @@ import {
|
||||||
} from '@ant-design/pro-components';
|
} from '@ant-design/pro-components';
|
||||||
import { App, Button, Popconfirm } from 'antd';
|
import { App, Button, Popconfirm } from 'antd';
|
||||||
import React, { useRef, useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
|
const capitalize = (s: string) => s.charAt(0).toLocaleUpperCase() + s.slice(1);
|
||||||
// TODO
|
// TODO
|
||||||
interface DictItem {
|
interface DictItem {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
@ -54,7 +56,7 @@ const NameCn: React.FC<{
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return message.error(errMsg);
|
return message.error(errMsg);
|
||||||
}
|
}
|
||||||
tableRef?.current?.reload();
|
tableRef?.current?.reloadAndRest?.();
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -67,6 +69,10 @@ const List: React.FC = () => {
|
||||||
|
|
||||||
const { message } = App.useApp();
|
const { message } = App.useApp();
|
||||||
const columns: ProColumns<API.Product>[] = [
|
const columns: ProColumns<API.Product>[] = [
|
||||||
|
{
|
||||||
|
title: 'sku',
|
||||||
|
dataIndex: 'sku',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '名称',
|
title: '名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
|
|
@ -80,6 +86,21 @@ const List: React.FC = () => {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '价格',
|
||||||
|
dataIndex: 'price',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '促销价',
|
||||||
|
dataIndex: 'promotionPrice',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '库存',
|
||||||
|
dataIndex: 'stock',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '产品描述',
|
title: '产品描述',
|
||||||
dataIndex: 'description',
|
dataIndex: 'description',
|
||||||
|
|
@ -101,10 +122,7 @@ const List: React.FC = () => {
|
||||||
title: '湿度',
|
title: '湿度',
|
||||||
dataIndex: 'humidity',
|
dataIndex: 'humidity',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: 'sku',
|
|
||||||
dataIndex: 'sku',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: '更新时间',
|
title: '更新时间',
|
||||||
dataIndex: 'updatedAt',
|
dataIndex: 'updatedAt',
|
||||||
|
|
@ -123,6 +141,7 @@ const List: React.FC = () => {
|
||||||
valueType: 'option',
|
valueType: 'option',
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<>
|
<>
|
||||||
|
<EditForm record={record} tableRef={actionRef} />
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title="删除"
|
title="删除"
|
||||||
description="确认删除?"
|
description="确认删除?"
|
||||||
|
|
@ -218,7 +237,7 @@ const CreateForm: React.FC<{
|
||||||
brand: brand ? brand.name : "",
|
brand: brand ? brand.name : "",
|
||||||
strength: strength ? strength.name : '',
|
strength: strength ? strength.name : '',
|
||||||
flavor: flavor ? flavor.name : '',
|
flavor: flavor ? flavor.name : '',
|
||||||
humidity: humidity === 'dry' ? 'Dry' : 'Moisture',
|
humidity: humidity ? capitalize(humidity) : '',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
|
@ -287,18 +306,15 @@ const CreateForm: React.FC<{
|
||||||
destroyOnHidden: true,
|
destroyOnHidden: true,
|
||||||
}}
|
}}
|
||||||
onFinish={async (values) => {
|
onFinish={async (values) => {
|
||||||
try {
|
const { success, message: errMsg } =
|
||||||
const { success, message: errMsg } =
|
await productcontrollerCreateproduct(values);
|
||||||
await productcontrollerCreateproduct(values);
|
if (success) {
|
||||||
if (!success) {
|
|
||||||
throw new Error(errMsg);
|
|
||||||
}
|
|
||||||
tableRef.current?.reload();
|
|
||||||
message.success('提交成功');
|
message.success('提交成功');
|
||||||
|
tableRef.current?.reloadAndRest?.();
|
||||||
return true;
|
return true;
|
||||||
} catch (error: any) {
|
|
||||||
message.error(error.message);
|
|
||||||
}
|
}
|
||||||
|
message.error(errMsg);
|
||||||
|
return false;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ProFormSelect
|
<ProFormSelect
|
||||||
|
|
@ -353,7 +369,7 @@ const CreateForm: React.FC<{
|
||||||
placeholder="请选择干湿"
|
placeholder="请选择干湿"
|
||||||
valueEnum={{
|
valueEnum={{
|
||||||
dry: 'dry',
|
dry: 'dry',
|
||||||
wet: 'wet',
|
moisture: 'moisture',
|
||||||
}}
|
}}
|
||||||
rules={[{ required: true, message: '请选择干湿' }]}
|
rules={[{ required: true, message: '请选择干湿' }]}
|
||||||
/>
|
/>
|
||||||
|
|
@ -381,6 +397,20 @@ const CreateForm: React.FC<{
|
||||||
自动生成
|
自动生成
|
||||||
</Button>
|
</Button>
|
||||||
</ProForm.Group>
|
</ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="price"
|
||||||
|
label="价格"
|
||||||
|
width="md"
|
||||||
|
placeholder="请输入价格"
|
||||||
|
rules={[{ required: false }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="promotionPrice"
|
||||||
|
label="促销价"
|
||||||
|
width="md"
|
||||||
|
placeholder="请输入促销价"
|
||||||
|
rules={[{ required: false }]}
|
||||||
|
/>
|
||||||
<ProFormTextArea
|
<ProFormTextArea
|
||||||
name="description"
|
name="description"
|
||||||
width="lg"
|
width="lg"
|
||||||
|
|
@ -392,3 +422,153 @@ const CreateForm: React.FC<{
|
||||||
};
|
};
|
||||||
|
|
||||||
export default List;
|
export default List;
|
||||||
|
|
||||||
|
const EditForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
record: API.Product;
|
||||||
|
}> = ({ tableRef, record }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const formRef = useRef<ProFormInstance>();
|
||||||
|
const [brandOptions, setBrandOptions] = useState<DictItem[]>([]);
|
||||||
|
const [strengthOptions, setStrengthOptions] = useState<DictItem[]>([]);
|
||||||
|
const [flavorOptions, setFlavorOptions] = useState<DictItem[]>([]);
|
||||||
|
|
||||||
|
const setInitialIds = () => {
|
||||||
|
const brand = brandOptions.find((item) => item.title === record.brandName);
|
||||||
|
const strength = strengthOptions.find((item) => item.title === record.strengthName);
|
||||||
|
const flavor = flavorOptions.find((item) => item.title === record.flavorsName);
|
||||||
|
formRef.current?.setFieldsValue({
|
||||||
|
brandId: brand?.id,
|
||||||
|
strengthId: strength?.id,
|
||||||
|
flavorsId: flavor?.id,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (brandOptions.length && strengthOptions.length && flavorOptions.length) {
|
||||||
|
setInitialIds();
|
||||||
|
}
|
||||||
|
}, [brandOptions, strengthOptions, flavorOptions]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.UpdateProductDTO>
|
||||||
|
formRef={formRef}
|
||||||
|
title="编辑"
|
||||||
|
trigger={<Button type="link">编辑</Button>}
|
||||||
|
initialValues={{
|
||||||
|
name: record.name,
|
||||||
|
sku: record.sku,
|
||||||
|
description: record.description,
|
||||||
|
humidity: record.humidity,
|
||||||
|
price: (record as any).price,
|
||||||
|
promotionPrice: (record as any).promotionPrice,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
const { success, message: errMsg } = await productcontrollerUpdateproduct(
|
||||||
|
{ id: record.id },
|
||||||
|
values as any,
|
||||||
|
);
|
||||||
|
if (success) {
|
||||||
|
message.success('更新成功');
|
||||||
|
tableRef.current?.reloadAndRest?.();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
message.error(errMsg);
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormSelect
|
||||||
|
name="brandId"
|
||||||
|
width="lg"
|
||||||
|
label="产品品牌"
|
||||||
|
placeholder="请选择产品品牌"
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await productcontrollerGetbrandall();
|
||||||
|
setBrandOptions(data);
|
||||||
|
return data.map((item: DictItem) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
rules={[{ required: true, message: '请选择产品品牌' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name="strengthId"
|
||||||
|
width="lg"
|
||||||
|
label="强度"
|
||||||
|
placeholder="请选择强度"
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await productcontrollerGetstrengthall();
|
||||||
|
setStrengthOptions(data);
|
||||||
|
return data.map((item: DictItem) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
rules={[{ required: true, message: '请选择强度' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name="flavorsId"
|
||||||
|
width="lg"
|
||||||
|
label="口味"
|
||||||
|
placeholder="请选择口味"
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await productcontrollerGetflavorsall();
|
||||||
|
setFlavorOptions(data);
|
||||||
|
return data.map((item: DictItem) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
rules={[{ required: true, message: '请选择口味' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name="humidity"
|
||||||
|
width="lg"
|
||||||
|
label="干湿"
|
||||||
|
placeholder="请选择干湿"
|
||||||
|
valueEnum={{
|
||||||
|
dry: 'dry',
|
||||||
|
moisture: 'moisture',
|
||||||
|
}}
|
||||||
|
rules={[{ required: true, message: '请选择干湿' }]}
|
||||||
|
/>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="sku"
|
||||||
|
label="SKU"
|
||||||
|
width="md"
|
||||||
|
placeholder="请输入SKU"
|
||||||
|
rules={[{ required: true, message: '请输入SKU' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
label="名称"
|
||||||
|
width="md"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="price"
|
||||||
|
label="价格"
|
||||||
|
width="md"
|
||||||
|
placeholder="请输入价格"
|
||||||
|
rules={[{ required: false }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="promotionPrice"
|
||||||
|
label="促销价"
|
||||||
|
width="md"
|
||||||
|
placeholder="请输入促销价"
|
||||||
|
rules={[{ required: false }]}
|
||||||
|
/>
|
||||||
|
<ProFormTextArea
|
||||||
|
name="description"
|
||||||
|
width="lg"
|
||||||
|
label="产品描述"
|
||||||
|
placeholder="请输入产品描述"
|
||||||
|
/>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
import { request } from 'umi';
|
||||||
|
|
||||||
|
/** 获取区域列表(分页) GET /api/area/ */
|
||||||
|
export async function areacontrollerGetarealist(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.areacontrollerGetarealistParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.Area[]>('/api/area/', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 创建区域 POST /api/area/ */
|
||||||
|
export async function areacontrollerCreatearea(
|
||||||
|
body: API.CreateAreaDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.Area>('/api/area/', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据ID获取区域详情 GET /api/area/${param0} */
|
||||||
|
export async function areacontrollerGetareabyid(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.areacontrollerGetareabyidParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.Area>(`/api/area/${param0}`, {
|
||||||
|
method: 'GET',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 更新区域 PUT /api/area/${param0} */
|
||||||
|
export async function areacontrollerUpdatearea(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.areacontrollerUpdateareaParams,
|
||||||
|
body: API.UpdateAreaDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.Area>(`/api/area/${param0}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除区域 DELETE /api/area/${param0} */
|
||||||
|
export async function areacontrollerDeletearea(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.areacontrollerDeleteareaParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<any>(`/api/area/${param0}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取所有区域 GET /api/area/all */
|
||||||
|
export async function areacontrollerGetallareas(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<API.Area[]>('/api/area/all', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// API 更新时间:
|
// API 更新时间:
|
||||||
// API 唯一标识:
|
// API 唯一标识:
|
||||||
|
import * as area from './area';
|
||||||
import * as customer from './customer';
|
import * as customer from './customer';
|
||||||
import * as dict from './dict';
|
import * as dict from './dict';
|
||||||
import * as locales from './locales';
|
import * as locales from './locales';
|
||||||
|
|
@ -17,6 +18,7 @@ import * as user from './user';
|
||||||
import * as webhook from './webhook';
|
import * as webhook from './webhook';
|
||||||
import * as wpProduct from './wpProduct';
|
import * as wpProduct from './wpProduct';
|
||||||
export default {
|
export default {
|
||||||
|
area,
|
||||||
customer,
|
customer,
|
||||||
dict,
|
dict,
|
||||||
locales,
|
locales,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,37 @@ declare namespace API {
|
||||||
postal_code?: string;
|
postal_code?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type Area = {
|
||||||
|
id?: number;
|
||||||
|
/** 区域名称 */
|
||||||
|
name?: string;
|
||||||
|
/** 创建时间 */
|
||||||
|
createdAt: string;
|
||||||
|
/** 更新时间 */
|
||||||
|
updatedAt: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type areacontrollerDeleteareaParams = {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type areacontrollerGetareabyidParams = {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type areacontrollerGetarealistParams = {
|
||||||
|
/** 当前页码 */
|
||||||
|
currentPage?: number;
|
||||||
|
/** 每页数量 */
|
||||||
|
pageSize?: number;
|
||||||
|
/** 区域名称 */
|
||||||
|
name?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type areacontrollerUpdateareaParams = {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
type BatchSetSkuDTO = {
|
type BatchSetSkuDTO = {
|
||||||
/** sku 数据列表 */
|
/** sku 数据列表 */
|
||||||
skus?: SkuItemDTO[];
|
skus?: SkuItemDTO[];
|
||||||
|
|
@ -34,6 +65,11 @@ declare namespace API {
|
||||||
items?: Dict[];
|
items?: Dict[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type CreateAreaDTO = {
|
||||||
|
/** 区域名称 */
|
||||||
|
name?: string;
|
||||||
|
};
|
||||||
|
|
||||||
type CreateBrandDTO = {
|
type CreateBrandDTO = {
|
||||||
/** 品牌名称 */
|
/** 品牌名称 */
|
||||||
title: string;
|
title: string;
|
||||||
|
|
@ -64,12 +100,12 @@ declare namespace API {
|
||||||
description?: string;
|
description?: string;
|
||||||
/** 产品 SKU */
|
/** 产品 SKU */
|
||||||
sku?: string;
|
sku?: string;
|
||||||
/** 品牌 */
|
/** 品牌 ID */
|
||||||
brand?: DictItemDTO;
|
brandId?: number;
|
||||||
/** 规格 */
|
/** 规格 ID */
|
||||||
strength?: DictItemDTO;
|
strengthId?: number;
|
||||||
/** 口味 */
|
/** 口味 ID */
|
||||||
flavor?: DictItemDTO;
|
flavorsId?: number;
|
||||||
humidity?: string;
|
humidity?: string;
|
||||||
/** 价格 */
|
/** 价格 */
|
||||||
price?: number;
|
price?: number;
|
||||||
|
|
@ -177,13 +213,6 @@ declare namespace API {
|
||||||
id: number;
|
id: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DictItemDTO = {
|
|
||||||
/** 显示名称 */
|
|
||||||
title?: string;
|
|
||||||
/** 唯一标识 */
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type DisableSiteDTO = {};
|
type DisableSiteDTO = {};
|
||||||
|
|
||||||
type localecontrollerGetlocaleParams = {
|
type localecontrollerGetlocaleParams = {
|
||||||
|
|
@ -705,6 +734,12 @@ declare namespace API {
|
||||||
sku?: string;
|
sku?: string;
|
||||||
/** 价格 */
|
/** 价格 */
|
||||||
price?: number;
|
price?: number;
|
||||||
|
/** 促销价格 */
|
||||||
|
promotionPrice?: number;
|
||||||
|
/** 库存 */
|
||||||
|
stock?: number;
|
||||||
|
/** 来源 */
|
||||||
|
source?: number;
|
||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
/** 更新时间 */
|
/** 更新时间 */
|
||||||
|
|
@ -906,6 +941,15 @@ declare namespace API {
|
||||||
items?: PurchaseOrderDTO[];
|
items?: PurchaseOrderDTO[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type QueryAreaDTO = {
|
||||||
|
/** 当前页码 */
|
||||||
|
currentPage?: number;
|
||||||
|
/** 每页数量 */
|
||||||
|
pageSize?: number;
|
||||||
|
/** 区域名称 */
|
||||||
|
name?: string;
|
||||||
|
};
|
||||||
|
|
||||||
type QueryBrandDTO = {
|
type QueryBrandDTO = {
|
||||||
/** 页码 */
|
/** 页码 */
|
||||||
current?: number;
|
current?: number;
|
||||||
|
|
@ -1569,6 +1613,11 @@ declare namespace API {
|
||||||
minute?: string;
|
minute?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type UpdateAreaDTO = {
|
||||||
|
/** 区域名称 */
|
||||||
|
name?: string;
|
||||||
|
};
|
||||||
|
|
||||||
type UpdateBrandDTO = {
|
type UpdateBrandDTO = {
|
||||||
/** 品牌名称 */
|
/** 品牌名称 */
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
@ -1594,12 +1643,12 @@ declare namespace API {
|
||||||
description?: string;
|
description?: string;
|
||||||
/** 产品 SKU */
|
/** 产品 SKU */
|
||||||
sku?: string;
|
sku?: string;
|
||||||
/** 品牌 */
|
/** 品牌 ID */
|
||||||
brand?: DictItemDTO;
|
brandId?: number;
|
||||||
/** 规格 */
|
/** 规格 ID */
|
||||||
strength?: DictItemDTO;
|
strengthId?: number;
|
||||||
/** 口味 */
|
/** 口味 ID */
|
||||||
flavor?: DictItemDTO;
|
flavorsId?: number;
|
||||||
humidity?: string;
|
humidity?: string;
|
||||||
/** 价格 */
|
/** 价格 */
|
||||||
price?: number;
|
price?: number;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue