diff --git a/.umirc.ts b/.umirc.ts index d73bd6b..ea983aa 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -93,21 +93,11 @@ export default defineConfig({ component: './Product/List', }, { - name: '品牌', - path: '/product/brand', - component: './Product/Brand', + name: '产品属性', + path: '/product/attribute', + component: './Product/Attribute', }, - { - name: '强度', - path: '/product/strength', - component: './Product/Strength', - }, - { - name: '口味', - path: '/product/flavors', - component: './Product/Flavors', - }, - + { name: 'WP商品列表', path: '/product/wp_list', diff --git a/src/pages/Dict/List/index.tsx b/src/pages/Dict/List/index.tsx index 527da54..ba37e97 100644 --- a/src/pages/Dict/List/index.tsx +++ b/src/pages/Dict/List/index.tsx @@ -245,7 +245,7 @@ const DictPage: React.FC = () => { title: '操作', key: 'action', render: (_: any, record: any) => ( - + - + { } }} > - + - @@ -360,6 +360,7 @@ const DictPage: React.FC = () => { columns={dictColumns} rowKey="id" loading={loadingDicts} + size="small" onRow={(record) => ({ onClick: () => { // 如果点击的是当前已选中的行,则取消选择 @@ -377,13 +378,14 @@ const DictPage: React.FC = () => { /> - +
@@ -402,13 +404,14 @@ const DictPage: React.FC = () => { } }} > - @@ -418,6 +421,7 @@ const DictPage: React.FC = () => { columns={dictItemColumns} rowKey="id" loading={loadingDictItems} + size="small" /> diff --git a/src/pages/Product/Attribute/consts.ts b/src/pages/Product/Attribute/consts.ts new file mode 100644 index 0000000..fd4af07 --- /dev/null +++ b/src/pages/Product/Attribute/consts.ts @@ -0,0 +1,2 @@ +// 中文注释:限定允许管理的字典名称集合 +export const allowedDictNames = new Set(['brand', 'strength', 'flavor', 'size', 'humidity']); \ No newline at end of file diff --git a/src/pages/Product/Attribute/index.tsx b/src/pages/Product/Attribute/index.tsx index fc1dae5..8c4d9dc 100644 --- a/src/pages/Product/Attribute/index.tsx +++ b/src/pages/Product/Attribute/index.tsx @@ -6,8 +6,7 @@ import React, { useEffect, useState } from 'react'; const { Sider, Content } = Layout; -// 中文注释:限定允许管理的字典名称集合 -const allowedDictNames = new Set(['brand', 'strength', 'flavor', 'size', 'humidity']); +import { allowedDictNames } from './consts'; const AttributePage: React.FC = () => { // 中文注释:左侧字典列表状态 diff --git a/src/pages/Product/List/index.tsx b/src/pages/Product/List/index.tsx index 889f1ba..c23ee0f 100644 --- a/src/pages/Product/List/index.tsx +++ b/src/pages/Product/List/index.tsx @@ -1,5 +1,6 @@ import { productcontrollerCreateproduct, + productcontrollerCompatsizeall, productcontrollerDeleteproduct, productcontrollerCompatbrandall, productcontrollerCompatflavorsall, @@ -27,7 +28,8 @@ import { ProFormTextArea, ProTable, } from '@ant-design/pro-components'; -import { App, Button, Popconfirm } from 'antd'; +import { App, Button, Popconfirm, Tag } from 'antd'; +import { allowedDictNames } from '@/pages/Product/Attribute/consts'; import React, { useRef, useState } from 'react'; const capitalize = (s: string) => s.charAt(0).toLocaleUpperCase() + s.slice(1); // TODO @@ -67,6 +69,50 @@ const NameCn: React.FC<{ /> ); }; + +const AttributesCell: React.FC<{ record: any }> = ({ record }) => { + const items: { key: string; value: string }[] = []; + // 中文注释:按允许的属性集合收集展示值 + if (allowedDictNames.has('brand') && record?.brand?.name) items.push({ key: '品牌', value: record.brand.name }); + if (allowedDictNames.has('strength') && record?.strength?.name) items.push({ key: '强度', value: record.strength.name }); + if (allowedDictNames.has('flavor') && record?.flavors?.name) items.push({ key: '口味', value: record.flavors.name }); + if (allowedDictNames.has('size') && record?.size?.name) items.push({ key: '规格', value: record.size.name }); + if (allowedDictNames.has('humidity') && record?.humidity) items.push({ key: '湿度', value: record.humidity }); + return ( +
+ {items.length ? items.map((it, idx) => ( + + {it.key}: {it.value} + + )) : -} +
+ ); +}; + + +const ComponentsCell: React.FC<{ productId: number }> = ({ productId }) => { + const [items, setItems] = React.useState([]); + React.useEffect(() => { + (async () => { + const { data = [] } = await productcontrollerGetproductcomponents({ id: productId }); + setItems(data || []); + })(); + }, [productId]); + return ( +
+ {items && items.length ? ( + items.map((c: any) => ( + + {(c.stock && c.stock.productSku) || `#${c.stockId}`} × {c.quantity}(库存:{c.stock ? c.stock.quantity : '-'}) + + )) + ) : ( + - + )} +
+ ); +}; + const List: React.FC = () => { const actionRef = useRef(); // 状态:存储当前选中的行 @@ -102,32 +148,23 @@ const List: React.FC = () => { hideInSearch: true, }, { - title: '库存', - dataIndex: 'stock', + title: '属性', + dataIndex: 'attributes', hideInSearch: true, + render: (_, record) => , }, + { + title: '构成', + dataIndex: 'components', + hideInSearch: true, + render: (_, record) => , + }, + { title: '描述', dataIndex: 'description', hideInSearch: true, }, - { - title: '品牌', - dataIndex: 'brand.name', - }, - { - title: '强度', - dataIndex: 'strength.name', - }, - { - title: '口味', - dataIndex: 'flavors.name', - }, - { - title: '湿度', - dataIndex: 'humidity', - }, - { title: '更新时间', dataIndex: 'updatedAt', @@ -163,7 +200,7 @@ const List: React.FC = () => { } }} > - @@ -322,7 +359,8 @@ const CreateForm: React.FC<{ values.brandId ? { id: values.brandId } : null, values.strengthId ? { id: values.strengthId } : null, values.flavorsId ? { id: values.flavorsId } : null, - values.humidity ? { dictName: 'humidity', name: values.humidity } : null, + values.sizeId ? { id: values.sizeId } : null, + values.humidity ? { id: values.humidityId } : null, ].filter(Boolean), }; const { success, message: errMsg } = @@ -381,6 +419,17 @@ const CreateForm: React.FC<{ }} rules={[{ required: true, message: '请选择口味' }]} /> + { + const { data = [] } = await productcontrollerCompatsizeall(); + return (data || []).map((item: any) => ({ label: item.name, value: item.id })); + }} + rules={[{ required: false }]} + /> ([]); const setInitialIds = () => { - const brand = brandOptions.find((item) => item.title === record.brand.name); - const strength = strengthOptions.find((item) => item.title === record.strength.name); - const flavor = flavorOptions.find((item) => item.title === record.flavors.name); + const brand = brandOptions.find((item) => item.title === (record.brand?.name)); + const strength = strengthOptions.find((item) => item.title === (record.strength?.name)); + const flavor = flavorOptions.find((item) => item.title === (record.flavors?.name)); formRef.current?.setFieldsValue({ brandId: brand?.id, strengthId: strength?.id, @@ -495,10 +544,10 @@ const EditForm: React.FC<{ name: record.name, sku: record.sku, description: record.description, - humidity: record.humidity, - price: (record as any).price, - promotionPrice: (record as any).promotionPrice, + price: record.price, + promotionPrice: record.promotionPrice, components, + attributes: record.attributes || [], }} onFinish={async (values) => { // 中文注释:组装 attributes(若选择了则发送) @@ -506,6 +555,7 @@ const EditForm: React.FC<{ values.brandId ? { id: values.brandId } : null, values.strengthId ? { id: values.strengthId } : null, values.flavorsId ? { id: values.flavorsId } : null, + values.sizeId ? { id: values.sizeId } : null, values.humidity ? { dictName: 'humidity', name: values.humidity } : null, ].filter(Boolean); const updatePayload: any = { @@ -629,7 +679,7 @@ const EditForm: React.FC<{ formRef.current?.setFieldsValue({ components: items }); }} > - 自动绑定(同 SKU) + 自动绑定组成(同 SKU)