feat(产品列表): 添加自动生成SKU和产品名称功能
实现通过模板渲染API自动生成产品SKU和名称的功能 添加品牌、强度、口味和干湿选项的状态管理 优化表单布局,将生成按钮与对应字段分组
This commit is contained in:
parent
bd4096258e
commit
15c8588357
|
|
@ -7,6 +7,7 @@ import {
|
||||||
productcontrollerGetstrengthall,
|
productcontrollerGetstrengthall,
|
||||||
productcontrollerUpdateproductnamecn,
|
productcontrollerUpdateproductnamecn,
|
||||||
} from '@/servers/api/product';
|
} from '@/servers/api/product';
|
||||||
|
import { templatecontrollerRendertemplate } from '@/servers/api/template';
|
||||||
import { PlusOutlined } from '@ant-design/icons';
|
import { PlusOutlined } from '@ant-design/icons';
|
||||||
import {
|
import {
|
||||||
ActionType,
|
ActionType,
|
||||||
|
|
@ -14,14 +15,20 @@ import {
|
||||||
PageContainer,
|
PageContainer,
|
||||||
ProColumns,
|
ProColumns,
|
||||||
ProForm,
|
ProForm,
|
||||||
|
ProFormInstance,
|
||||||
ProFormSelect,
|
ProFormSelect,
|
||||||
ProFormText,
|
ProFormText,
|
||||||
ProFormTextArea,
|
ProFormTextArea,
|
||||||
ProTable,
|
ProTable,
|
||||||
} 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 } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
|
// TODO
|
||||||
|
interface DictItem {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
const NameCn: React.FC<{
|
const NameCn: React.FC<{
|
||||||
id: number;
|
id: number;
|
||||||
value: string | undefined;
|
value: string | undefined;
|
||||||
|
|
@ -176,10 +183,99 @@ const List: React.FC = () => {
|
||||||
const CreateForm: React.FC<{
|
const CreateForm: React.FC<{
|
||||||
tableRef: React.MutableRefObject<ActionType | undefined>;
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
}> = ({ tableRef }) => {
|
}> = ({ tableRef }) => {
|
||||||
|
// antd 的消息提醒
|
||||||
const { message } = App.useApp();
|
const { message } = App.useApp();
|
||||||
|
// 表单引用
|
||||||
|
const formRef = useRef<ProFormInstance>();
|
||||||
|
// 状态:存储品牌、强度和口味的选项
|
||||||
|
const [brandOptions, setBrandOptions] = useState<DictItem[]>([]);
|
||||||
|
const [strengthOptions, setStrengthOptions] = useState<DictItem[]>([]);
|
||||||
|
const [flavorOptions, setFlavorOptions] = useState<DictItem[]>([]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 生成 SKU
|
||||||
|
*/
|
||||||
|
const handleGenerateSku = async () => {
|
||||||
|
try {
|
||||||
|
// 从表单引用中获取当前表单的值
|
||||||
|
const formValues = formRef.current?.getFieldsValue();
|
||||||
|
const { humidity, brandId, strengthId, flavorsId } = formValues;
|
||||||
|
// 检查是否所有必需的字段都已选择
|
||||||
|
if (!brandId || !strengthId || !flavorsId || !humidity) {
|
||||||
|
message.warning('请先选择品牌、强度、口味和干湿');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从选项中查找所选品牌、强度和口味的完整对象
|
||||||
|
const brand = brandOptions.find((item) => item.id === brandId);
|
||||||
|
const strength = strengthOptions.find((item) => item.id === strengthId);
|
||||||
|
const flavor = flavorOptions.find((item) => item.id === flavorsId);
|
||||||
|
|
||||||
|
// 调用模板渲染API来生成SKU
|
||||||
|
const { data: rendered, message: msg, success } = await templatecontrollerRendertemplate(
|
||||||
|
{ name: 'product.sku' },
|
||||||
|
{
|
||||||
|
brand: brand ? brand.name : "",
|
||||||
|
strength: strength ? strength.name : '',
|
||||||
|
flavor: flavor ? flavor.name : '',
|
||||||
|
humidity: humidity === 'dry' ? 'Dry' : 'Moisture',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将生成的SKU设置到表单字段中
|
||||||
|
formRef.current?.setFieldsValue({ sku: rendered });
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(`生成失败: ${error.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 生成产品名称
|
||||||
|
*/
|
||||||
|
const handleGenerateName = async () => {
|
||||||
|
try {
|
||||||
|
// 从表单引用中获取当前表单的值
|
||||||
|
const formValues = formRef.current?.getFieldsValue();
|
||||||
|
const { humidity, brandId, strengthId, flavorsId } = formValues;
|
||||||
|
// 检查是否所有必需的字段都已选择
|
||||||
|
if (!brandId || !strengthId || !flavorsId || !humidity) {
|
||||||
|
message.warning('请先选择品牌、强度、口味和干湿');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从选项中查找所选品牌、强度和口味的完整对象
|
||||||
|
const brand = brandOptions.find((item) => item.id === brandId);
|
||||||
|
const strength = strengthOptions.find((item) => item.id === strengthId);
|
||||||
|
const flavor = flavorOptions.find((item) => item.id === flavorsId);
|
||||||
|
|
||||||
|
// 调用模板渲染API来生成产品名称
|
||||||
|
const { message: msg, data: rendered, success } = await templatecontrollerRendertemplate(
|
||||||
|
{ name: 'product.title' },
|
||||||
|
{
|
||||||
|
brand: brand ? brand.title : "",
|
||||||
|
strength: strength ? strength.title : '',
|
||||||
|
flavor: flavor ? flavor.title : '',
|
||||||
|
model: '',
|
||||||
|
humidity: humidity === 'dry' ? 'Dry' : 'Moisture',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(msg);
|
||||||
|
}
|
||||||
|
// 将生成的名称设置到表单字段中
|
||||||
|
formRef.current?.setFieldsValue({ name: rendered });
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(`生成失败: ${error.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// TODO 可以输入brand等
|
||||||
return (
|
return (
|
||||||
<DrawerForm<API.CreateProductDTO>
|
<DrawerForm<API.CreateProductDTO>
|
||||||
title="新建"
|
title="新建"
|
||||||
|
formRef={formRef} // Pass formRef
|
||||||
trigger={
|
trigger={
|
||||||
<Button type="primary">
|
<Button type="primary">
|
||||||
<PlusOutlined />
|
<PlusOutlined />
|
||||||
|
|
@ -205,20 +301,6 @@ const CreateForm: React.FC<{
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ProForm.Group>
|
|
||||||
<ProFormText
|
|
||||||
name="name"
|
|
||||||
label="名称"
|
|
||||||
width="lg"
|
|
||||||
placeholder="请输入名称"
|
|
||||||
rules={[{ required: true, message: '请输入名称' }]}
|
|
||||||
/>
|
|
||||||
<ProFormTextArea
|
|
||||||
name="description"
|
|
||||||
width="lg"
|
|
||||||
label="产品描述"
|
|
||||||
placeholder="请输入产品描述"
|
|
||||||
/>
|
|
||||||
<ProFormSelect
|
<ProFormSelect
|
||||||
name="brandId"
|
name="brandId"
|
||||||
width="lg"
|
width="lg"
|
||||||
|
|
@ -226,7 +308,8 @@ const CreateForm: React.FC<{
|
||||||
placeholder="请选择产品品牌"
|
placeholder="请选择产品品牌"
|
||||||
request={async () => {
|
request={async () => {
|
||||||
const { data = [] } = await productcontrollerGetbrandall();
|
const { data = [] } = await productcontrollerGetbrandall();
|
||||||
return data.map((item: API.Brand) => ({
|
setBrandOptions(data);
|
||||||
|
return data.map((item: DictItem) => ({
|
||||||
label: item.name,
|
label: item.name,
|
||||||
value: item.id,
|
value: item.id,
|
||||||
}));
|
}));
|
||||||
|
|
@ -240,7 +323,8 @@ const CreateForm: React.FC<{
|
||||||
placeholder="请选择强度"
|
placeholder="请选择强度"
|
||||||
request={async () => {
|
request={async () => {
|
||||||
const { data = [] } = await productcontrollerGetstrengthall();
|
const { data = [] } = await productcontrollerGetstrengthall();
|
||||||
return data.map((item) => ({
|
setStrengthOptions(data);
|
||||||
|
return data.map((item: DictItem) => ({
|
||||||
label: item.name,
|
label: item.name,
|
||||||
value: item.id,
|
value: item.id,
|
||||||
}));
|
}));
|
||||||
|
|
@ -254,7 +338,8 @@ const CreateForm: React.FC<{
|
||||||
placeholder="请选择口味"
|
placeholder="请选择口味"
|
||||||
request={async () => {
|
request={async () => {
|
||||||
const { data = [] } = await productcontrollerGetflavorsall();
|
const { data = [] } = await productcontrollerGetflavorsall();
|
||||||
return data.map((item) => ({
|
setFlavorOptions(data);
|
||||||
|
return data.map((item: DictItem) => ({
|
||||||
label: item.name,
|
label: item.name,
|
||||||
value: item.id,
|
value: item.id,
|
||||||
}));
|
}));
|
||||||
|
|
@ -267,12 +352,41 @@ const CreateForm: React.FC<{
|
||||||
label="干湿"
|
label="干湿"
|
||||||
placeholder="请选择干湿"
|
placeholder="请选择干湿"
|
||||||
valueEnum={{
|
valueEnum={{
|
||||||
dry: '干',
|
dry: 'dry',
|
||||||
wet: '湿',
|
wet: 'wet',
|
||||||
}}
|
}}
|
||||||
rules={[{ required: true, message: '请选择干湿' }]}
|
rules={[{ required: true, message: '请选择干湿' }]}
|
||||||
/>
|
/>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="sku"
|
||||||
|
label="SKU"
|
||||||
|
width="md"
|
||||||
|
placeholder="请输入SKU"
|
||||||
|
rules={[{ required: true, message: '请输入SKU' }]}
|
||||||
|
/>
|
||||||
|
<Button style={{ marginTop: '32px' }} onClick={handleGenerateSku}>
|
||||||
|
自动生成
|
||||||
|
</Button>
|
||||||
</ProForm.Group>
|
</ProForm.Group>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
label="名称"
|
||||||
|
width="md"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
<Button style={{ marginTop: '32px' }} onClick={handleGenerateName}>
|
||||||
|
自动生成
|
||||||
|
</Button>
|
||||||
|
</ProForm.Group>
|
||||||
|
<ProFormTextArea
|
||||||
|
name="description"
|
||||||
|
width="lg"
|
||||||
|
label="产品描述"
|
||||||
|
placeholder="请输入产品描述"
|
||||||
|
/>
|
||||||
</DrawerForm>
|
</DrawerForm>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -73,3 +73,22 @@ export async function templatecontrollerGettemplatelist(options?: {
|
||||||
...(options || {}),
|
...(options || {}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /template/render/${param0} */
|
||||||
|
export async function templatecontrollerRendertemplate(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.templatecontrollerRendertemplateParams,
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { name: param0, ...queryParams } = params;
|
||||||
|
return request<Record<string, any>>(`/template/render/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,8 @@ declare namespace API {
|
||||||
/** 口味 */
|
/** 口味 */
|
||||||
flavor?: DictItemDTO;
|
flavor?: DictItemDTO;
|
||||||
humidity?: string;
|
humidity?: string;
|
||||||
|
/** 价格 */
|
||||||
|
price?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type CreatePurchaseOrderDTO = {
|
type CreatePurchaseOrderDTO = {
|
||||||
|
|
@ -701,6 +703,8 @@ declare namespace API {
|
||||||
description?: string;
|
description?: string;
|
||||||
/** sku */
|
/** sku */
|
||||||
sku?: string;
|
sku?: string;
|
||||||
|
/** 价格 */
|
||||||
|
price?: number;
|
||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
/** 更新时间 */
|
/** 更新时间 */
|
||||||
|
|
@ -1536,6 +1540,8 @@ declare namespace API {
|
||||||
name?: string;
|
name?: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
/** 是否可删除 */
|
||||||
|
deletable: boolean;
|
||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
/** 更新时间 */
|
/** 更新时间 */
|
||||||
|
|
@ -1550,6 +1556,10 @@ declare namespace API {
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type templatecontrollerRendertemplateParams = {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
type templatecontrollerUpdatetemplateParams = {
|
type templatecontrollerUpdatetemplateParams = {
|
||||||
id: number;
|
id: number;
|
||||||
};
|
};
|
||||||
|
|
@ -1591,6 +1601,8 @@ declare namespace API {
|
||||||
/** 口味 */
|
/** 口味 */
|
||||||
flavor?: DictItemDTO;
|
flavor?: DictItemDTO;
|
||||||
humidity?: string;
|
humidity?: string;
|
||||||
|
/** 价格 */
|
||||||
|
price?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type UpdatePurchaseOrderDTO = {
|
type UpdatePurchaseOrderDTO = {
|
||||||
|
|
@ -1749,7 +1761,7 @@ declare namespace API {
|
||||||
siteId: string;
|
siteId: string;
|
||||||
/** wp产品ID */
|
/** wp产品ID */
|
||||||
externalProductId: string;
|
externalProductId: string;
|
||||||
/** sku */
|
/** 商店sku */
|
||||||
sku?: string;
|
sku?: string;
|
||||||
/** 产品名称 */
|
/** 产品名称 */
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue