From c66db9b9840a27d1d883e89878a24e5e3d7e9c15 Mon Sep 17 00:00:00 2001 From: tikkhun Date: Tue, 2 Dec 2025 15:02:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E4=BA=A7=E5=93=81):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=A7=E5=93=81=E5=B1=9E=E6=80=A7=E5=85=B3?= =?UTF-8?q?=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refactor(属性): 移除category属性并优化表单组件 feat(同步): 添加商品同步页面和接口调整 refactor(区域): 简化区域API和类型定义 style(布局): 调整属性页面布局和滚动样式 --- .umirc.ts | 7 +- src/pages/Category/index.tsx | 291 ++++++++++++++++++ .../components/AttributeFormItem.tsx | 2 + src/pages/Product/Attribute/consts.ts | 1 - src/pages/Product/Attribute/index.tsx | 5 +- src/pages/Product/List/index.tsx | 288 +++++++++-------- src/pages/Product/Sync/index.tsx | 23 +- src/servers/api/area.ts | 30 +- src/servers/api/typings.d.ts | 59 ++-- 9 files changed, 518 insertions(+), 188 deletions(-) create mode 100644 src/pages/Category/index.tsx diff --git a/.umirc.ts b/.umirc.ts index 6d0c99c..f06eec5 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -114,7 +114,12 @@ export default defineConfig({ path: '/product/attribute', component: './Product/Attribute', }, - + // sync + { + name: '同步商品', + path: '/product/sync', + component: './Product/Sync', + }, { name: 'WP商品列表', path: '/product/wp_list', diff --git a/src/pages/Category/index.tsx b/src/pages/Category/index.tsx new file mode 100644 index 0000000..53cda7a --- /dev/null +++ b/src/pages/Category/index.tsx @@ -0,0 +1,291 @@ +import { PlusOutlined } from '@ant-design/icons'; +import { + PageContainer, +} from '@ant-design/pro-components'; +import { request } from '@umijs/max'; +import { + Button, + Card, + Form, + Input, + Layout, + List, + Modal, + Popconfirm, + Select, + message, +} from 'antd'; +import React, { useEffect, useState } from 'react'; +import { + productcontrollerCreatecategory, + productcontrollerCreatecategoryattribute, + productcontrollerDeletecategory, + productcontrollerDeletecategoryattribute, + productcontrollerGetcategoriesall, + productcontrollerGetcategoryattributes, + productcontrollerUpdatecategory, +} from '@/servers/api/product'; +import { attributes } from '../Product/Attribute/consts'; + +const { Sider, Content } = Layout; + +const CategoryPage: React.FC = () => { + const [categories, setCategories] = useState([]); + const [loadingCategories, setLoadingCategories] = useState(false); + const [selectedCategory, setSelectedCategory] = useState(null); + const [categoryAttributes, setCategoryAttributes] = useState([]); + const [loadingAttributes, setLoadingAttributes] = useState(false); + + const [isCategoryModalVisible, setIsCategoryModalVisible] = useState(false); + const [categoryForm] = Form.useForm(); + const [editingCategory, setEditingCategory] = useState(null); + + const [isAttributeModalVisible, setIsAttributeModalVisible] = useState(false); + const [availableDicts, setAvailableDicts] = useState([]); + const [selectedDictIds, setSelectedDictIds] = useState([]); + + const fetchCategories = async () => { + setLoadingCategories(true); + try { + const res = await productcontrollerGetcategoriesall(); + setCategories(res || []); + } catch (error) { + message.error('获取分类列表失败'); + } + setLoadingCategories(false); + }; + + useEffect(() => { + fetchCategories(); + }, []); + + const fetchCategoryAttributes = async (categoryId: number) => { + setLoadingAttributes(true); + try { + const res = await productcontrollerGetcategoryattributes({ categoryItemId: categoryId }); + setCategoryAttributes(res || []); + } catch (error) { + message.error('获取分类属性失败'); + } + setLoadingAttributes(false); + }; + + useEffect(() => { + if (selectedCategory) { + fetchCategoryAttributes(selectedCategory.id); + } else { + setCategoryAttributes([]); + } + }, [selectedCategory]); + + const handleCategorySubmit = async (values: any) => { + try { + if (editingCategory) { + await productcontrollerUpdatecategory({ id: editingCategory.id }, values); + message.success('更新成功'); + } else { + await productcontrollerCreatecategory(values); + message.success('创建成功'); + } + setIsCategoryModalVisible(false); + fetchCategories(); + } catch (error: any) { + message.error(error.message || '操作失败'); + } + }; + + const handleDeleteCategory = async (id: number) => { + try { + await productcontrollerDeletecategory({ id }); + message.success('删除成功'); + if (selectedCategory?.id === id) { + setSelectedCategory(null); + } + fetchCategories(); + } catch (error: any) { + message.error(error.message || '删除失败'); + } + }; + + const handleAddAttribute = async () => { + // Fetch all dicts and filter those that are allowed attributes + try { + const res = await request('/dict/list'); + const filtered = (res || []).filter((d: any) => attributes.has(d.name)); + // Filter out already added attributes + const existingDictIds = new Set(categoryAttributes.map((ca: any) => ca.dict.id)); + const available = filtered.filter((d: any) => !existingDictIds.has(d.id)); + setAvailableDicts(available); + setSelectedDictIds([]); + setIsAttributeModalVisible(true); + } catch (error) { + message.error('获取属性字典失败'); + } + }; + + const handleAttributeSubmit = async () => { + if (selectedDictIds.length === 0) { + message.warning('请选择属性'); + return; + } + try { + await productcontrollerCreatecategoryattribute({ + categoryItemId: selectedCategory.id, + attributeDictIds: selectedDictIds, + }); + message.success('添加属性成功'); + setIsAttributeModalVisible(false); + fetchCategoryAttributes(selectedCategory.id); + } catch (error: any) { + message.error(error.message || '添加失败'); + } + }; + + const handleDeleteAttribute = async (id: number) => { + try { + await productcontrollerDeletecategoryattribute({ id }); + message.success('移除属性成功'); + fetchCategoryAttributes(selectedCategory.id); + } catch (error: any) { + message.error(error.message || '移除失败'); + } + }; + + return ( + + + +
+ 分类列表 + +
+ ( + setSelectedCategory(item)} + actions={[ + { + e.stopPropagation(); + setEditingCategory(item); + categoryForm.setFieldsValue(item); + setIsCategoryModalVisible(true); + }} + > + 编辑 + , + { + e?.stopPropagation(); + handleDeleteCategory(item.id); + }} + onCancel={(e) => e?.stopPropagation()} + > + e.stopPropagation()} style={{ color: 'red' }}>删除 + , + ]} + > + + + )} + /> +
+ + {selectedCategory ? ( + 添加关联属性}> + ( + handleDeleteAttribute(item.id)} + > + + + ]} + > + + + )} + /> + + ) : ( +
+ 请选择左侧分类 +
+ )} +
+
+ + categoryForm.submit()} + onCancel={() => setIsCategoryModalVisible(false)} + > +
+ + + + + + +
+
+ + setIsAttributeModalVisible(false)} + > +
+ +